mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-02 09:35:40 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
190
src/vs/platform/environment/node/argv.ts
Normal file
190
src/vs/platform/environment/node/argv.ts
Normal file
@@ -0,0 +1,190 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as os from 'os';
|
||||
import * as minimist from 'minimist';
|
||||
import * as assert from 'assert';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ParsedArgs } from '../common/environment';
|
||||
import product from 'vs/platform/node/product';
|
||||
|
||||
const options: minimist.Opts = {
|
||||
string: [
|
||||
'locale',
|
||||
'user-data-dir',
|
||||
'extensions-dir',
|
||||
'extensionDevelopmentPath',
|
||||
'extensionTestsPath',
|
||||
'install-extension',
|
||||
'uninstall-extension',
|
||||
'debugId',
|
||||
'debugPluginHost',
|
||||
'debugBrkPluginHost',
|
||||
'open-url',
|
||||
'enable-proposed-api'
|
||||
],
|
||||
boolean: [
|
||||
'help',
|
||||
'version',
|
||||
'wait',
|
||||
'diff',
|
||||
'add',
|
||||
'goto',
|
||||
'new-window',
|
||||
'unity-launch',
|
||||
'reuse-window',
|
||||
'performance',
|
||||
'prof-startup',
|
||||
'verbose',
|
||||
'logExtensionHostCommunication',
|
||||
'disable-extensions',
|
||||
'list-extensions',
|
||||
'show-versions',
|
||||
'nolazy',
|
||||
'skip-getting-started'
|
||||
],
|
||||
alias: {
|
||||
add: 'a',
|
||||
help: 'h',
|
||||
version: 'v',
|
||||
wait: 'w',
|
||||
diff: 'd',
|
||||
goto: 'g',
|
||||
'new-window': 'n',
|
||||
'reuse-window': 'r',
|
||||
performance: 'p',
|
||||
'disable-extensions': 'disableExtensions',
|
||||
'extensions-dir': 'extensionHomePath',
|
||||
'debugPluginHost': 'inspect-extensions',
|
||||
'debugBrkPluginHost': 'inspect-brk-extensions',
|
||||
}
|
||||
};
|
||||
|
||||
function validate(args: ParsedArgs): ParsedArgs {
|
||||
if (args.goto) {
|
||||
args._.forEach(arg => assert(/^(\w:)?[^:]+(:\d*){0,2}$/.test(arg), localize('gotoValidation', "Arguments in `--goto` mode should be in the format of `FILE(:LINE(:CHARACTER))`.")));
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
function stripAppPath(argv: string[]): string[] {
|
||||
const index = firstIndex(argv, a => !/^-/.test(a));
|
||||
|
||||
if (index > -1) {
|
||||
return [...argv.slice(0, index), ...argv.slice(index + 1)];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to parse raw code process.argv such as: `Electron . --verbose --wait`
|
||||
*/
|
||||
export function parseMainProcessArgv(processArgv: string[]): ParsedArgs {
|
||||
let [, ...args] = processArgv;
|
||||
|
||||
// If dev, remove the first non-option argument: it's the app location
|
||||
if (process.env['VSCODE_DEV']) {
|
||||
args = stripAppPath(args);
|
||||
}
|
||||
|
||||
return validate(parseArgs(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to parse raw code CLI process.argv such as: `Electron cli.js . --verbose --wait`
|
||||
*/
|
||||
export function parseCLIProcessArgv(processArgv: string[]): ParsedArgs {
|
||||
let [, , ...args] = processArgv;
|
||||
|
||||
if (process.env['VSCODE_DEV']) {
|
||||
args = stripAppPath(args);
|
||||
}
|
||||
|
||||
return validate(parseArgs(args));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to parse code arguments such as `--verbose --wait`
|
||||
*/
|
||||
export function parseArgs(args: string[]): ParsedArgs {
|
||||
return minimist(args, options) as ParsedArgs;
|
||||
}
|
||||
|
||||
export const optionsHelp: { [name: string]: string; } = {
|
||||
'-d, --diff <file> <file>': localize('diff', "Compare two files with each other."),
|
||||
'-a, --add <dir>': localize('add', "Add folder(s) to the last active window."),
|
||||
'-g, --goto <file:line[:character]>': localize('goto', "Open a file at the path on the specified line and character position."),
|
||||
'--locale <locale>': localize('locale', "The locale to use (e.g. en-US or zh-TW)."),
|
||||
'-n, --new-window': localize('newWindow', "Force a new instance of Code."),
|
||||
'-p, --performance': localize('performance', "Start with the 'Developer: Startup Performance' command enabled."),
|
||||
'--prof-startup': localize('prof-startup', "Run CPU profiler during startup"),
|
||||
'-r, --reuse-window': localize('reuseWindow', "Force opening a file or folder in the last active window."),
|
||||
'--user-data-dir <dir>': localize('userDataDir', "Specifies the directory that user data is kept in, useful when running as root."),
|
||||
'--verbose': localize('verbose', "Print verbose output (implies --wait)."),
|
||||
'-w, --wait': localize('wait', "Wait for the window to be closed before returning."),
|
||||
'--extensions-dir <dir>': localize('extensionHomePath', "Set the root path for extensions."),
|
||||
'--list-extensions': localize('listExtensions', "List the installed extensions."),
|
||||
'--show-versions': localize('showVersions', "Show versions of installed extensions, when using --list-extension."),
|
||||
'--install-extension (<extension-id> | <extension-vsix-path>)': localize('installExtension', "Installs an extension."),
|
||||
'--uninstall-extension <extension-id>': localize('uninstallExtension', "Uninstalls an extension."),
|
||||
'--enable-proposed-api <extension-id>': localize('experimentalApis', "Enables proposed api features for an extension."),
|
||||
'--disable-extensions': localize('disableExtensions', "Disable all installed extensions."),
|
||||
'--disable-gpu': localize('disableGPU', "Disable GPU hardware acceleration."),
|
||||
'-v, --version': localize('version', "Print version."),
|
||||
'-h, --help': localize('help', "Print usage.")
|
||||
};
|
||||
|
||||
// TODO@Ben multi root
|
||||
if (product.quality === 'stable') {
|
||||
delete optionsHelp['-a, --add'];
|
||||
}
|
||||
|
||||
export function formatOptions(options: { [name: string]: string; }, columns: number): string {
|
||||
let keys = Object.keys(options);
|
||||
let argLength = Math.max.apply(null, keys.map(k => k.length)) + 2/*left padding*/ + 1/*right padding*/;
|
||||
if (columns - argLength < 25) {
|
||||
// Use a condensed version on narrow terminals
|
||||
return keys.reduce((r, key) => r.concat([` ${key}`, ` ${options[key]}`]), []).join('\n');
|
||||
}
|
||||
let descriptionColumns = columns - argLength - 1;
|
||||
let result = '';
|
||||
keys.forEach(k => {
|
||||
let wrappedDescription = wrapText(options[k], descriptionColumns);
|
||||
let keyPadding = (<any>' ').repeat(argLength - k.length - 2/*left padding*/);
|
||||
if (result.length > 0) {
|
||||
result += '\n';
|
||||
}
|
||||
result += ' ' + k + keyPadding + wrappedDescription[0];
|
||||
for (let i = 1; i < wrappedDescription.length; i++) {
|
||||
result += '\n' + (<any>' ').repeat(argLength) + wrappedDescription[i];
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function wrapText(text: string, columns: number): string[] {
|
||||
let lines: string[] = [];
|
||||
while (text.length) {
|
||||
let index = text.length < columns ? text.length : text.lastIndexOf(' ', columns);
|
||||
let line = text.slice(0, index).trim();
|
||||
text = text.slice(index);
|
||||
lines.push(line);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
export function buildHelpMessage(fullName: string, name: string, version: string): string {
|
||||
const columns = (<any>process.stdout).isTTY ? (<any>process.stdout).columns : 80;
|
||||
const executable = `${name}${os.platform() === 'win32' ? '.exe' : ''}`;
|
||||
|
||||
return `${fullName} ${version}
|
||||
|
||||
${ localize('usage', "Usage")}: ${executable} [${localize('options', "options")}] [${localize('paths', 'paths')}...]
|
||||
|
||||
${ localize('optionsUpperCase', "Options")}:
|
||||
${formatOptions(optionsHelp, columns)}`;
|
||||
}
|
||||
188
src/vs/platform/environment/node/environmentService.ts
Normal file
188
src/vs/platform/environment/node/environmentService.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import * as crypto from 'crypto';
|
||||
import * as paths from 'vs/base/node/paths';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import pkg from 'vs/platform/node/package';
|
||||
import product from 'vs/platform/node/product';
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function getNixIPCHandle(userDataPath: string, type: string): string {
|
||||
if (process.env['XDG_RUNTIME_DIR']) {
|
||||
return path.join(process.env['XDG_RUNTIME_DIR'], `${pkg.name}-${pkg.version}-${type}.sock`);
|
||||
}
|
||||
return path.join(userDataPath, `${pkg.version}-${type}.sock`);
|
||||
}
|
||||
|
||||
function getWin32IPCHandle(type: string): string {
|
||||
// Support to run VS Code multiple times as different user
|
||||
// by making the socket unique over the logged in user
|
||||
const userId = getUniqueUserId();
|
||||
const name = product.applicationName + (userId ? `-${userId}` : '');
|
||||
|
||||
return `\\\\.\\pipe\\${name}-${pkg.version}-${type}-sock`;
|
||||
}
|
||||
|
||||
function getIPCHandle(userDataPath: string, type: string): string {
|
||||
if (process.platform === 'win32') {
|
||||
return getWin32IPCHandle(type);
|
||||
} else {
|
||||
return getNixIPCHandle(userDataPath, type);
|
||||
}
|
||||
}
|
||||
|
||||
export class EnvironmentService implements IEnvironmentService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
get args(): ParsedArgs { return this._args; }
|
||||
|
||||
@memoize
|
||||
get appRoot(): string { return path.dirname(URI.parse(require.toUrl('')).fsPath); }
|
||||
|
||||
get execPath(): string { return this._execPath; }
|
||||
|
||||
@memoize
|
||||
get userHome(): string { return os.homedir(); }
|
||||
|
||||
@memoize
|
||||
get userDataPath(): string { return parseUserDataDir(this._args, process); }
|
||||
|
||||
get appNameLong(): string { return product.nameLong; }
|
||||
|
||||
get appQuality(): string { return product.quality; }
|
||||
|
||||
@memoize
|
||||
get appSettingsHome(): string { return path.join(this.userDataPath, 'User'); }
|
||||
|
||||
@memoize
|
||||
get appSettingsPath(): string { return path.join(this.appSettingsHome, 'settings.json'); }
|
||||
|
||||
@memoize
|
||||
get appKeybindingsPath(): string { return path.join(this.appSettingsHome, 'keybindings.json'); }
|
||||
|
||||
@memoize
|
||||
get isExtensionDevelopment(): boolean { return !!this._args.extensionDevelopmentPath; }
|
||||
|
||||
@memoize
|
||||
get backupHome(): string { return path.join(this.userDataPath, 'Backups'); }
|
||||
|
||||
@memoize
|
||||
get backupWorkspacesPath(): string { return path.join(this.backupHome, 'workspaces.json'); }
|
||||
|
||||
@memoize
|
||||
get workspacesHome(): string { return path.join(this.userDataPath, 'Workspaces'); }
|
||||
|
||||
@memoize
|
||||
get extensionsPath(): string { return parsePathArg(this._args['extensions-dir'], process) || process.env['VSCODE_EXTENSIONS'] || path.join(this.userHome, product.dataFolderName, 'extensions'); }
|
||||
|
||||
@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; }
|
||||
|
||||
get disableExtensions(): boolean { return this._args['disable-extensions']; }
|
||||
|
||||
get skipGettingStarted(): boolean { return this._args['skip-getting-started']; }
|
||||
|
||||
@memoize
|
||||
get debugExtensionHost(): { port: number; break: boolean; debugId: string } { return parseExtensionHostPort(this._args, this.isBuilt); }
|
||||
|
||||
get isBuilt(): boolean { return !process.env['VSCODE_DEV']; }
|
||||
get verbose(): boolean { return this._args.verbose; }
|
||||
get wait(): boolean { return this._args.wait; }
|
||||
get logExtensionHostCommunication(): boolean { return this._args.logExtensionHostCommunication; }
|
||||
|
||||
get performance(): boolean { return this._args.performance; }
|
||||
|
||||
@memoize
|
||||
get profileStartup(): { prefix: string, dir: string } | undefined {
|
||||
if (this._args['prof-startup']) {
|
||||
return {
|
||||
prefix: process.env.VSCODE_PROFILES_PREFIX,
|
||||
dir: os.homedir()
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@memoize
|
||||
get mainIPCHandle(): string { return getIPCHandle(this.userDataPath, 'main'); }
|
||||
|
||||
@memoize
|
||||
get sharedIPCHandle(): string { return getIPCHandle(this.userDataPath, 'shared'); }
|
||||
|
||||
@memoize
|
||||
get nodeCachedDataDir(): string { return this.isBuilt ? path.join(this.userDataPath, 'CachedData', product.commit) : undefined; }
|
||||
|
||||
readonly machineUUID: string;
|
||||
|
||||
constructor(private _args: ParsedArgs, private _execPath: string) {
|
||||
const machineIdPath = path.join(this.userDataPath, 'machineid');
|
||||
|
||||
try {
|
||||
this.machineUUID = fs.readFileSync(machineIdPath, 'utf8');
|
||||
} catch (err) {
|
||||
this.machineUUID = generateUuid();
|
||||
|
||||
try {
|
||||
fs.writeFileSync(machineIdPath, this.machineUUID);
|
||||
} catch (err) {
|
||||
console.warn('Could not store machine ID');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function parseExtensionHostPort(args: ParsedArgs, isBuild: boolean): { port: number; break: boolean; debugId: string } {
|
||||
const portStr = args.debugBrkPluginHost || args.debugPluginHost;
|
||||
const port = Number(portStr) || (!isBuild ? 5870 : null);
|
||||
const brk = port ? Boolean(!!args.debugBrkPluginHost) : false;
|
||||
return { port, break: brk, debugId: args.debugId };
|
||||
}
|
||||
|
||||
function parsePathArg(arg: string, process: NodeJS.Process): string {
|
||||
if (!arg) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
Reference in New Issue
Block a user