From d3ee67c68799476d2077a5ad3298f2a782b0d27a Mon Sep 17 00:00:00 2001 From: Vlad Arama Date: Thu, 29 Jun 2023 08:57:39 -0400 Subject: [PATCH 1/4] portable-mode for blueprint prototype --- .../node/theia-blueprint-variables-server.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts index 3b9bde6a6..3b16e35ee 100644 --- a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts +++ b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts @@ -16,6 +16,7 @@ import * as os from 'os'; import * as path from 'path'; +import { existsSync } from 'node:fs'; import { injectable } from '@theia/core/shared/inversify'; import { FileUri } from '@theia/core/lib/node/file-uri'; import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @@ -23,7 +24,35 @@ import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @injectable() export class TheiaBlueprintEnvVariableServer extends EnvVariablesServerImpl { - protected readonly _configDirUri: string = FileUri.create(path.join(os.homedir(), '.theia-blueprint')).toString(true); + protected _configDirUri: string; + + protected async createConfigDirUri(): Promise { + const projectPath = this.handlePath(process.cwd()); + const dataFolderPath = path.join(projectPath, 'data'); + if (existsSync(dataFolderPath)) { + this._configDirUri = dataFolderPath; + } else { + this._configDirUri = path.join(os.homedir(), '.theia-blueprint'); + } + return FileUri.create(this._configDirUri).toString(); + } + + protected handlePath(pathStr: string): string { + let pathArr = pathStr.split(path.sep); + switch (os.platform()) { + case "linux": + pathArr = pathArr.slice(0, pathArr.indexOf('linux-unpacked') + 1); + return pathArr.join(path.sep); + case "win32": + pathArr = pathArr.slice(0, pathArr.indexOf('win-unpacked') + 1); + return pathArr.join(path.sep); + case "darwin": + pathArr = pathArr.slice(0, pathArr.indexOf('mac') + 1); + return pathArr.join(path.sep); + default: + return ''; + } + } async getConfigDirUri(): Promise { return this._configDirUri; From df7f9dfc1fa68a3eed8bf3b7717386b9dde4eb40 Mon Sep 17 00:00:00 2001 From: Vlad Arama Date: Fri, 30 Jun 2023 09:05:34 -0400 Subject: [PATCH 2/4] improve portable-mode prototype --- .../node/theia-blueprint-variables-server.ts | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts index 3b16e35ee..41638b7ad 100644 --- a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts +++ b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts @@ -24,34 +24,22 @@ import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @injectable() export class TheiaBlueprintEnvVariableServer extends EnvVariablesServerImpl { - protected _configDirUri: string; + protected readonly _configDirUri: Promise = this.createConfigDirUri(); protected async createConfigDirUri(): Promise { const projectPath = this.handlePath(process.cwd()); const dataFolderPath = path.join(projectPath, 'data'); if (existsSync(dataFolderPath)) { - this._configDirUri = dataFolderPath; + return FileUri.create(dataFolderPath).toString(true); } else { - this._configDirUri = path.join(os.homedir(), '.theia-blueprint'); + return FileUri.create(path.join(os.homedir(), '.theia-blueprint')).toString(true); } - return FileUri.create(this._configDirUri).toString(); } protected handlePath(pathStr: string): string { let pathArr = pathStr.split(path.sep); - switch (os.platform()) { - case "linux": - pathArr = pathArr.slice(0, pathArr.indexOf('linux-unpacked') + 1); - return pathArr.join(path.sep); - case "win32": - pathArr = pathArr.slice(0, pathArr.indexOf('win-unpacked') + 1); - return pathArr.join(path.sep); - case "darwin": - pathArr = pathArr.slice(0, pathArr.indexOf('mac') + 1); - return pathArr.join(path.sep); - default: - return ''; - } + pathArr = pathArr.slice(0, pathArr.indexOf('TheiaBlueprint') + 1); + return pathArr.join(path.sep); } async getConfigDirUri(): Promise { From 4522afce82e3aa103686409ab5d87219c5b305b1 Mon Sep 17 00:00:00 2001 From: Vlad Arama Date: Thu, 6 Jul 2023 14:35:58 -0400 Subject: [PATCH 3/4] refactor portable-mode --- .../node/theia-blueprint-variables-server.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts index 41638b7ad..7acd084cd 100644 --- a/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts +++ b/theia-extensions/theia-blueprint-product/src/node/theia-blueprint-variables-server.ts @@ -16,7 +16,7 @@ import * as os from 'os'; import * as path from 'path'; -import { existsSync } from 'node:fs'; +import { existsSync, mkdirSync } from 'node:fs'; import { injectable } from '@theia/core/shared/inversify'; import { FileUri } from '@theia/core/lib/node/file-uri'; import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @@ -27,21 +27,21 @@ export class TheiaBlueprintEnvVariableServer extends EnvVariablesServerImpl { protected readonly _configDirUri: Promise = this.createConfigDirUri(); protected async createConfigDirUri(): Promise { - const projectPath = this.handlePath(process.cwd()); - const dataFolderPath = path.join(projectPath, 'data'); + const dataFolderPath = path.join(process.cwd(), 'data'); + const userDataPath = path.join(dataFolderPath, 'user-data'); + // Check if data folder exists for portable mode if (existsSync(dataFolderPath)) { - return FileUri.create(dataFolderPath).toString(true); + if (existsSync(userDataPath)) { + return FileUri.create(userDataPath).toString(true); + } else { + mkdirSync(userDataPath); + return FileUri.create(userDataPath).toString(true); + } } else { return FileUri.create(path.join(os.homedir(), '.theia-blueprint')).toString(true); } } - protected handlePath(pathStr: string): string { - let pathArr = pathStr.split(path.sep); - pathArr = pathArr.slice(0, pathArr.indexOf('TheiaBlueprint') + 1); - return pathArr.join(path.sep); - } - async getConfigDirUri(): Promise { return this._configDirUri; } From 225455676f9f39acff4e7e67addee464224a6b55 Mon Sep 17 00:00:00 2001 From: Vlad Arama Date: Fri, 24 Nov 2023 10:07:46 -0500 Subject: [PATCH 4/4] update portable-mode This commit addresses review commments and adds caching to avoid reading and writing to the disk too often. Signed-off-by: Vlad Arama --- theia-extensions/product/package.json | 5 +++-- .../src/node/theia-blueprint-variables-server.ts | 14 +++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/theia-extensions/product/package.json b/theia-extensions/product/package.json index 68beba4b2..c2bff9fa4 100644 --- a/theia-extensions/product/package.json +++ b/theia-extensions/product/package.json @@ -8,7 +8,8 @@ "@theia/getting-started": "1.43.0", "@theia/vsx-registry": "1.43.0", "@theia/workspace": "1.43.0", - "inversify": "^6.0.1" + "inversify": "^6.0.1", + "fs-extra": "^4.0.2" }, "devDependencies": { "rimraf": "^2.7.1", @@ -48,4 +49,4 @@ "peerDependencies": { "react": "^16.8.0" } -} +} \ No newline at end of file diff --git a/theia-extensions/product/src/node/theia-blueprint-variables-server.ts b/theia-extensions/product/src/node/theia-blueprint-variables-server.ts index 7acd084cd..fc6470edb 100644 --- a/theia-extensions/product/src/node/theia-blueprint-variables-server.ts +++ b/theia-extensions/product/src/node/theia-blueprint-variables-server.ts @@ -16,7 +16,7 @@ import * as os from 'os'; import * as path from 'path'; -import { existsSync, mkdirSync } from 'node:fs'; +import { pathExists, mkdir } from 'fs-extra'; import { injectable } from '@theia/core/shared/inversify'; import { FileUri } from '@theia/core/lib/node/file-uri'; import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @@ -24,17 +24,21 @@ import { EnvVariablesServerImpl } from '@theia/core/lib/node/env-variables'; @injectable() export class TheiaBlueprintEnvVariableServer extends EnvVariablesServerImpl { + protected readonly pathExistenceCache: { [key: string]: boolean } = {}; protected readonly _configDirUri: Promise = this.createConfigDirUri(); protected async createConfigDirUri(): Promise { const dataFolderPath = path.join(process.cwd(), 'data'); const userDataPath = path.join(dataFolderPath, 'user-data'); - // Check if data folder exists for portable mode - if (existsSync(dataFolderPath)) { - if (existsSync(userDataPath)) { + + const dataFolderExists = this.pathExistenceCache[dataFolderPath] ??= await pathExists(dataFolderPath); + if (dataFolderExists) { + const userDataExists = this.pathExistenceCache[userDataPath] ??= await pathExists(userDataPath); + if (userDataExists) { return FileUri.create(userDataPath).toString(true); } else { - mkdirSync(userDataPath); + await mkdir(userDataPath); + this.pathExistenceCache[userDataPath] = true; return FileUri.create(userDataPath).toString(true); } } else {