cliProcessMain.ts 7.5 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 { localize } from 'vs/nls';
7 8
import product from 'vs/platform/product';
import pkg from 'vs/platform/package';
J
Joao Moreno 已提交
9 10
import { ParsedArgs } from 'vs/code/node/argv';
import { TPromise } from 'vs/base/common/winjs.base';
11
import { sequence } from 'vs/base/common/async';
J
Joao Moreno 已提交
12 13 14 15 16 17 18 19
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IEventService } from 'vs/platform/event/common/event';
import { EventService } from 'vs/platform/event/common/eventService';
J
Joao Moreno 已提交
20
import { IExtensionManagementService, IExtensionGalleryService, IQueryResult, IExtensionManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
J
Joao Moreno 已提交
21 22
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/node/extensionGalleryService';
23 24 25
import { ITelemetryService, combinedAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
J
Joao Moreno 已提交
26 27 28 29
import { IRequestService } from 'vs/platform/request/common/request';
import { NodeRequestService } from 'vs/platform/request/node/nodeRequestService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { NodeConfigurationService } from 'vs/platform/configuration/node/nodeConfigurationService';
30
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
J
Joao Moreno 已提交
31

J
Joao Moreno 已提交
32
const notFound = id => localize('notFound', "Extension '{0}' not found.", id);
J
Joao Moreno 已提交
33
const notInstalled = id => localize('notInstalled', "Extension '{0}' is not installed.", id);
J
Joao Moreno 已提交
34
const useId = localize('useId', "Make sure you use the full extension ID, eg: {0}", 'ms-vscode.csharp');
J
Joao Moreno 已提交
35

J
Joao Moreno 已提交
36 37 38 39
function getId(manifest: IExtensionManifest): string {
	return `${ manifest.publisher }.${ manifest.name }`;
}

J
Joao Moreno 已提交
40 41 42 43 44 45 46 47
class Main {

	constructor(
		@IExtensionManagementService private extensionManagementService: IExtensionManagementService,
		@IExtensionGalleryService private extensionGalleryService: IExtensionGalleryService
	) {}

	run(argv: ParsedArgs): TPromise<any> {
J
Joao Moreno 已提交
48 49
		// TODO@joao - make this contributable

J
Joao Moreno 已提交
50
		if (argv['list-extensions']) {
J
Joao Moreno 已提交
51 52
			return this.listExtensions();
		} else if (argv['install-extension']) {
53 54 55
			const arg = argv['install-extension'];
			const ids: string[] = typeof arg === 'string' ? [arg] : arg;
			return this.installExtension(ids);
J
Joao Moreno 已提交
56
		} else if (argv['uninstall-extension']) {
57 58 59
			const arg = argv['uninstall-extension'];
			const ids: string[] = typeof arg === 'string' ? [arg] : arg;
			return this.uninstallExtension(ids);
J
Joao Moreno 已提交
60 61
		}
	}
J
Joao Moreno 已提交
62 63 64

	private listExtensions(): TPromise<any> {
		return this.extensionManagementService.getInstalled().then(extensions => {
J
Joao Moreno 已提交
65
			extensions.forEach(e => console.log(getId(e.manifest)));
J
Joao Moreno 已提交
66 67 68
		});
	}

69
	private installExtension(ids: string[]): TPromise<any> {
70 71
		return sequence(ids.map(id => () => {
			return this.extensionManagementService.getInstalled().then(installed => {
J
Joao Moreno 已提交
72
				const isInstalled = installed.some(e => getId(e.manifest) === id);
73 74

				if (isInstalled) {
75
					console.log(localize('alreadyInstalled', "Extension '{0}' is already installed.", id));
J
Joao Moreno 已提交
76
					return TPromise.as(null);
77
				}
J
Joao Moreno 已提交
78

J
Joao Moreno 已提交
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
				return this.extensionGalleryService.query({ ids: [id] })
					.then<IQueryResult>(null, err => {
						if (err.responseText) {
							try {
								const response = JSON.parse(err.responseText);
								return TPromise.wrapError(response.message);
							} catch (e) {
								return TPromise.wrapError(err);
							}
						}
					})
					.then(result => {
						const [extension] = result.firstPage;

						if (!extension) {
							return TPromise.wrapError(`${ notFound(id) }\n${ useId }`);
						}

						console.log(localize('foundExtension', "Found '{0}' in the marketplace.", id));
						console.log(localize('installing', "Installing..."));

J
Joao Moreno 已提交
100
						return this.extensionManagementService.install(extension).then(() => {
J
Joao Moreno 已提交
101
							console.log(localize('successInstall', "Extension '{0}' v{1} was successfully installed!", id, extension.manifest.version));
J
Joao Moreno 已提交
102
						});
103
					});
104 105
			});
		}));
J
Joao Moreno 已提交
106
	}
J
Joao Moreno 已提交
107

108 109 110
	private uninstallExtension(ids: string[]): TPromise<any> {
		return sequence(ids.map(id => () => {
			return this.extensionManagementService.getInstalled().then(installed => {
J
Joao Moreno 已提交
111
				const [extension] = installed.filter(e => getId(e.manifest) === id);
J
Joao Moreno 已提交
112

113 114 115
				if (!extension) {
					return TPromise.wrapError(`${ notInstalled(id) }\n${ useId }`);
				}
J
Joao Moreno 已提交
116

117
				console.log(localize('uninstalling', "Uninstalling {0}...", id));
J
Joao Moreno 已提交
118

119 120 121
				return this.extensionManagementService.uninstall(extension).then(() => {
					console.log(localize('successUninstall', "Extension '{0}' was successfully uninstalled!", id));
				});
J
Joao Moreno 已提交
122
			});
123
		}));
J
Joao Moreno 已提交
124
	}
J
Joao Moreno 已提交
125 126
}

127 128
const eventPrefix = 'monacoworkbench';

J
Joao Moreno 已提交
129 130 131 132 133
export function main(argv: ParsedArgs): TPromise<void> {
	const services = new ServiceCollection();
	services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService));

	const instantiationService: IInstantiationService = new InstantiationService(services);
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

	return instantiationService.invokeFunction(accessor => {
		const services = new ServiceCollection();
		services.set(IEventService, new SyncDescriptor(EventService));
		services.set(IConfigurationService, new SyncDescriptor(NodeConfigurationService));
		services.set(IRequestService, new SyncDescriptor(NodeRequestService));
		services.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementService));
		services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService));

		const { appRoot, extensionsPath, extensionDevelopmentPath, isBuilt } = accessor.get(IEnvironmentService);

		if (isBuilt && !extensionDevelopmentPath && product.enableTelemetry) {
			const appenders: AppInsightsAppender[] = [];

			if (product.aiConfig && product.aiConfig.key) {
				appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.key));
			}

			if (product.aiConfig && product.aiConfig.asimovKey) {
				appenders.push(new AppInsightsAppender(eventPrefix, null, product.aiConfig.asimovKey));
			}

			// It is important to dispose the AI adapter properly because
			// only then they flush remaining data.
			process.once('exit', () => appenders.forEach(a => a.dispose()));

			const config: ITelemetryServiceConfig = {
				appender: combinedAppender(...appenders),
				commonProperties: resolveCommonProperties(product.commit, pkg.version),
				piiPaths: [appRoot, extensionsPath]
			};

			services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config));
		} else {
			services.set(ITelemetryService, NullTelemetryService);
		}

		const instantiationService2 = instantiationService.createChild(services);
		const main = instantiationService2.createInstance(Main);

		return main.run(argv);
	});
J
Joao Moreno 已提交
176
}