From d631cb8076aa8557b30af60ac1014befd8f91926 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 13 Jun 2018 15:53:26 +0200 Subject: [PATCH 1/9] main.js cleanup --- src/main.js | 131 +++++++++++++--------------------------------------- 1 file changed, 33 insertions(+), 98 deletions(-) diff --git a/src/main.js b/src/main.js index ce9c5e893b23d..d7cf61e6e623f 100644 --- a/src/main.js +++ b/src/main.js @@ -45,11 +45,18 @@ let fs = require('fs'); let path = require('path'); let minimist = require('minimist'); let paths = require('./paths'); +let product = require('../product.json'); let args = minimist(process.argv, { - string: ['user-data-dir', 'locale'] + string: [ + 'user-data-dir', + 'locale', + 'js-flags', + 'max-memory' + ] }); +//#region NLS function stripComments(content) { let regexp = /("(?:[^\\\"]*(?:\\.)?)*")|('(?:[^\\\']*(?:\\.)?)*')|(\/\*(?:\r?\n|.)*?\*\/)|(\/{2,}.*?(?:(?:\r?\n)|$))/g; let result = content.replace(regexp, function (match, m1, m2, m3, m4) { @@ -74,113 +81,38 @@ function stripComments(content) { return result; } -let _commit; -function getCommit() { - if (_commit) { - return _commit; - } - if (_commit === null) { - return undefined; - } - try { - let productJson = require(path.join(__dirname, '../product.json')); - if (productJson.commit) { - _commit = productJson.commit; - } else { - _commit = null; - } - } catch (exp) { - _commit = null; - } - return _commit || undefined; -} +const mkdir = dir => new Promise((c, e) => fs.mkdir(dir, err => (err && err.code !== 'EEXIST') ? e(err) : c())); +const exists = file => new Promise(c => fs.exists(file, c)); +const readFile = file => new Promise((c, e) => fs.readFile(file, 'utf8', (err, data) => err ? e(err) : c(data))); +const writeFile = (file, content) => new Promise((c, e) => fs.writeFile(file, content, 'utf8', err => err ? e(err) : c())); +const touch = file => new Promise((c, e) => { const d = new Date(); fs.utimes(file, d, d, err => err ? e(err) : c()); }); function mkdirp(dir) { - return mkdir(dir) - .then(null, (err) => { - if (err && err.code === 'ENOENT') { - let parent = path.dirname(dir); - if (parent !== dir) { // if not arrived at root - return mkdirp(parent) - .then(() => { - return mkdir(dir); - }); - } - } - throw err; - }); -} - -function mkdir(dir) { - return new Promise((resolve, reject) => { - fs.mkdir(dir, (err) => { - if (err && err.code !== 'EEXIST') { - reject(err); - } else { - resolve(dir); - } - }); - }); -} - -function exists(file) { - return new Promise((resolve) => { - fs.exists(file, (result) => { - resolve(result); - }); - }); -} - -function readFile(file) { - return new Promise((resolve, reject) => { - fs.readFile(file, 'utf8', (err, data) => { - if (err) { - reject(err); - return; - } - resolve(data); - }); - }); -} + return mkdir(dir).then(null, err => { + if (err && err.code === 'ENOENT') { + const parent = path.dirname(dir); -function writeFile(file, content) { - return new Promise((resolve, reject) => { - fs.writeFile(file, content, 'utf8', (err) => { - if (err) { - reject(err); - return; + if (parent !== dir) { // if not arrived at root + return mkdirp(parent).then(() => mkdir(dir)); } - resolve(undefined); - }); - }); -} + } -function touch(file) { - return new Promise((resolve, reject) => { - let d = new Date(); - fs.utimes(file, d, d, (err) => { - if (err) { - reject(err); - return; - } - resolve(undefined); - }); + throw err; }); } function resolveJSFlags() { - let jsFlags = []; + const jsFlags = []; + if (args['js-flags']) { jsFlags.push(args['js-flags']); } + if (args['max-memory'] && !/max_old_space_size=(\d+)/g.exec(args['js-flags'])) { jsFlags.push(`--max_old_space_size=${args['max-memory']}`); } - if (jsFlags.length > 0) { - return jsFlags.join(' '); - } else { - return null; - } + + return jsFlags.length > 0 ? jsFlags.join(' ') : null; } // Language tags are case insensitve however an amd loader is case sensitive @@ -285,7 +217,7 @@ function getNLSConfiguration(locale) { } perf.mark('nlsGeneration:start'); - let defaultResult = function(locale) { + let defaultResult = function (locale) { let isCoreLanguage = true; if (locale) { isCoreLanguage = ['de', 'es', 'fr', 'it', 'ja', 'ko', 'ru', 'zh-cn', 'zh-tw'].some((language) => { @@ -296,13 +228,13 @@ function getNLSConfiguration(locale) { let result = resolveLocale(locale); perf.mark('nlsGeneration:end'); return Promise.resolve(result); - } else { + } else { perf.mark('nlsGeneration:end'); return Promise.resolve({ locale: locale, availableLanguages: {} }); } }; try { - let commit = getCommit(); + let commit = product.commit; if (!commit) { return defaultResult(locale); } @@ -339,7 +271,7 @@ function getNLSConfiguration(locale) { return exists(coreLocation).then((fileExists) => { if (fileExists) { // We don't wait for this. No big harm if we can't touch - touch(coreLocation).catch(() => {}); + touch(coreLocation).catch(() => { }); perf.mark('nlsGeneration:end'); return result; } @@ -392,7 +324,9 @@ function getNLSConfiguration(locale) { return defaultResult(locale); } } +//#endregion +//#region Cached Data Dir function getNodeCachedDataDir() { // flag to disable cached data support if (process.argv.indexOf('--no-cached-data') > 0) { @@ -405,7 +339,7 @@ function getNodeCachedDataDir() { } // find commit id - let commit = getCommit(); + let commit = product.commit; if (!commit) { return Promise.resolve(undefined); } @@ -414,6 +348,7 @@ function getNodeCachedDataDir() { return mkdirp(dir).then(undefined, function () { /*ignore*/ }); } +//#endregion // Set userData path before app 'ready' event and call to process.chdir let userData = path.resolve(args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform)); From bd799550fe9057bf9aa2ef1dbd5c52971b23d3ed Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 13 Jun 2018 17:13:55 +0200 Subject: [PATCH 2/9] 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 db7b6cce2062d..49f934d092a36 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 d7cf61e6e623f..723f537b71227 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 381202a6d1bbd..f6c1d02397f8d 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 f85d99660c562..685ccc5d3740b 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 { From 7c8a164902cfa23c033c9c799dd2737dea3490a7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 14 Jun 2018 12:05:39 +0200 Subject: [PATCH 3/9] product.portableTemp --- src/cli.js | 2 +- src/main.js | 2 +- src/vs/platform/node/product.ts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cli.js b/src/cli.js index 49f934d092a36..6712d3ae0036a 100644 --- a/src/cli.js +++ b/src/cli.js @@ -24,7 +24,7 @@ function getPortableDataPath() { return path.join(path.dirname(getApplicationPath()), product.portable); } -if (product.portable) { +if (product.portable && product.portableTemp) { const portablePath = getPortableDataPath(); try { fs.mkdirSync(portablePath); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } diff --git a/src/main.js b/src/main.js index 723f537b71227..f4e5bc96a6b28 100644 --- a/src/main.js +++ b/src/main.js @@ -31,7 +31,7 @@ function getPortableDataPath() { return path.join(path.dirname(getApplicationPath()), product.portable); } -if (product.portable) { +if (product.portable && product.portableTemp) { const portablePath = getPortableDataPath(); try { fs.mkdirSync(portablePath); } catch (err) { if (err.code !== 'EEXIST') { throw err; } } diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index 685ccc5d3740b..1d3edb1d5f709 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -74,6 +74,7 @@ export interface IProductConfiguration { }; logUploaderUrl: string; portable?: string; + portableTemp?: string; } export interface ISurveyData { From b295b7228cde3b8a52263f7be7efeacd60b73de8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 14 Jun 2018 12:14:26 +0200 Subject: [PATCH 4/9] set portable mode --- src/vs/code/node/cli.ts | 24 +++++++++++++++++++++++- src/vs/platform/environment/node/argv.ts | 6 +++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 0c5a6074797e2..9b1073fad2eae 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { assign } from 'vs/base/common/objects'; import { parseCLIProcessArgv, buildHelpMessage } from 'vs/platform/environment/node/argv'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; -import product from 'vs/platform/node/product'; +import product, { IProductConfiguration } from 'vs/platform/node/product'; import pkg from 'vs/platform/node/package'; import * as paths from 'path'; import * as os from 'os'; @@ -19,6 +19,7 @@ import { resolveTerminalEncoding } from 'vs/base/node/encoding'; import * as iconv from 'iconv-lite'; import { writeFileAndFlushSync } from 'vs/base/node/extfs'; import { isWindows } from 'vs/base/common/platform'; +import uri from 'vs/base/common/uri'; function shouldSpawnCliProcess(argv: ParsedArgs): boolean { return !!argv['install-source'] @@ -31,6 +32,15 @@ interface IMainCli { main: (argv: ParsedArgs) => TPromise; } +function updateProductJsonSync(fn: (productJson: IProductConfiguration) => void): void { + const rootPath = paths.dirname(uri.parse(require.toUrl('')).fsPath); + const productJsonPath = paths.join(rootPath, 'product.json'); + const product = JSON.parse(fs.readFileSync(productJsonPath, 'utf8')) as IProductConfiguration; + fn(product); + + fs.writeFileSync(productJsonPath, JSON.stringify(product, null, '\t'), 'utf8'); +} + export async function main(argv: string[]): TPromise { let args: ParsedArgs; @@ -57,6 +67,18 @@ export async function main(argv: string[]): TPromise { return mainCli.then(cli => cli.main(args)); } + // Enable Portable + else if (args['set-portable']) { + updateProductJsonSync(product => product.portable = 'code-portable-data'); + console.log('Portable mode enabled'); + } + + // Disable Portable + else if (args['unset-portable']) { + updateProductJsonSync(product => { delete product.portable; delete product.portableTemp; }); + console.log('Portable mode disabled'); + } + // Write File else if (args['file-write']) { const source = args._[0]; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 529890d30348d..8d9b2900ed742 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -64,7 +64,9 @@ const options: minimist.Opts = { 'status', 'file-write', 'file-chmod', - 'driver-verbose' + 'driver-verbose', + 'set-portable', + 'unset-portable' ], alias: { add: 'a', @@ -150,6 +152,8 @@ const optionsHelp: { [name: string]: string; } = { '-w, --wait': localize('wait', "Wait for the files to be closed before returning."), '--locale ': localize('locale', "The locale to use (e.g. en-US or zh-TW)."), '--user-data-dir ': localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code."), + '--set-portable': localize('setPortable', "Enables portable mode"), + '--unset-portable': localize('unsedPortable', "Disables portable mode"), '-v, --version': localize('version', "Print version."), '-h, --help': localize('help', "Print usage.") }; From 79fe01eff6826ff124377848e3d0c8307b51d22e Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 18 Jun 2018 09:49:02 +0200 Subject: [PATCH 5/9] Revert "set portable mode" This reverts commit b295b7228cde3b8a52263f7be7efeacd60b73de8. --- src/vs/code/node/cli.ts | 24 +----------------------- src/vs/platform/environment/node/argv.ts | 6 +----- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/vs/code/node/cli.ts b/src/vs/code/node/cli.ts index 9b1073fad2eae..0c5a6074797e2 100644 --- a/src/vs/code/node/cli.ts +++ b/src/vs/code/node/cli.ts @@ -8,7 +8,7 @@ import { TPromise } from 'vs/base/common/winjs.base'; import { assign } from 'vs/base/common/objects'; import { parseCLIProcessArgv, buildHelpMessage } from 'vs/platform/environment/node/argv'; import { ParsedArgs } from 'vs/platform/environment/common/environment'; -import product, { IProductConfiguration } from 'vs/platform/node/product'; +import product from 'vs/platform/node/product'; import pkg from 'vs/platform/node/package'; import * as paths from 'path'; import * as os from 'os'; @@ -19,7 +19,6 @@ import { resolveTerminalEncoding } from 'vs/base/node/encoding'; import * as iconv from 'iconv-lite'; import { writeFileAndFlushSync } from 'vs/base/node/extfs'; import { isWindows } from 'vs/base/common/platform'; -import uri from 'vs/base/common/uri'; function shouldSpawnCliProcess(argv: ParsedArgs): boolean { return !!argv['install-source'] @@ -32,15 +31,6 @@ interface IMainCli { main: (argv: ParsedArgs) => TPromise; } -function updateProductJsonSync(fn: (productJson: IProductConfiguration) => void): void { - const rootPath = paths.dirname(uri.parse(require.toUrl('')).fsPath); - const productJsonPath = paths.join(rootPath, 'product.json'); - const product = JSON.parse(fs.readFileSync(productJsonPath, 'utf8')) as IProductConfiguration; - fn(product); - - fs.writeFileSync(productJsonPath, JSON.stringify(product, null, '\t'), 'utf8'); -} - export async function main(argv: string[]): TPromise { let args: ParsedArgs; @@ -67,18 +57,6 @@ export async function main(argv: string[]): TPromise { return mainCli.then(cli => cli.main(args)); } - // Enable Portable - else if (args['set-portable']) { - updateProductJsonSync(product => product.portable = 'code-portable-data'); - console.log('Portable mode enabled'); - } - - // Disable Portable - else if (args['unset-portable']) { - updateProductJsonSync(product => { delete product.portable; delete product.portableTemp; }); - console.log('Portable mode disabled'); - } - // Write File else if (args['file-write']) { const source = args._[0]; diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index 8d9b2900ed742..529890d30348d 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -64,9 +64,7 @@ const options: minimist.Opts = { 'status', 'file-write', 'file-chmod', - 'driver-verbose', - 'set-portable', - 'unset-portable' + 'driver-verbose' ], alias: { add: 'a', @@ -152,8 +150,6 @@ const optionsHelp: { [name: string]: string; } = { '-w, --wait': localize('wait', "Wait for the files to be closed before returning."), '--locale ': localize('locale', "The locale to use (e.g. en-US or zh-TW)."), '--user-data-dir ': localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code."), - '--set-portable': localize('setPortable', "Enables portable mode"), - '--unset-portable': localize('unsedPortable', "Disables portable mode"), '-v, --version': localize('version', "Print version."), '-h, --help': localize('help', "Print usage.") }; From 3d43c10398b159ae8941a412fd36a8833bcea764 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 18 Jun 2018 10:09:50 +0200 Subject: [PATCH 6/9] portable: check folder --- src/cli.js | 22 +++++++------- src/main.js | 29 +++++++++++-------- .../environment/node/environmentService.ts | 19 +++--------- src/vs/platform/node/product.ts | 1 - .../parts/terminal/node/terminalProcess.ts | 3 +- 5 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/cli.js b/src/cli.js index 6712d3ae0036a..1bb0476f61f59 100644 --- a/src/cli.js +++ b/src/cli.js @@ -20,18 +20,20 @@ function getApplicationPath() { } } -function getPortableDataPath() { - return path.join(path.dirname(getApplicationPath()), product.portable); +const portableDataName = product.portable || `${product.applicationName}-portable-data`; +const portableDataPath = path.join(path.dirname(getApplicationPath()), portableDataName); +const isPortable = fs.existsSync(portableDataPath); +const portableTempPath = path.join(portableDataPath, 'tmp'); +const isTempPortable = isPortable && fs.existsSync(portableTempPath); + +if (isPortable) { + process.env['VSCODE_PORTABLE'] = portableDataPath; +} else { + delete process.env['VSCODE_PORTABLE']; } -if (product.portable && product.portableTemp) { - 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; +if (isTempPortable) { + process.env[process.platform === 'win32' ? 'TEMP' : 'TMPDIR'] = portableTempPath; } //#region Add support for using node_modules.asar diff --git a/src/main.js b/src/main.js index f4e5bc96a6b28..a73456948f47f 100644 --- a/src/main.js +++ b/src/main.js @@ -27,20 +27,25 @@ function getApplicationPath() { } } -function getPortableDataPath() { - return path.join(path.dirname(getApplicationPath()), product.portable); +const portableDataName = product.portable || `${product.applicationName}-portable-data`; +const portableDataPath = process.env['VSCODE_PORTABLE'] || path.join(path.dirname(getApplicationPath()), portableDataName); +const isPortable = fs.existsSync(portableDataPath); +const portableTempPath = path.join(portableDataPath, 'tmp'); +const isTempPortable = isPortable && fs.existsSync(portableTempPath); + +if (isPortable) { + process.env['VSCODE_PORTABLE'] = portableDataPath; +} else { + delete process.env['VSCODE_PORTABLE']; } -if (product.portable && product.portableTemp) { - 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; +if (isTempPortable) { + process.env[process.platform === 'win32' ? 'TEMP' : 'TMPDIR'] = portableTempPath; } +console.log('portableDataPath', portableDataPath); +console.log('isPortable', isPortable); + //#region Add support for using node_modules.asar (function () { const path = require('path'); @@ -377,8 +382,8 @@ function getNodeCachedDataDir() { //#endregion function getUserDataPath() { - if (product.portable) { - return path.join(getPortableDataPath(), 'user-data'); + if (isPortable) { + return path.join(portableDataPath, 'user-data'); } return path.resolve(args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform)); diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index f6c1d02397f8d..06e2171dfb51b 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -89,21 +89,10 @@ export class EnvironmentService implements IEnvironmentService { @memoize get userHome(): string { return os.homedir(); } - @memoize - 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'); + if (process.env['VSCODE_PORTABLE']) { + return path.join(process.env['VSCODE_PORTABLE'], 'user-data'); } return parseUserDataDir(this._args, process); @@ -151,8 +140,8 @@ export class EnvironmentService implements IEnvironmentService { 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 if (process.env['VSCODE_PORTABLE']) { + return path.join(process.env['VSCODE_PORTABLE'], 'extensions'); } else { return path.join(this.userHome, product.dataFolderName, 'extensions'); } diff --git a/src/vs/platform/node/product.ts b/src/vs/platform/node/product.ts index 1d3edb1d5f709..685ccc5d3740b 100644 --- a/src/vs/platform/node/product.ts +++ b/src/vs/platform/node/product.ts @@ -74,7 +74,6 @@ export interface IProductConfiguration { }; logUploaderUrl: string; portable?: string; - portableTemp?: string; } export interface ISurveyData { diff --git a/src/vs/workbench/parts/terminal/node/terminalProcess.ts b/src/vs/workbench/parts/terminal/node/terminalProcess.ts index e3a7383153825..2ad362e73d2c8 100644 --- a/src/vs/workbench/parts/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/parts/terminal/node/terminalProcess.ts @@ -116,7 +116,8 @@ function cleanEnv() { 'PTYCOLS', 'PTYROWS', 'PTYSHELLCMDLINE', - 'VSCODE_LOGS' + 'VSCODE_LOGS', + 'VSCODE_PORTABLE' ]; keys.forEach(function (key) { if (process.env[key]) { From 2e332cc8942c19f6322966b07bc11a137d2c0bf7 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 18 Jun 2018 16:07:10 +0200 Subject: [PATCH 7/9] fix portable env state propagation in linux --- src/vs/code/electron-main/main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index 9eb5162971cd3..ea19b3997be7c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -321,7 +321,8 @@ function main() { const instanceEnv: typeof process.env = { VSCODE_IPC_HOOK: environmentService.mainIPCHandle, VSCODE_NLS_CONFIG: process.env['VSCODE_NLS_CONFIG'], - VSCODE_LOGS: process.env['VSCODE_LOGS'] + VSCODE_LOGS: process.env['VSCODE_LOGS'], + VSCODE_PORTABLE: process.env['VSCODE_PORTABLE'] }; assign(process.env, instanceEnv); From 19753e49e5a61b21bc47cfd1b1c57b5b42bfa8f4 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 18 Jun 2018 17:03:48 +0200 Subject: [PATCH 8/9] fix portable in linux --- src/vs/code/electron-main/main.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index ea19b3997be7c..632ecd517abb4 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -321,9 +321,13 @@ function main() { const instanceEnv: typeof process.env = { VSCODE_IPC_HOOK: environmentService.mainIPCHandle, VSCODE_NLS_CONFIG: process.env['VSCODE_NLS_CONFIG'], - VSCODE_LOGS: process.env['VSCODE_LOGS'], - VSCODE_PORTABLE: process.env['VSCODE_PORTABLE'] + VSCODE_LOGS: process.env['VSCODE_LOGS'] }; + + if (process.env['VSCODE_PORTABLE']) { + instanceEnv['VSCODE_PORTABLE'] = process.env['VSCODE_PORTABLE']; + } + assign(process.env, instanceEnv); // Startup From 76f39b2ed114d8c039ca537f5c8751dc57646f33 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Mon, 18 Jun 2018 20:02:02 +0200 Subject: [PATCH 9/9] remove console.log --- src/main.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main.js b/src/main.js index a73456948f47f..2946f2490b2e4 100644 --- a/src/main.js +++ b/src/main.js @@ -43,9 +43,6 @@ if (isTempPortable) { process.env[process.platform === 'win32' ? 'TEMP' : 'TMPDIR'] = portableTempPath; } -console.log('portableDataPath', portableDataPath); -console.log('isPortable', isPortable); - //#region Add support for using node_modules.asar (function () { const path = require('path');