diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index 8ef5cc8dd0d3f31a713a244c1bbc0406c5503a07..c5514f4eff7ca276c3cc5b814e5736dcbbe83508 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -55,7 +55,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider'; import { Schemas } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; export interface ISharedProcessConfiguration { readonly machineId: string; @@ -111,10 +110,10 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat await configurationService.initialize(); services.set(IEnvironmentService, environmentService); + services.set(IProductService, { _serviceBrand: undefined, ...product }); services.set(ILogService, logService); services.set(IConfigurationService, configurationService); services.set(IRequestService, new SyncDescriptor(RequestService)); - services.set(IProductService, new SyncDescriptor(ProductService)); const mainProcessService = new MainProcessService(server, mainRouter); services.set(IMainProcessService, mainProcessService); diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index d9ed94ff68e500d653f70d4ea07afa7349f6b19d..32005dd153ea0bd94940edf2aae0383e11aedbf8 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -47,7 +47,6 @@ import { IFileService } from 'vs/platform/files/common/files'; import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id); const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id); @@ -325,7 +324,7 @@ export async function main(argv: ParsedArgs): Promise { services.set(ILogService, logService); services.set(IConfigurationService, configurationService); services.set(IStateService, new SyncDescriptor(StateService)); - services.set(IProductService, new SyncDescriptor(ProductService)); + services.set(IProductService, { _serviceBrand: undefined, ...product }); // Files const fileService = new FileService(logService); diff --git a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts index 42fbff47fe24ffe82bf3f1924327e7c2a15c231b..2d39c51297528a4642b9a945aa31762e44fa9c41 100644 --- a/src/vs/platform/extensionManagement/common/extensionGalleryService.ts +++ b/src/vs/platform/extensionManagement/common/extensionGalleryService.ts @@ -342,10 +342,10 @@ export class ExtensionGalleryService implements IExtensionGalleryService { @IProductService private readonly productService: IProductService, @optional(IStorageService) private readonly storageService: IStorageService, ) { - const config = productService.productConfiguration.extensionsGallery; + const config = productService.extensionsGallery; this.extensionsGalleryUrl = config && config.serviceUrl; this.extensionsControlUrl = config && config.controlUrl; - this.commonHeadersPromise = resolveMarketplaceHeaders(productService.productConfiguration.version, this.environmentService, this.fileService, this.storageService); + this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, this.environmentService, this.fileService, this.storageService); } private api(path = ''): string { @@ -358,7 +358,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { getCompatibleExtension(arg1: IExtensionIdentifier | IGalleryExtension, version?: string): Promise { const extension: IGalleryExtension | null = isIExtensionIdentifier(arg1) ? null : arg1; - if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { + if (extension && extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return Promise.resolve(extension); } const { id, uuid } = extension ? extension.identifier : arg1; @@ -384,7 +384,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const versionAsset = rawExtension.versions.filter(v => v.version === version)[0]; if (versionAsset) { const extension = toExtension(rawExtension, versionAsset, 0, query); - if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.productConfiguration.version)) { + if (extension.properties.engine && isEngineValid(extension.properties.engine, this.productService.version)) { return extension; } } @@ -619,7 +619,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { return this.queryGallery(query, CancellationToken.None).then(({ galleryExtensions }) => { if (galleryExtensions.length) { if (compatible) { - return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.productConfiguration.version) ? v : null))) + return Promise.all(galleryExtensions[0].versions.map(v => this.getEngine(v).then(engine => isEngineValid(engine, this.productService.version) ? v : null))) .then(versions => versions .filter(v => !!v) .map(v => ({ version: v!.version, date: v!.lastUpdated }))); @@ -705,7 +705,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { if (!engine) { return null; } - if (isEngineValid(engine, this.productService.productConfiguration.version)) { + if (isEngineValid(engine, this.productService.version)) { return Promise.resolve(version); } } @@ -737,7 +737,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService { const version = versions[0]; return this.getEngine(version) .then(engine => { - if (!isEngineValid(engine, this.productService.productConfiguration.version)) { + if (!isEngineValid(engine, this.productService.version)) { return this.getLastValidExtensionVersionRecursively(extension, versions.slice(1)); } diff --git a/src/vs/platform/product/browser/productService.ts b/src/vs/platform/product/browser/productService.ts deleted file mode 100644 index fae6e1d5fa7c07287470e77cca580489a0072370..0000000000000000000000000000000000000000 --- a/src/vs/platform/product/browser/productService.ts +++ /dev/null @@ -1,26 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; - -export class ProductService implements IProductService { - - _serviceBrand!: ServiceIdentifier; - - readonly productConfiguration: IProductConfiguration; - - constructor() { - const element = document.getElementById('vscode-remote-product-configuration'); - this.productConfiguration = { - ...element ? JSON.parse(element.getAttribute('data-settings')!) : { - version: '1.38.0-unknown', - nameLong: 'Unknown', - extensionAllowedProposedApi: [], - }, ...{ urlProtocol: '', enableTelemetry: false } - }; - } - -} diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index ec42094d94cd791e8fa8498b436a6bd761b784a9..3797e18a25ea4ff7bea2c498ac2de0597d5794fa 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -3,19 +3,18 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const IProductService = createDecorator('productService'); -export interface IProductService { +export interface IProductService extends Readonly { - _serviceBrand: ServiceIdentifier; + _serviceBrand: undefined; - readonly productConfiguration: IProductConfiguration; } export interface IProductConfiguration { - readonly version: string; + version: string; nameShort: string; nameLong: string; readonly applicationName: string; diff --git a/src/vs/platform/product/node/product.ts b/src/vs/platform/product/node/product.ts index 08610d71a1a2b027c21bd587e626882b990098e5..3d13f26c57605a1755265cccc412e33e5811edcc 100644 --- a/src/vs/platform/product/node/product.ts +++ b/src/vs/platform/product/node/product.ts @@ -6,6 +6,7 @@ import * as path from 'vs/base/common/path'; import { getPathFromAmdModule } from 'vs/base/common/amd'; import { IProductConfiguration } from 'vs/platform/product/common/product'; +import pkg from 'vs/platform/product/node/package'; const rootPath = path.dirname(getPathFromAmdModule(require, '')); const productJsonPath = path.join(rootPath, 'product.json'); @@ -17,4 +18,6 @@ if (process.env['VSCODE_DEV']) { product.dataFolderName += '-dev'; } +product.version = pkg.version; + export default product; diff --git a/src/vs/platform/product/node/productService.ts b/src/vs/platform/product/node/productService.ts deleted file mode 100644 index f3986577355c88cf11435cbf10400c845c1335c3..0000000000000000000000000000000000000000 --- a/src/vs/platform/product/node/productService.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; -import product from 'vs/platform/product/node/product'; -import pkg from 'vs/platform/product/node/package'; -import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; - -export class ProductService implements IProductService { - - _serviceBrand!: ServiceIdentifier; - - readonly productConfiguration: IProductConfiguration; - - constructor() { - this.productConfiguration = { - ...product, ...{ version: pkg.version } - }; - } - -} diff --git a/src/vs/workbench/api/browser/mainThreadWebview.ts b/src/vs/workbench/api/browser/mainThreadWebview.ts index f2c3141d0639980c61efdc59d2b16da6839a5235..90bdeb5ea748ac8e3c9614c20e944e92b4eb1c61 100644 --- a/src/vs/workbench/api/browser/mainThreadWebview.ts +++ b/src/vs/workbench/api/browser/mainThreadWebview.ts @@ -327,7 +327,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews if (MainThreadWebviews.standardSupportedLinkSchemes.has(link.scheme)) { return true; } - if (this._productService.productConfiguration.urlProtocol === link.scheme) { + if (this._productService.urlProtocol === link.scheme) { return true; } return !!webview.webview.contentOptions.enableCommandUris && link.scheme === 'command'; diff --git a/src/vs/workbench/browser/web.main.ts b/src/vs/workbench/browser/web.main.ts index 812663e25d43c99a3daf0b801ca80a51739b3075..c28e693fc47cb6312b3a5c5be2f05043e5698b93 100644 --- a/src/vs/workbench/browser/web.main.ts +++ b/src/vs/workbench/browser/web.main.ts @@ -14,7 +14,7 @@ import { Workbench } from 'vs/workbench/browser/workbench'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { REMOTE_FILE_SYSTEM_CHANNEL_NAME, RemoteExtensionsFileSystemProvider } from 'vs/platform/remote/common/remoteAgentFileSystemChannel'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { IProductService } from 'vs/platform/product/common/product'; +import { IProductService, IProductConfiguration } from 'vs/platform/product/common/product'; import { RemoteAgentService } from 'vs/workbench/services/remote/browser/remoteAgentServiceImpl'; import { RemoteAuthorityResolverService } from 'vs/platform/remote/browser/remoteAuthorityResolverService'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; @@ -33,7 +33,6 @@ import { ISignService } from 'vs/platform/sign/common/sign'; import { SignService } from 'vs/platform/sign/browser/signService'; import { hash } from 'vs/base/common/hash'; import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api'; -import { ProductService } from 'vs/platform/product/browser/productService'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; import { BACKUPS } from 'vs/platform/environment/common/environment'; import { joinPath } from 'vs/base/common/resources'; @@ -121,7 +120,7 @@ class CodeRendererMain extends Disposable { serviceCollection.set(IWorkbenchEnvironmentService, environmentService); // Product - const productService = new ProductService(); + const productService = this.createProductService(); serviceCollection.set(IProductService, productService); // Remote @@ -187,6 +186,18 @@ class CodeRendererMain extends Disposable { return { serviceCollection, logService, storageService: services[1] }; } + private createProductService(): IProductService { + const element = document.getElementById('vscode-remote-product-configuration'); + const productConfiguration: IProductConfiguration = { + ...element ? JSON.parse(element.getAttribute('data-settings')!) : { + version: '1.38.0-unknown', + nameLong: 'Unknown', + extensionAllowedProposedApi: [], + }, ...{ urlProtocol: '', enableTelemetry: false } + }; + return { _serviceBrand: undefined, ...productConfiguration }; + } + private async createStorageService(payload: IWorkspaceInitializationPayload, environmentService: IWorkbenchEnvironmentService, fileService: IFileService, logService: ILogService): Promise { const storageService = new BrowserStorageService(environmentService, fileService); diff --git a/src/vs/workbench/browser/web.simpleservices.ts b/src/vs/workbench/browser/web.simpleservices.ts index ce9a691a28b672180a523a15c3d9d4f32a130791..ce24f3df7bf3b91fcb6b9b90a7aea7e3608b70ea 100644 --- a/src/vs/workbench/browser/web.simpleservices.ts +++ b/src/vs/workbench/browser/web.simpleservices.ts @@ -743,13 +743,13 @@ export class SimpleWindowsService implements IWindowsService { async openAboutDialog(): Promise { const detail = localize('aboutDetail', "Version: {0}\nCommit: {1}\nDate: {2}\nBrowser: {3}", - this.productService.productConfiguration.version || 'Unknown', - this.productService.productConfiguration.commit || 'Unknown', - this.productService.productConfiguration.date || 'Unknown', + this.productService.version || 'Unknown', + this.productService.commit || 'Unknown', + this.productService.date || 'Unknown', navigator.userAgent ); - const result = await this.dialogService.show(Severity.Info, this.productService.productConfiguration.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); + const result = await this.dialogService.show(Severity.Info, this.productService.nameLong, [localize('copy', "Copy"), localize('ok', "OK")], { detail }); if (result === 0) { this.clipboardService.writeText(detail); diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index 6fdc99451a6b88862825b4976c9a0a9b81266db1..d454894401968dd2b0c782b95f9628cb7e7ddb53 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -175,7 +175,7 @@ export class DebugSession implements IDebugSession { return this.raw!.initialize({ clientID: 'vscode', - clientName: this.productService.productConfiguration.nameLong, + clientName: this.productService.nameLong, adapterID: this.configuration.type, pathFormat: 'path', linesStartAt1: true, diff --git a/src/vs/workbench/contrib/experiments/common/experimentService.ts b/src/vs/workbench/contrib/experiments/common/experimentService.ts index bef55ac4b26b89f2daf20ba6c47ccd56df683071..5707377ce4b1b7c9d97b834ad3f2e559418274a4 100644 --- a/src/vs/workbench/contrib/experiments/common/experimentService.ts +++ b/src/vs/workbench/contrib/experiments/common/experimentService.ts @@ -170,10 +170,10 @@ export class ExperimentService extends Disposable implements IExperimentService } protected getExperiments(): Promise { - if (!this.productService.productConfiguration.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { + if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) { return Promise.resolve([]); } - return this.requestService.request({ type: 'GET', url: this.productService.productConfiguration.experimentsUrl }, CancellationToken.None).then(context => { + return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => { if (context.res.statusCode !== 200) { return Promise.resolve(null); } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts index c080f868407b27788a13bddfbaf807c81a665137..12a05302a752b575c310925ccd78fd9f76b8f8f3 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionTipsService.ts @@ -116,8 +116,8 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx return; } - if (this.productService.productConfiguration.extensionsGallery && this.productService.productConfiguration.extensionsGallery.recommendationsUrl) { - this._extensionsRecommendationsUrl = this.productService.productConfiguration.extensionsGallery.recommendationsUrl; + if (this.productService.extensionsGallery && this.productService.extensionsGallery.recommendationsUrl) { + this._extensionsRecommendationsUrl = this.productService.extensionsGallery.recommendationsUrl; } this.sessionSeed = +new Date(); @@ -243,7 +243,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } getKeymapRecommendations(): IExtensionRecommendation[] { - return (this.productService.productConfiguration.keymapExtensionTips || []) + return (this.productService.keymapExtensionTips || []) .filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId)) .map(extensionId => ({ extensionId, sources: ['application'] })); } @@ -600,10 +600,10 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx return Object.keys(this._fileBasedRecommendations) .sort((a, b) => { if (this._fileBasedRecommendations[a].recommendedTime === this._fileBasedRecommendations[b].recommendedTime) { - if (!this.productService.productConfiguration.extensionImportantTips || caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, a)) { + if (!this.productService.extensionImportantTips || caseInsensitiveGet(this.productService.extensionImportantTips, a)) { return -1; } - if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, b)) { + if (caseInsensitiveGet(this.productService.extensionImportantTips, b)) { return 1; } } @@ -614,11 +614,11 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } /** - * Parse all file based recommendations from this.productService.productConfiguration.extensionTips - * Retire existing recommendations if they are older than a week or are not part of this.productService.productConfiguration.extensionTips anymore + * Parse all file based recommendations from this.productService.extensionTips + * Retire existing recommendations if they are older than a week or are not part of this.productService.extensionTips anymore */ private fetchFileBasedRecommendations() { - const extensionTips = this.productService.productConfiguration.extensionTips; + const extensionTips = this.productService.extensionTips; if (!extensionTips) { return; } @@ -635,7 +635,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } }); - forEach(this.productService.productConfiguration.extensionImportantTips, entry => { + forEach(this.productService.extensionImportantTips, entry => { let { key: id, value } = entry; const { pattern } = value; let ids = this._availableRecommendations[pattern]; @@ -697,7 +697,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx let { key: pattern, value: ids } = entry; if (match(pattern, model.uri.toString())) { for (let id of ids) { - if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id)) { + if (caseInsensitiveGet(this.productService.extensionImportantTips, id)) { recommendationsToSuggest.push(id); } const filedBasedRecommendation = this._fileBasedRecommendations[id.toLowerCase()] || { recommendedTime: now, sources: [] }; @@ -751,7 +751,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } const id = recommendationsToSuggest[0]; - const entry = caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id); + const entry = caseInsensitiveGet(this.productService.extensionImportantTips, id); if (!entry) { return false; } @@ -981,7 +981,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx } /** - * If user has any of the tools listed in this.productService.productConfiguration.exeBasedExtensionTips, fetch corresponding recommendations + * If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations */ private async fetchExecutableRecommendations(important: boolean): Promise { if (Platform.Web) { @@ -1007,7 +1007,7 @@ export abstract class BaseExtensionTipsService extends Disposable implements IEx const promises: Promise[] = []; // Loop through recommended extensions - forEach(this.productService.productConfiguration.exeBasedExtensionTips, entry => { + forEach(this.productService.exeBasedExtensionTips, entry => { if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) { return; } diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts index 05bef903d9e003f0829a307ba4ff22ec6275c04d..ec19e774ab1f699d30ac4658dd381ad6d5c8883a 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts @@ -76,10 +76,10 @@ export function toExtensionDescription(local: ILocalExtension): IExtensionDescri const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => { - if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.productConfiguration.extensionsGallery) { + if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.extensionsGallery) { return Promise.reject(error); } else { - const downloadUrl = `${productService.productConfiguration.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; + const downloadUrl = `${productService.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`; notificationService.prompt(Severity.Error, message, [{ label: localize('download', "Download Manually"), run: () => openerService.open(URI.parse(downloadUrl)).then(() => { diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 99ec538b4426ea7d14caacba26feecb088445cca..b64689e02c6c9ba8407bdd1fdf6db35de8bbcae0 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -114,11 +114,11 @@ class Extension implements IExtension { } get url(): string | undefined { - if (!this.productService.productConfiguration.extensionsGallery || !this.gallery) { + if (!this.productService.extensionsGallery || !this.gallery) { return undefined; } - return `${this.productService.productConfiguration.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; + return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`; } get iconUrl(): string { @@ -615,7 +615,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension text = text.replace(extensionRegex, (m, ext) => { // Get curated keywords - const lookup = this.productService.productConfiguration.extensionKeywords || {}; + const lookup = this.productService.extensionKeywords || {}; const keywords = lookup[ext] || []; // Get mode name @@ -1022,7 +1022,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension get allowedBadgeProviders(): string[] { if (!this._extensionAllowedBadgeProviders) { - this._extensionAllowedBadgeProviders = (this.productService.productConfiguration.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); + this._extensionAllowedBadgeProviders = (this.productService.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase()); } return this._extensionAllowedBadgeProviders; } diff --git a/src/vs/workbench/contrib/feedback/browser/feedback.ts b/src/vs/workbench/contrib/feedback/browser/feedback.ts index 130c7fd3a0441d312c5f8ab76a9fbb277251b515..618dc7edaa9d5db9d64da05e9907dcdf8eba5594 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedback.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedback.ts @@ -73,8 +73,8 @@ export class FeedbackDropdown extends Dropdown { this.feedbackDelegate = options.feedbackService; this.maxFeedbackCharacters = this.feedbackDelegate.getCharacterLimit(this.sentiment); - if (productService.productConfiguration.sendASmile) { - this.requestFeatureLink = productService.productConfiguration.sendASmile.requestFeatureUrl; + if (productService.sendASmile) { + this.requestFeatureLink = productService.sendASmile.requestFeatureUrl; } this.integrityService.isPure().then(result => { diff --git a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts index 458dc93b0b6883d926d68f2c1a2da91d07e55289..c609aa4132fa3a8f761cc98c0e87a7e32710396f 100644 --- a/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts +++ b/src/vs/workbench/contrib/feedback/browser/feedbackStatusbarItem.ts @@ -58,7 +58,7 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben ) { super(); - if (productService.productConfiguration.sendASmile) { + if (productService.sendASmile) { this.entry = this._register(statusbarService.addEntry(this.getStatusEntry(), 'status.feedback', localize('status.feedback', "Tweet Feedback"), StatusbarAlignment.RIGHT, -100 /* towards the end of the right hand side */)); CommandsRegistry.registerCommand('_feedback.open', () => this.toggleFeedback()); diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts index b876c396a7f4267c027f9c3ca356208cf474a8bc..37de5e7766e9f496d2d15f313287323f07f01963 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesSearch.ts @@ -74,7 +74,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences }; } else { return { - urlBase: this.productService.productConfiguration.settingsSearchUrl + urlBase: this.productService.settingsSearchUrl }; } } @@ -365,7 +365,7 @@ class RemoteSearchProvider implements ISearchProvider { const extensions = await this.installedExtensions; const filters = this.options.newExtensionsOnly ? [`diminish eq 'latest'`] : - this.getVersionFilters(extensions, this.productService.productConfiguration.settingsSearchBuildId); + this.getVersionFilters(extensions, this.productService.settingsSearchBuildId); const filterStr = filters .slice(filterPage * RemoteSearchProvider.MAX_REQUEST_FILTERS, (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS) diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index b1ecf1026f3c47f32094e10be0b00e864ff57f0c..b3ff7db5e88e2b8e1b77d7b67f98a80b8a33026f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -226,7 +226,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); this._configHelper.showRecommendations(shellLaunchConfig); const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv(); - const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.productConfiguration.version, this._configHelper.config.setLocaleVariables, baseEnv); + const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty); diff --git a/src/vs/workbench/electron-browser/desktop.main.ts b/src/vs/workbench/electron-browser/desktop.main.ts index 40ea992a2a152387eeafa6e87628920a1230558f..a6836c38075f7e4becbf4df9484bfd0abe4627a7 100644 --- a/src/vs/workbench/electron-browser/desktop.main.ts +++ b/src/vs/workbench/electron-browser/desktop.main.ts @@ -51,6 +51,8 @@ import { SignService } from 'vs/platform/sign/node/signService'; import { ISignService } from 'vs/platform/sign/common/sign'; import { FileUserDataProvider } from 'vs/workbench/services/userData/common/fileUserDataProvider'; import { basename } from 'vs/base/common/resources'; +import { IProductService } from 'vs/platform/product/common/product'; +import product from 'vs/platform/product/node/product'; class CodeRendererMain extends Disposable { @@ -177,6 +179,9 @@ class CodeRendererMain extends Disposable { // Environment serviceCollection.set(IWorkbenchEnvironmentService, this.environmentService); + // Product + serviceCollection.set(IProductService, { _serviceBrand: undefined, ...product }); + // Log const logService = this._register(this.createLogService(mainProcessService, this.environmentService)); serviceCollection.set(ILogService, logService); diff --git a/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts b/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts index 5852ce2d53ce729899c8b1f41ecb063d9323f3b2..4536a5ad507abd1bde21459595adab8a85f9d617 100644 --- a/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts +++ b/src/vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test.ts @@ -16,12 +16,12 @@ import { IExtensionContributions, ExtensionType, IExtension } from 'vs/platform/ import { isUndefinedOrNull } from 'vs/base/common/types'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { ProductService } from 'vs/platform/product/node/productService'; import { URI } from 'vs/base/common/uri'; import { Schemas } from 'vs/base/common/network'; import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts'; import { assign } from 'vs/base/common/objects'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { productService } from 'vs/workbench/test/workbenchTestServices'; function storageService(instantiationService: TestInstantiationService): IStorageService { let service = instantiationService.get(IStorageService); @@ -46,7 +46,7 @@ export class TestExtensionEnablementService extends ExtensionEnablementService { instantiationService.get(IExtensionManagementService) || instantiationService.stub(IExtensionManagementService, { onDidInstallExtension: new Emitter().event, onDidUninstallExtension: new Emitter().event } as IExtensionManagementService), instantiationService.get(IConfigurationService), instantiationService.get(IExtensionManagementServerService), - new ProductService() + productService ); } diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts index 7848fdee12777d8a351de040be026ddd3c1c9ebc..5794b2590616708495f2502974f1bc1268956d87 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHostStarter.ts @@ -117,15 +117,15 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter { const [telemetryInfo, extensionDescriptions] = await Promise.all([this._telemetryService.getTelemetryInfo(), this._extensions]); const workspace = this._contextService.getWorkspace(); return { - commit: this._productService.productConfiguration.commit, - version: this._productService.productConfiguration.version, + commit: this._productService.commit, + version: this._productService.version, parentPid: -1, environment: { isExtensionDevelopmentDebug: false, appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined, appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined, - appName: this._productService.productConfiguration.nameLong, - appUriScheme: this._productService.productConfiguration.urlProtocol, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts index 51f991375a6a3ad4d4bae1198bd6351a4ab5c876..6445a03a6e631fb08916a5838893b46d213f16da 100644 --- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts @@ -462,12 +462,12 @@ class ProposedApiController { } this.enableProposedApiForAll = !environmentService.isBuilt || - (!!environmentService.extensionDevelopmentLocationURI && productService.productConfiguration.nameLong !== 'Visual Studio Code') || + (!!environmentService.extensionDevelopmentLocationURI && productService.nameLong !== 'Visual Studio Code') || (this.enableProposedApiFor.length === 0 && 'enable-proposed-api' in environmentService.args); this.productAllowProposedApi = new Set(); - if (isNonEmptyArray(productService.productConfiguration.extensionAllowedProposedApi)) { - productService.productConfiguration.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); + if (isNonEmptyArray(productService.extensionAllowedProposedApi)) { + productService.extensionAllowedProposedApi.forEach((id) => this.productAllowProposedApi.add(ExtensionIdentifier.toKey(id))); } } diff --git a/src/vs/workbench/services/extensions/common/extensionsUtil.ts b/src/vs/workbench/services/extensions/common/extensionsUtil.ts index 2f7d4e01039aca0022e8b6601a5b83de3991789e..a1496708db6d1a47cd3893c4279a4f2a6fbdd580 100644 --- a/src/vs/workbench/services/extensions/common/extensionsUtil.ts +++ b/src/vs/workbench/services/extensions/common/extensionsUtil.ts @@ -24,7 +24,7 @@ export function isUIExtension(manifest: IExtensionManifest, productService: IPro case 'workspace': return false; default: { // Tagged as UI extension in product - if (isNonEmptyArray(productService.productConfiguration.uiExtensions) && productService.productConfiguration.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { + if (isNonEmptyArray(productService.uiExtensions) && productService.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) { return true; } // Not an UI extension if it has main diff --git a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts index ca657398990c7c74dae1df8b541e2a572e2e4bca..47aaf4a22bb3bcc6ce28ec08d8b00c9954def54d 100644 --- a/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts +++ b/src/vs/workbench/services/extensions/common/remoteExtensionHostClient.ts @@ -71,7 +71,7 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH public start(): Promise { const options: IConnectionOptions = { - commit: this._productService.productConfiguration.commit, + commit: this._productService.commit, socketFactory: this._socketFactory, addressProvider: { getAddress: async () => { @@ -181,15 +181,15 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH const hostExtensions = allExtensions.filter(extension => extension.main && extension.api === 'none').map(extension => extension.identifier); const workspace = this._contextService.getWorkspace(); const r: IInitData = { - commit: this._productService.productConfiguration.commit, - version: this._productService.productConfiguration.version, + commit: this._productService.commit, + version: this._productService.version, parentPid: remoteExtensionHostData.pid, environment: { isExtensionDevelopmentDebug, appRoot: remoteExtensionHostData.appRoot, appSettingsHome: remoteExtensionHostData.appSettingsHome, - appName: this._productService.productConfiguration.nameLong, - appUriScheme: this._productService.productConfiguration.urlProtocol, + appName: this._productService.nameLong, + appUriScheme: this._productService.urlProtocol, appLanguage: platform.language, extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI, extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI, diff --git a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts index 75787071f85169f6a248a977dc8a709728aba663..f94d89adb16b2e1983a72cd11a55b2733e92a585 100644 --- a/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts +++ b/src/vs/workbench/services/extensions/electron-browser/remoteExtensionManagementIpc.ts @@ -69,7 +69,7 @@ export class RemoteExtensionManagementChannelClient extends ExtensionManagementC const installed = await this.getInstalled(ExtensionType.User); const compatible = await this.galleryService.getCompatibleExtension(extension); if (!compatible) { - return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.productConfiguration.version))); + return Promise.reject(new Error(localize('incompatible', "Unable to install extension '{0}' as it is not compatible with VS Code '{1}'.", extension.identifier.id, this.productService.version))); } const manifest = await this.galleryService.getManifest(compatible, CancellationToken.None); if (manifest) { diff --git a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts index db4d2038ca3e047aedc253c527c81f07ec5e70d9..fd979ca094c62f1a23dad2423bb91123cdc785af 100644 --- a/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts +++ b/src/vs/workbench/services/remote/browser/remoteAgentServiceImpl.ts @@ -28,7 +28,7 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR super(environmentService); this.socketFactory = new BrowserSocketFactory(webSocketFactory); - this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.productConfiguration.commit, this.socketFactory, remoteAuthorityResolverService, signService)); + this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, remoteAuthorityResolverService, signService)); } getConnection(): IRemoteAgentConnection | null { diff --git a/src/vs/workbench/services/telemetry/browser/telemetryService.ts b/src/vs/workbench/services/telemetry/browser/telemetryService.ts index 2632d935d80e41f776e25a0df15aa8ddccf2790f..eac9dcfb1d0a793b4478278b5194fb069385a89d 100644 --- a/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/browser/telemetryService.ts @@ -79,11 +79,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - const aiKey = productService.productConfiguration.aiConfig && productService.productConfiguration.aiConfig.asimovKey; - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry && !!aiKey) { + const aiKey = productService.aiConfig && productService.aiConfig.asimovKey; + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry && !!aiKey) { const config: ITelemetryServiceConfig = { appender: combinedAppender(new WebTelemetryAppender(aiKey, logService), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.configuration.remoteAuthority), piiPaths: [environmentService.appRoot] }; diff --git a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts index 002b6ae4ce3696f953822f7617e56e7ac05454e7..c5561e4429580fa04fcf83781aec1c85aed82cd3 100644 --- a/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts +++ b/src/vs/workbench/services/telemetry/electron-browser/telemetryService.ts @@ -34,11 +34,11 @@ export class TelemetryService extends Disposable implements ITelemetryService { ) { super(); - if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.productConfiguration.enableTelemetry) { + if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) { const channel = sharedProcessService.getChannel('telemetryAppender'); const config: ITelemetryServiceConfig = { appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService)), - commonProperties: resolveWorkbenchCommonProperties(storageService, productService.productConfiguration.commit, productService.productConfiguration.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), + commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.configuration.machineId, environmentService.installSourcePath, environmentService.configuration.remoteAuthority), piiPaths: environmentService.extensionsPath ? [environmentService.appRoot, environmentService.extensionsPath] : [environmentService.appRoot] }; diff --git a/src/vs/workbench/test/workbenchTestServices.ts b/src/vs/workbench/test/workbenchTestServices.ts index 0ca22ba62b88d15769243fd96397b85f30264f18..576df9cb63c536d218b65d23442337d2c6026ed9 100644 --- a/src/vs/workbench/test/workbenchTestServices.ts +++ b/src/vs/workbench/test/workbenchTestServices.ts @@ -84,6 +84,8 @@ import { WorkbenchEnvironmentService } from 'vs/workbench/services/environment/n import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer'; import { NodeTextFileService } from 'vs/workbench/services/textfile/node/textFileService'; import { Schemas } from 'vs/base/common/network'; +import { IProductService } from 'vs/platform/product/common/product'; +import product from 'vs/platform/product/node/product'; export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput { return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined); @@ -1631,3 +1633,5 @@ export class RemoteFileSystemProvider implements IFileSystemProvider { private toFileResource(resource: URI): URI { return resource.with({ scheme: Schemas.file, authority: '' }); } } + +export const productService: IProductService = { _serviceBrand: undefined, ...product }; diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 3373be0bd3508550998d2e8372b83f6ab79ec9f9..90f3e4c63d142516cf461e4fb6aee00ae84751a7 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -61,8 +61,6 @@ import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; import { LocalizationsService } from 'vs/platform/localizations/electron-browser/localizationsService'; import { ISharedProcessService, SharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; -import { IProductService } from 'vs/platform/product/common/product'; -import { ProductService } from 'vs/platform/product/node/productService'; import { IWindowsService } from 'vs/platform/windows/common/windows'; import { WindowsService } from 'vs/platform/windows/electron-browser/windowsService'; import { IUpdateService } from 'vs/platform/update/common/update'; @@ -81,7 +79,6 @@ registerSingleton(IRequestService, RequestService, true); registerSingleton(ILifecycleService, LifecycleService); registerSingleton(ILocalizationsService, LocalizationsService); registerSingleton(ISharedProcessService, SharedProcessService, true); -registerSingleton(IProductService, ProductService, true); registerSingleton(IWindowsService, WindowsService); registerSingleton(IUpdateService, UpdateService); registerSingleton(IIssueService, IssueService);