From bd799550fe9057bf9aa2ef1dbd5c52971b23d3ed Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 13 Jun 2018 17:13:55 +0200 Subject: [PATCH] portable mode --- src/cli.js | 31 +++++++++++ src/main.js | 53 +++++++++++++++---- .../environment/node/environmentService.ts | 33 +++++++++++- src/vs/platform/node/product.ts | 1 + 4 files changed, 106 insertions(+), 12 deletions(-) diff --git a/src/cli.js b/src/cli.js index db7b6cce206..49f934d092a 100644 --- a/src/cli.js +++ b/src/cli.js @@ -3,6 +3,37 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) + +const fs = require('fs'); +const path = require('path'); +const product = require('../product.json'); +const appRoot = path.dirname(__dirname); + +function getApplicationPath() { + if (process.env['VSCODE_DEV']) { + return appRoot; + } else if (process.platform === 'darwin') { + return path.dirname(path.dirname(path.dirname(appRoot))); + } else { + return path.dirname(path.dirname(appRoot)); + } +} + +function getPortableDataPath() { + return path.join(path.dirname(getApplicationPath()), product.portable); +} + +if (product.portable) { + const portablePath = getPortableDataPath(); + try { fs.mkdirSync(portablePath); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } + + const tmpdir = path.join(portablePath, 'tmp'); + try { fs.mkdirSync(tmpdir); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } + + process.env[process.platform === 'win32' ? 'TEMP' : 'TMPDIR'] = tmpdir; +} + //#region Add support for using node_modules.asar (function () { const path = require('path'); diff --git a/src/main.js b/src/main.js index d7cf61e6e62..723f537b712 100644 --- a/src/main.js +++ b/src/main.js @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -let perf = require('./vs/base/common/performance'); +const perf = require('./vs/base/common/performance'); perf.mark('main:started'); // Perf measurements @@ -12,6 +12,35 @@ global.perfStartTime = Date.now(); Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https://github.com/v8/v8/wiki/Stack-Trace-API) +const fs = require('fs'); +const path = require('path'); +const product = require('../product.json'); +const appRoot = path.dirname(__dirname); + +function getApplicationPath() { + if (process.env['VSCODE_DEV']) { + return appRoot; + } else if (process.platform === 'darwin') { + return path.dirname(path.dirname(path.dirname(appRoot))); + } else { + return path.dirname(path.dirname(appRoot)); + } +} + +function getPortableDataPath() { + return path.join(path.dirname(getApplicationPath()), product.portable); +} + +if (product.portable) { + const portablePath = getPortableDataPath(); + try { fs.mkdirSync(portablePath); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } + + const tmpdir = path.join(portablePath, 'tmp'); + try { fs.mkdirSync(tmpdir); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } + + process.env[process.platform === 'win32' ? 'TEMP' : 'TMPDIR'] = tmpdir; +} + //#region Add support for using node_modules.asar (function () { const path = require('path'); @@ -36,18 +65,15 @@ Error.stackTraceLimit = 100; // increase number of stack frames (from 10, https: })(); //#endregion -let app = require('electron').app; +const app = require('electron').app; // TODO@Ben Electron 2.0.x: prevent localStorage migration from SQLite to LevelDB due to issues app.commandLine.appendSwitch('disable-mojo-local-storage'); -let fs = require('fs'); -let path = require('path'); -let minimist = require('minimist'); -let paths = require('./paths'); -let product = require('../product.json'); +const minimist = require('minimist'); +const paths = require('./paths'); -let args = minimist(process.argv, { +const args = minimist(process.argv, { string: [ 'user-data-dir', 'locale', @@ -350,9 +376,16 @@ function getNodeCachedDataDir() { } //#endregion +function getUserDataPath() { + if (product.portable) { + return path.join(getPortableDataPath(), 'user-data'); + } + + return path.resolve(args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform)); +} + // Set userData path before app 'ready' event and call to process.chdir -let userData = path.resolve(args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform)); -app.setPath('userData', userData); +app.setPath('userData', getUserDataPath()); // Update cwd based on environment and platform try { diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 381202a6d1b..f6c1d02397f 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -90,7 +90,24 @@ export class EnvironmentService implements IEnvironmentService { get userHome(): string { return os.homedir(); } @memoize - get userDataPath(): string { return parseUserDataDir(this._args, process); } + private get appPath(): string { + if (process.env['VSCODE_DEV']) { + return this.appRoot; + } else if (process.platform === 'darwin') { + return path.dirname(path.dirname(path.dirname(this.appRoot))); + } else { + return path.dirname(path.dirname(this.appRoot)); + } + } + + @memoize + get userDataPath(): string { + if (product.portable) { + return path.join(path.dirname(this.appPath), product.portable, 'user-data'); + } + + return parseUserDataDir(this._args, process); + } get appNameLong(): string { return product.nameLong; } @@ -127,7 +144,19 @@ export class EnvironmentService implements IEnvironmentService { get installSourcePath(): string { return path.join(this.userDataPath, 'installSource'); } @memoize - get extensionsPath(): string { return parsePathArg(this._args['extensions-dir'], process) || process.env['VSCODE_EXTENSIONS'] || path.join(this.userHome, product.dataFolderName, 'extensions'); } + get extensionsPath(): string { + const fromArgs = parsePathArg(this._args['extensions-dir'], process); + + if (fromArgs) { + return fromArgs; + } else if (process.env['VSCODE_EXTENSIONS']) { + return process.env['VSCODE_EXTENSIONS']; + } else if (product.portable) { + return path.join(path.dirname(this.appPath), product.portable, 'extensions'); + } else { + return path.join(this.userHome, product.dataFolderName, 'extensions'); + } + } @memoize get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath ? path.normalize(this._args.extensionDevelopmentPath) : this._args.extensionDevelopmentPath; } diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index f85d99660c5..685ccc5d374 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -73,6 +73,7 @@ export interface IProductConfiguration { 'darwin': string; }; logUploaderUrl: string; + portable?: string; } export interface ISurveyData { -- GitLab