environmentService.ts 5.2 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

J
Joao Moreno 已提交
6
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
7
import * as crypto from 'crypto';
J
Joao Moreno 已提交
8 9 10
import * as paths from 'vs/base/node/paths';
import * as os from 'os';
import * as path from 'path';
11
import URI from 'vs/base/common/uri';
12
import { memoize } from 'vs/base/common/decorators';
13 14
import pkg from 'vs/platform/node/package';
import product from 'vs/platform/node/product';
J
Joao Moreno 已提交
15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
function getUniqueUserId(): string {
	let username: string;
	if (process.platform === 'win32') {
		username = process.env.USERNAME;
	} else {
		username = process.env.USER;
	}

	if (!username) {
		return ''; // fail gracefully if there is no user name
	}

	// use sha256 to ensure the userid value can be used in filenames and are unique
	return crypto.createHash('sha256').update(username).digest('hex').substr(0, 6);
}

J
Joao Moreno 已提交
32
function getIPCHandlePrefix(): string {
33 34 35 36 37 38
	let name = pkg.name;

	// Support to run VS Code multiple times as different user
	// by making the socket unique over the logged in user
	let userId = getUniqueUserId();
	if (userId) {
J
Johannes Rieken 已提交
39
		name += `-${userId}`;
40 41 42
	}

	if (process.platform === 'win32') {
J
Johannes Rieken 已提交
43
		return `\\\\.\\pipe\\${name}`;
44 45 46 47 48
	}

	return path.join(os.tmpdir(), name);
}

J
Joao Moreno 已提交
49 50 51
function getIPCHandleSuffix(): string {
	return process.platform === 'win32' ? '-sock' : '.sock';
}
52

J
Joao Moreno 已提交
53 54
export class EnvironmentService implements IEnvironmentService {

55
	_serviceBrand: any;
J
Joao Moreno 已提交
56

J
Joao Moreno 已提交
57 58
	get args(): ParsedArgs { return this._args; }

59 60
	@memoize
	get appRoot(): string { return path.dirname(URI.parse(require.toUrl('')).fsPath); }
J
Joao Moreno 已提交
61 62

	get execPath(): string { return this._execPath; }
63

64
	@memoize
65 66 67 68
	get userHome(): string { return os.homedir(); }

	@memoize
	get userProductHome(): string { return path.join(this.userHome, product.dataFolderName); }
J
Joao Moreno 已提交
69

70
	@memoize
71
	get userDataPath(): string { return parseUserDataDir(this._args, process); }
J
Joao Moreno 已提交
72

73 74 75 76
	get appNameLong(): string { return product.nameLong; }

	get appQuality(): string { return product.quality; }

77 78
	@memoize
	get appSettingsHome(): string { return path.join(this.userDataPath, 'User'); }
79

80 81
	@memoize
	get appSettingsPath(): string { return path.join(this.appSettingsHome, 'settings.json'); }
82

83 84
	@memoize
	get appKeybindingsPath(): string { return path.join(this.appSettingsHome, 'keybindings.json'); }
85

86
	@memoize
87
	get isExtensionDevelopment(): boolean { return !!this._args.extensionDevelopmentPath; }
88

89 90 91 92 93 94
	@memoize
	get backupHome(): string { return path.join(this.userDataPath, 'Backups'); }

	@memoize
	get backupWorkspacesPath(): string { return path.join(this.backupHome, 'workspaces.json'); }

95
	@memoize
J
João Moreno 已提交
96
	get extensionsPath(): string { return parsePathArg(this._args['extensions-dir'], process) || path.join(this.userProductHome, 'extensions'); }
J
Joao Moreno 已提交
97

98 99 100 101 102
	@memoize
	get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath ? path.normalize(this._args.extensionDevelopmentPath) : this._args.extensionDevelopmentPath; }

	@memoize
	get extensionTestsPath(): string { return this._args.extensionTestsPath ? path.normalize(this._args.extensionTestsPath) : this._args.extensionTestsPath; }
103

J
Johannes Rieken 已提交
104
	get disableExtensions(): boolean { return this._args['disable-extensions']; }
B
Benjamin Pasero 已提交
105

106
	@memoize
J
Joao Moreno 已提交
107
	get debugExtensionHost(): { port: number; break: boolean; } { return parseExtensionHostPort(this._args, this.isBuilt); }
108

109
	get isBuilt(): boolean { return !process.env['VSCODE_DEV']; }
J
Joao Moreno 已提交
110
	get verbose(): boolean { return this._args.verbose; }
111
	get wait(): boolean { return this._args.wait; }
J
Joao Moreno 已提交
112 113
	get performance(): boolean { return this._args.performance; }
	get logExtensionHostCommunication(): boolean { return this._args.logExtensionHostCommunication; }
114

115
	@memoize
J
Joao Moreno 已提交
116
	get mainIPCHandle(): string { return `${getIPCHandlePrefix()}-${pkg.version}${getIPCHandleSuffix()}`; }
117 118

	@memoize
J
Joao Moreno 已提交
119
	get sharedIPCHandle(): string { return `${getIPCHandlePrefix()}-${pkg.version}-shared${getIPCHandleSuffix()}`; }
120

121
	@memoize
122
	get nodeCachedDataDir(): string { return path.join(this.userDataPath, 'CachedData'); }
123

J
Johannes Rieken 已提交
124
	constructor(private _args: ParsedArgs, private _execPath: string) { }
125 126
}

J
Joao Moreno 已提交
127
export function parseExtensionHostPort(args: ParsedArgs, isBuild: boolean): { port: number; break: boolean; } {
128 129 130
	const portStr = args.debugBrkPluginHost || args.debugPluginHost;
	const port = Number(portStr) || (!isBuild ? 5870 : null);
	const brk = port ? Boolean(!!args.debugBrkPluginHost) : false;
J
Joao Moreno 已提交
131
	return { port, break: brk };
132 133
}

J
João Moreno 已提交
134 135 136
function parsePathArg(arg: string, process: NodeJS.Process): string {
	if (!arg) {
		return;
137
	}
J
João Moreno 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151

	// Determine if the arg is relative or absolute, if relative use the original CWD
	// (VSCODE_CWD), not the potentially overridden one (process.cwd()).
	const resolved = path.resolve(arg);

	if (path.normalize(arg) === resolved) {
		return resolved;
	} else {
		return path.resolve(process.env['VSCODE_CWD'] || process.cwd(), arg);
	}
}

export function parseUserDataDir(args: ParsedArgs, process: NodeJS.Process): string {
	return parsePathArg(args['user-data-dir'], process) || path.resolve(paths.getDefaultUserDataPath(process.platform));
152
}