From 28fdd6b2aa8cab43ce669211e92091bb81eb361e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 22 May 2020 16:04:09 -0700 Subject: [PATCH 01/11] Allow LS to be bundled, versioned --- package.json | 2 +- .../languageServerFolderService.ts | 2 +- src/client/activation/node/downloader.ts | 37 +++++++ .../node/languageServerFolderService.ts | 57 ++++++++++- .../activation/node/languageServerProxy.ts | 4 +- src/client/activation/serviceRegistry.ts | 4 +- .../languageServerPackageService.test.ts | 3 +- .../languageServerPackageService.unit.test.ts | 3 +- .../langaugeServerFolderSerivce.unit.test.ts | 99 +++++++++++++++++++ ...azureBobStoreRepository.functional.test.ts | 3 +- 10 files changed, 203 insertions(+), 11 deletions(-) create mode 100644 src/client/activation/node/downloader.ts create mode 100644 src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts diff --git a/package.json b/package.json index 8285e8f5ae92..ef0f1e521f4f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "featureFlags": { "usingNewInterpreterStorage": true }, - "languageServerVersion": "0.5.30", + "languageServerVersionV1": "0.5.30", "publisher": "ms-python", "enableProposedApi": false, "author": { diff --git a/src/client/activation/languageServer/languageServerFolderService.ts b/src/client/activation/languageServer/languageServerFolderService.ts index 03ce4e88d1b5..f3e34b589149 100644 --- a/src/client/activation/languageServer/languageServerFolderService.ts +++ b/src/client/activation/languageServer/languageServerFolderService.ts @@ -10,7 +10,7 @@ import { LanguageServerFolderService } from '../common/languageServerFolderServi import { DotNetLanguageServerFolder } from '../types'; // Must match languageServerVersion* keys in package.json -const DotNetLanguageServerMinVersionKey = 'languageServerVersion'; +export const DotNetLanguageServerMinVersionKey = 'languageServerVersionV1'; @injectable() export class DotNetLanguageServerFolderService extends LanguageServerFolderService { diff --git a/src/client/activation/node/downloader.ts b/src/client/activation/node/downloader.ts new file mode 100644 index 000000000000..45f380bd4bad --- /dev/null +++ b/src/client/activation/node/downloader.ts @@ -0,0 +1,37 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { inject, injectable } from 'inversify'; +import { IApplicationShell, IWorkspaceService } from '../../common/application/types'; +import { IFileSystem } from '../../common/platform/types'; +import { IFileDownloader, Resource } from '../../common/types'; +import { IServiceContainer } from '../../ioc/types'; +import { LanguageServerDownloader } from '../common/downloader'; +import { ILanguageServerFolderService, ILanguageServerOutputChannel } from '../types'; + +@injectable() +export class NodeLanguageServerDownloader extends LanguageServerDownloader { + private readonly bundled: boolean; + + constructor( + @inject(ILanguageServerOutputChannel) lsOutputChannel: ILanguageServerOutputChannel, + @inject(IFileDownloader) fileDownloader: IFileDownloader, + @inject(ILanguageServerFolderService) lsFolderService: ILanguageServerFolderService, + @inject(IApplicationShell) appShell: IApplicationShell, + @inject(IFileSystem) fs: IFileSystem, + @inject(IWorkspaceService) workspace: IWorkspaceService, + @inject(IServiceContainer) services: IServiceContainer + ) { + super(lsOutputChannel, fileDownloader, lsFolderService, appShell, fs, workspace, services); + const config = workspace.getConfiguration('python'); + this.bundled = !config.get('packageName'); + } + + public async downloadLanguageServer(destinationFolder: string, resource: Resource): Promise { + if (!this.bundled) { + return super.downloadLanguageServer(destinationFolder, resource); + } + } +} diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index 8da206ac55c9..424aace7fe7c 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -4,12 +4,18 @@ 'use strict'; import { inject, injectable } from 'inversify'; +import * as semver from 'semver'; +import { IApplicationEnvironment, IWorkspaceService } from '../../common/application/types'; +import { NugetPackage } from '../../common/nuget/types'; +import { Resource } from '../../common/types'; import { IServiceContainer } from '../../ioc/types'; import { LanguageServerFolderService } from '../common/languageServerFolderService'; -import { NodeLanguageServerFolder } from '../types'; +import { FolderVersionPair, ILanguageServerFolderService, NodeLanguageServerFolder } from '../types'; -@injectable() -export class NodeLanguageServerFolderService extends LanguageServerFolderService { +// Must match languageServerVersion* keys in package.json +export const NodeLanguageServerVersionKey = 'languageServerVersionV2'; + +class FallbackNodeLanguageServerFolderService extends LanguageServerFolderService { constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { super(serviceContainer, NodeLanguageServerFolder); } @@ -18,3 +24,48 @@ export class NodeLanguageServerFolderService extends LanguageServerFolderService return '0.0.0'; } } + +@injectable() +export class NodeLanguageServerFolderService implements ILanguageServerFolderService { + private readonly _bundledVersion: semver.SemVer | undefined; + private readonly fallback: FallbackNodeLanguageServerFolderService; + + constructor( + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IWorkspaceService) workspaceService: IWorkspaceService, + @inject(IApplicationEnvironment) appEnv: IApplicationEnvironment + ) { + this.fallback = new FallbackNodeLanguageServerFolderService(serviceContainer); + + const config = workspaceService.getConfiguration('python'); + if (!config.get('packageName')) { + const ver = appEnv.packageJson[NodeLanguageServerVersionKey] as string; + this._bundledVersion = semver.parse(ver) || undefined; + } + } + + public get bundledVersion(): semver.SemVer | undefined { + return this._bundledVersion; + } + + public async getLanguageServerFolderName(resource: Resource): Promise { + if (this._bundledVersion) { + return NodeLanguageServerFolder; + } + return this.fallback.getLanguageServerFolderName(resource); + } + + public async getLatestLanguageServerVersion(resource: Resource): Promise { + if (this._bundledVersion) { + return undefined; + } + return this.fallback.getLatestLanguageServerVersion(resource); + } + + public async getCurrentLanguageServerDirectory(): Promise { + if (this._bundledVersion) { + return { path: NodeLanguageServerFolder, version: this._bundledVersion }; + } + return this.fallback.getCurrentLanguageServerDirectory(); + } +} diff --git a/src/client/activation/node/languageServerProxy.ts b/src/client/activation/node/languageServerProxy.ts index ef1ecbb08310..b5db195c625d 100644 --- a/src/client/activation/node/languageServerProxy.ts +++ b/src/client/activation/node/languageServerProxy.ts @@ -79,8 +79,8 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy { options: LanguageClientOptions ): Promise { if (!this.languageClient) { - const lsVersion = await this.folderService.getLatestLanguageServerVersion(resource); - this.lsVersion = lsVersion?.version.format(); + const directory = await this.folderService.getCurrentLanguageServerDirectory(); + this.lsVersion = directory?.version.format(); this.cancellationStrategy = new FileBasedCancellationStrategy(); options.connectionOptions = { cancellationStrategy: this.cancellationStrategy }; diff --git a/src/client/activation/serviceRegistry.ts b/src/client/activation/serviceRegistry.ts index c7afe4e9afb1..d0143254ff9d 100644 --- a/src/client/activation/serviceRegistry.ts +++ b/src/client/activation/serviceRegistry.ts @@ -41,6 +41,7 @@ import { LanguageServerOutputChannel } from './languageServer/outputChannel'; import { PlatformData } from './languageServer/platformData'; import { NodeLanguageServerActivator } from './node/activator'; import { NodeLanguageServerAnalysisOptions } from './node/analysisOptions'; +import { NodeLanguageServerDownloader } from './node/downloader'; import { NodeLanguageClientFactory } from './node/languageClientFactory'; import { NodeLanguageServerFolderService } from './node/languageServerFolderService'; import { @@ -149,6 +150,7 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp ILanguageServerPackageService, DotNetLanguageServerPackageService ); + serviceManager.addSingleton(ILanguageServerDownloader, LanguageServerDownloader); registerDotNetTypes(serviceManager); } else if (languageServerType === LanguageServerType.Node) { serviceManager.add( @@ -187,6 +189,7 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp ILanguageServerPackageService, NodeLanguageServerPackageService ); + serviceManager.addSingleton(ILanguageServerDownloader, NodeLanguageServerDownloader); } else if (languageServerType === LanguageServerType.None) { serviceManager.add( ILanguageServerActivator, @@ -210,7 +213,6 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp DownloadBetaChannelRule, LanguageServerDownloadChannel.stable ); - serviceManager.addSingleton(ILanguageServerDownloader, LanguageServerDownloader); serviceManager.addSingleton( ILanguageServerOutputChannel, diff --git a/src/test/activation/languageServer/languageServerPackageService.test.ts b/src/test/activation/languageServer/languageServerPackageService.test.ts index 9defd3ef9b03..e401d524e428 100644 --- a/src/test/activation/languageServer/languageServerPackageService.test.ts +++ b/src/test/activation/languageServer/languageServerPackageService.test.ts @@ -8,6 +8,7 @@ import { expect } from 'chai'; import * as typeMoq from 'typemoq'; import { WorkspaceConfiguration } from 'vscode'; +import { DotNetLanguageServerMinVersionKey } from '../../../client/activation/languageServer/languageServerFolderService'; import { DotNetLanguageServerPackageService } from '../../../client/activation/languageServer/languageServerPackageService'; import { IApplicationEnvironment, IWorkspaceService } from '../../../client/common/application/types'; import { AzureBlobStoreNugetRepository } from '../../../client/common/nuget/azureBlobStoreNugetRepository'; @@ -44,7 +45,7 @@ suite('Language Server Package Service', () => { ); serviceContainer.setup((c) => c.get(typeMoq.It.isValue(INugetRepository))).returns(() => nugetRepo); const appEnv = typeMoq.Mock.ofType(); - const packageJson = { languageServerVersion: '0.0.1' }; + const packageJson = { [DotNetLanguageServerMinVersionKey]: '0.0.1' }; appEnv.setup((e) => e.packageJson).returns(() => packageJson); const platform = typeMoq.Mock.ofType(); const lsPackageService = new DotNetLanguageServerPackageService( diff --git a/src/test/activation/languageServer/languageServerPackageService.unit.test.ts b/src/test/activation/languageServer/languageServerPackageService.unit.test.ts index ab3055be776c..358b48f63c41 100644 --- a/src/test/activation/languageServer/languageServerPackageService.unit.test.ts +++ b/src/test/activation/languageServer/languageServerPackageService.unit.test.ts @@ -12,6 +12,7 @@ import { azureCDNBlobStorageAccount, LanguageServerDownloadChannel } from '../../../client/activation/common/packageRepository'; +import { DotNetLanguageServerMinVersionKey } from '../../../client/activation/languageServer/languageServerFolderService'; import { DotNetLanguageServerPackageService } from '../../../client/activation/languageServer/languageServerPackageService'; import { PlatformName } from '../../../client/activation/types'; import { IApplicationEnvironment } from '../../../client/common/application/types'; @@ -41,7 +42,7 @@ suite('Language Server - Package Service', () => { lsPackageService.getLanguageServerDownloadChannel = () => 'stable'; }); function setMinVersionOfLs(version: string) { - const packageJson = { languageServerVersion: version }; + const packageJson = { [DotNetLanguageServerMinVersionKey]: version }; appVersion.setup((e) => e.packageJson).returns(() => packageJson); } [true, false].forEach((is64Bit) => { diff --git a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts new file mode 100644 index 000000000000..b81560244cbe --- /dev/null +++ b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts @@ -0,0 +1,99 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { assert, expect } from 'chai'; +import * as TypeMoq from 'typemoq'; +import { Uri, WorkspaceConfiguration } from 'vscode'; +import { + NodeLanguageServerFolderService, + NodeLanguageServerVersionKey +} from '../../../client/activation/node/languageServerFolderService'; +import { NodeLanguageServerFolder } from '../../../client/activation/types'; +import { IApplicationEnvironment, IWorkspaceService } from '../../../client/common/application/types'; +import { IConfigurationService, IPythonSettings } from '../../../client/common/types'; +import { IServiceContainer } from '../../../client/ioc/types'; + +// tslint:disable:max-func-body-length + +suite('Node Language Server Folder Service', () => { + const resource = Uri.parse('a'); + const version = '0.0.1-test'; + + let serviceContainer: TypeMoq.IMock; + let workspaceConfiguration: TypeMoq.IMock; + let workspaceService: TypeMoq.IMock; + let appEnvironment: TypeMoq.IMock; + + setup(() => { + serviceContainer = TypeMoq.Mock.ofType(); + workspaceConfiguration = TypeMoq.Mock.ofType(); + workspaceService = TypeMoq.Mock.ofType(); + workspaceService + .setup((ws) => ws.getConfiguration('python', TypeMoq.It.isAny())) + .returns(() => workspaceConfiguration.object); + appEnvironment = TypeMoq.Mock.ofType(); + }); + + test('With packageName set', () => { + appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: version })); + workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => 'somePackageName'); + + const folderService = new NodeLanguageServerFolderService( + serviceContainer.object, + workspaceService.object, + appEnvironment.object + ); + + expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + }); + + test('Invalid version', () => { + appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: 'fakeversion' })); + workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => undefined); + + const folderService = new NodeLanguageServerFolderService( + serviceContainer.object, + workspaceService.object, + appEnvironment.object + ); + + expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + }); + + suite('Valid configuration', () => { + let folderService: NodeLanguageServerFolderService; + + setup(() => { + appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: version })); + workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => undefined); + folderService = new NodeLanguageServerFolderService( + serviceContainer.object, + workspaceService.object, + appEnvironment.object + ); + }); + + test('Parsed version is correct', () => { + expect(folderService.bundledVersion!.format()).to.be.equal(version); + }); + + test('getLanguageServerFolderName', async () => { + const folderName = await folderService.getLanguageServerFolderName(resource); + expect(folderName).to.be.equal(NodeLanguageServerFolder); + }); + + test('getLatestLanguageServerVersion', async () => { + const pkg = await folderService.getLatestLanguageServerVersion(resource); + expect(pkg).to.equal(undefined, 'expected latest version to be undefined'); + }); + + test('Method getCurrentLanguageServerDirectory()', async () => { + const dir = await folderService.getCurrentLanguageServerDirectory(); + assert(dir); + expect(dir!.path).to.equal(NodeLanguageServerFolder); + expect(dir!.version.format()).to.be.equal(version); + }); + }); +}); diff --git a/src/test/common/nuget/azureBobStoreRepository.functional.test.ts b/src/test/common/nuget/azureBobStoreRepository.functional.test.ts index 48a58c988e43..2afb1b94b680 100644 --- a/src/test/common/nuget/azureBobStoreRepository.functional.test.ts +++ b/src/test/common/nuget/azureBobStoreRepository.functional.test.ts @@ -7,6 +7,7 @@ import { expect } from 'chai'; import { SemVer } from 'semver'; import * as typeMoq from 'typemoq'; import { WorkspaceConfiguration } from 'vscode'; +import { DotNetLanguageServerMinVersionKey } from '../../../client/activation/languageServer/languageServerFolderService'; import { DotNetLanguageServerPackageService } from '../../../client/activation/languageServer/languageServerPackageService'; import { IApplicationEnvironment, IWorkspaceService } from '../../../client/common/application/types'; import { AzureBlobStoreNugetRepository } from '../../../client/common/nuget/azureBlobStoreNugetRepository'; @@ -53,7 +54,7 @@ suite('Nuget Azure Storage Repository', () => { // tslint:disable-next-line:no-invalid-this this.timeout(15000); const platformService = new PlatformService(); - const packageJson = { languageServerVersion: '0.0.1' }; + const packageJson = { [DotNetLanguageServerMinVersionKey]: '0.0.1' }; const appEnv = typeMoq.Mock.ofType(); appEnv.setup((e) => e.packageJson).returns(() => packageJson); const lsPackageService = new DotNetLanguageServerPackageService( From be1aed7c1a92e4297bb57aa2226626ff8970cc24 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 27 May 2020 19:14:06 -0700 Subject: [PATCH 02/11] Remove unused imports --- .../activation/node/langaugeServerFolderSerivce.unit.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts index b81560244cbe..e1b150ef1bc1 100644 --- a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts +++ b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts @@ -12,7 +12,6 @@ import { } from '../../../client/activation/node/languageServerFolderService'; import { NodeLanguageServerFolder } from '../../../client/activation/types'; import { IApplicationEnvironment, IWorkspaceService } from '../../../client/common/application/types'; -import { IConfigurationService, IPythonSettings } from '../../../client/common/types'; import { IServiceContainer } from '../../../client/ioc/types'; // tslint:disable:max-func-body-length From a4589abef29a07e0a2d1e4adaef7ddd43a583080 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 28 May 2020 10:22:43 -0700 Subject: [PATCH 03/11] Remove unused inject decorator --- src/client/activation/node/languageServerFolderService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index 424aace7fe7c..6b3621fcef12 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -16,7 +16,7 @@ import { FolderVersionPair, ILanguageServerFolderService, NodeLanguageServerFold export const NodeLanguageServerVersionKey = 'languageServerVersionV2'; class FallbackNodeLanguageServerFolderService extends LanguageServerFolderService { - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + constructor(serviceContainer: IServiceContainer) { super(serviceContainer, NodeLanguageServerFolder); } From 4b162d5b59eeb1e77ceb90d1b35f48123f80d795 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 28 May 2020 11:58:55 -0700 Subject: [PATCH 04/11] Add isBundled to folder service interface, remove unused downloader --- src/client/activation/common/downloader.ts | 7 ++++ .../common/languageServerFolderService.ts | 4 ++ src/client/activation/node/downloader.ts | 37 ------------------- .../node/languageServerFolderService.ts | 4 ++ src/client/activation/serviceRegistry.ts | 4 +- src/client/activation/types.ts | 1 + .../languageServer/downloader.unit.test.ts | 1 + 7 files changed, 18 insertions(+), 40 deletions(-) delete mode 100644 src/client/activation/node/downloader.ts diff --git a/src/client/activation/common/downloader.ts b/src/client/activation/common/downloader.ts index 6f304bea24f7..877a95c71bfb 100644 --- a/src/client/activation/common/downloader.ts +++ b/src/client/activation/common/downloader.ts @@ -14,6 +14,7 @@ import { createDeferred } from '../../common/utils/async'; import { Common, LanguageService } from '../../common/utils/localize'; import { StopWatch } from '../../common/utils/stopWatch'; import { IServiceContainer } from '../../ioc/types'; +import { traceError } from '../../logging'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; import { @@ -58,6 +59,12 @@ export class LanguageServerDownloader implements ILanguageServerDownloader { } public async downloadLanguageServer(destinationFolder: string, resource: Resource): Promise { + if (this.lsFolderService.isBundled()) { + // Sanity check; a bundled LS should never be downloaded. + traceError('Attempted to download bundled langauge server'); + return; + } + const [downloadUri, lsVersion, lsName] = await this.getDownloadInfo(resource); const timer: StopWatch = new StopWatch(); let success: boolean = true; diff --git a/src/client/activation/common/languageServerFolderService.ts b/src/client/activation/common/languageServerFolderService.ts index 3aa99f8e20e4..b71faa9945cb 100644 --- a/src/client/activation/common/languageServerFolderService.ts +++ b/src/client/activation/common/languageServerFolderService.ts @@ -26,6 +26,10 @@ export abstract class LanguageServerFolderService implements ILanguageServerFold @unmanaged() protected readonly languageServerFolder: string ) {} + public isBundled(): boolean { + return false; + } + @traceDecorators.verbose('Get language server folder name') public async getLanguageServerFolderName(resource: Resource): Promise { const currentFolder = await this.getCurrentLanguageServerDirectory(); diff --git a/src/client/activation/node/downloader.ts b/src/client/activation/node/downloader.ts deleted file mode 100644 index 45f380bd4bad..000000000000 --- a/src/client/activation/node/downloader.ts +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -'use strict'; - -import { inject, injectable } from 'inversify'; -import { IApplicationShell, IWorkspaceService } from '../../common/application/types'; -import { IFileSystem } from '../../common/platform/types'; -import { IFileDownloader, Resource } from '../../common/types'; -import { IServiceContainer } from '../../ioc/types'; -import { LanguageServerDownloader } from '../common/downloader'; -import { ILanguageServerFolderService, ILanguageServerOutputChannel } from '../types'; - -@injectable() -export class NodeLanguageServerDownloader extends LanguageServerDownloader { - private readonly bundled: boolean; - - constructor( - @inject(ILanguageServerOutputChannel) lsOutputChannel: ILanguageServerOutputChannel, - @inject(IFileDownloader) fileDownloader: IFileDownloader, - @inject(ILanguageServerFolderService) lsFolderService: ILanguageServerFolderService, - @inject(IApplicationShell) appShell: IApplicationShell, - @inject(IFileSystem) fs: IFileSystem, - @inject(IWorkspaceService) workspace: IWorkspaceService, - @inject(IServiceContainer) services: IServiceContainer - ) { - super(lsOutputChannel, fileDownloader, lsFolderService, appShell, fs, workspace, services); - const config = workspace.getConfiguration('python'); - this.bundled = !config.get('packageName'); - } - - public async downloadLanguageServer(destinationFolder: string, resource: Resource): Promise { - if (!this.bundled) { - return super.downloadLanguageServer(destinationFolder, resource); - } - } -} diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index 6b3621fcef12..8b6d1cb49c98 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -48,6 +48,10 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer return this._bundledVersion; } + public isBundled(): boolean { + return !!this._bundledVersion; + } + public async getLanguageServerFolderName(resource: Resource): Promise { if (this._bundledVersion) { return NodeLanguageServerFolder; diff --git a/src/client/activation/serviceRegistry.ts b/src/client/activation/serviceRegistry.ts index d0143254ff9d..c7afe4e9afb1 100644 --- a/src/client/activation/serviceRegistry.ts +++ b/src/client/activation/serviceRegistry.ts @@ -41,7 +41,6 @@ import { LanguageServerOutputChannel } from './languageServer/outputChannel'; import { PlatformData } from './languageServer/platformData'; import { NodeLanguageServerActivator } from './node/activator'; import { NodeLanguageServerAnalysisOptions } from './node/analysisOptions'; -import { NodeLanguageServerDownloader } from './node/downloader'; import { NodeLanguageClientFactory } from './node/languageClientFactory'; import { NodeLanguageServerFolderService } from './node/languageServerFolderService'; import { @@ -150,7 +149,6 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp ILanguageServerPackageService, DotNetLanguageServerPackageService ); - serviceManager.addSingleton(ILanguageServerDownloader, LanguageServerDownloader); registerDotNetTypes(serviceManager); } else if (languageServerType === LanguageServerType.Node) { serviceManager.add( @@ -189,7 +187,6 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp ILanguageServerPackageService, NodeLanguageServerPackageService ); - serviceManager.addSingleton(ILanguageServerDownloader, NodeLanguageServerDownloader); } else if (languageServerType === LanguageServerType.None) { serviceManager.add( ILanguageServerActivator, @@ -213,6 +210,7 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp DownloadBetaChannelRule, LanguageServerDownloadChannel.stable ); + serviceManager.addSingleton(ILanguageServerDownloader, LanguageServerDownloader); serviceManager.addSingleton( ILanguageServerOutputChannel, diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index 6b53c01f60e0..d49c7eb5386e 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -116,6 +116,7 @@ export interface ILanguageServerFolderService { getLanguageServerFolderName(resource: Resource): Promise; getLatestLanguageServerVersion(resource: Resource): Promise; getCurrentLanguageServerDirectory(): Promise; + isBundled(): boolean; } export const ILanguageServerDownloader = Symbol('ILanguageServerDownloader'); diff --git a/src/test/activation/languageServer/downloader.unit.test.ts b/src/test/activation/languageServer/downloader.unit.test.ts index 19f00f1dc689..e0fc4e2b9e1f 100644 --- a/src/test/activation/languageServer/downloader.unit.test.ts +++ b/src/test/activation/languageServer/downloader.unit.test.ts @@ -269,6 +269,7 @@ suite('Language Server Activation - Downloader', () => { setup(() => { appShell = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); folderService = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); + folderService.setup((f) => f.isBundled()).returns(() => false); output = TypeMoq.Mock.ofType(); fs = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); platformData = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); From 74a7d39ad63130dd8e8dbc810d754cedd68216a4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 28 May 2020 12:54:02 -0700 Subject: [PATCH 05/11] Consider downloadLanguageServer, move to dedicated directory --- .gitignore | 2 +- .vscodeignore | 2 ++ src/client/activation/common/downloader.ts | 2 +- .../node/languageServerFolderService.ts | 23 +++++++++---- src/client/activation/types.ts | 1 + .../langaugeServerFolderSerivce.unit.test.ts | 33 +++++++++++++++++-- 6 files changed, 52 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index f3befcb98957..ebcf58dd5285 100644 --- a/.gitignore +++ b/.gitignore @@ -42,4 +42,4 @@ ptvsd*.log pydevd*.log nodeLanguageServer/** nodeLanguageServer.*/** - +bundledLanguageServer/** diff --git a/.vscodeignore b/.vscodeignore index fb4a694b35ea..cb9182d58ca6 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -58,6 +58,8 @@ webpack.datascience-*.config.js .vscode test/** languageServer/** languageServer.*/** +nodeLanguageServer/** +nodeLanguageServer.*/** bin/** build/** BuildOutput/** diff --git a/src/client/activation/common/downloader.ts b/src/client/activation/common/downloader.ts index 877a95c71bfb..c724175ace04 100644 --- a/src/client/activation/common/downloader.ts +++ b/src/client/activation/common/downloader.ts @@ -61,7 +61,7 @@ export class LanguageServerDownloader implements ILanguageServerDownloader { public async downloadLanguageServer(destinationFolder: string, resource: Resource): Promise { if (this.lsFolderService.isBundled()) { // Sanity check; a bundled LS should never be downloaded. - traceError('Attempted to download bundled langauge server'); + traceError('Attempted to download bundled language server'); return; } diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index 8b6d1cb49c98..bc18d0f1a1db 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -7,10 +7,15 @@ import { inject, injectable } from 'inversify'; import * as semver from 'semver'; import { IApplicationEnvironment, IWorkspaceService } from '../../common/application/types'; import { NugetPackage } from '../../common/nuget/types'; -import { Resource } from '../../common/types'; +import { IConfigurationService, Resource } from '../../common/types'; import { IServiceContainer } from '../../ioc/types'; import { LanguageServerFolderService } from '../common/languageServerFolderService'; -import { FolderVersionPair, ILanguageServerFolderService, NodeLanguageServerFolder } from '../types'; +import { + BundledLanguageServerFolder, + FolderVersionPair, + ILanguageServerFolderService, + NodeLanguageServerFolder +} from '../types'; // Must match languageServerVersion* keys in package.json export const NodeLanguageServerVersionKey = 'languageServerVersionV2'; @@ -32,13 +37,19 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer constructor( @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IConfigurationService) configService: IConfigurationService, @inject(IWorkspaceService) workspaceService: IWorkspaceService, @inject(IApplicationEnvironment) appEnv: IApplicationEnvironment ) { this.fallback = new FallbackNodeLanguageServerFolderService(serviceContainer); - const config = workspaceService.getConfiguration('python'); - if (!config.get('packageName')) { + // downloadLanguageServer is a bit of a misnomer; if false then this indicates that a local + // development copy should be run instead of a "real" build, telemetry discarded, etc. + // So, we require it to be true, even though in the bundled case no real download happens. + if ( + configService.getSettings().downloadLanguageServer && + !workspaceService.getConfiguration('python').get('packageName') + ) { const ver = appEnv.packageJson[NodeLanguageServerVersionKey] as string; this._bundledVersion = semver.parse(ver) || undefined; } @@ -54,7 +65,7 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer public async getLanguageServerFolderName(resource: Resource): Promise { if (this._bundledVersion) { - return NodeLanguageServerFolder; + return BundledLanguageServerFolder; } return this.fallback.getLanguageServerFolderName(resource); } @@ -68,7 +79,7 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer public async getCurrentLanguageServerDirectory(): Promise { if (this._bundledVersion) { - return { path: NodeLanguageServerFolder, version: this._bundledVersion }; + return { path: BundledLanguageServerFolder, version: this._bundledVersion }; } return this.fallback.getCurrentLanguageServerDirectory(); } diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index d49c7eb5386e..7cd251a86c6d 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -72,6 +72,7 @@ export enum LanguageServerType { export const DotNetLanguageServerFolder = 'languageServer'; export const NodeLanguageServerFolder = 'nodeLanguageServer'; +export const BundledLanguageServerFolder = 'bundledLanguageServer'; // tslint:disable-next-line: interface-name export interface DocumentHandler { diff --git a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts index e1b150ef1bc1..4f42c7770cb7 100644 --- a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts +++ b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts @@ -10,8 +10,9 @@ import { NodeLanguageServerFolderService, NodeLanguageServerVersionKey } from '../../../client/activation/node/languageServerFolderService'; -import { NodeLanguageServerFolder } from '../../../client/activation/types'; +import { BundledLanguageServerFolder } from '../../../client/activation/types'; import { IApplicationEnvironment, IWorkspaceService } from '../../../client/common/application/types'; +import { IConfigurationService, IPythonSettings } from '../../../client/common/types'; import { IServiceContainer } from '../../../client/ioc/types'; // tslint:disable:max-func-body-length @@ -21,12 +22,17 @@ suite('Node Language Server Folder Service', () => { const version = '0.0.1-test'; let serviceContainer: TypeMoq.IMock; + let pythonSettings: TypeMoq.IMock; + let configService: TypeMoq.IMock; let workspaceConfiguration: TypeMoq.IMock; let workspaceService: TypeMoq.IMock; let appEnvironment: TypeMoq.IMock; setup(() => { serviceContainer = TypeMoq.Mock.ofType(); + configService = TypeMoq.Mock.ofType(); + pythonSettings = TypeMoq.Mock.ofType(); + configService.setup((c) => c.getSettings(undefined)).returns(() => pythonSettings.object); workspaceConfiguration = TypeMoq.Mock.ofType(); workspaceService = TypeMoq.Mock.ofType(); workspaceService @@ -36,11 +42,13 @@ suite('Node Language Server Folder Service', () => { }); test('With packageName set', () => { + pythonSettings.setup((p) => p.downloadLanguageServer).returns(() => true); appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: version })); workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => 'somePackageName'); const folderService = new NodeLanguageServerFolderService( serviceContainer.object, + configService.object, workspaceService.object, appEnvironment.object ); @@ -49,11 +57,28 @@ suite('Node Language Server Folder Service', () => { }); test('Invalid version', () => { + pythonSettings.setup((p) => p.downloadLanguageServer).returns(() => true); appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: 'fakeversion' })); workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => undefined); const folderService = new NodeLanguageServerFolderService( serviceContainer.object, + configService.object, + workspaceService.object, + appEnvironment.object + ); + + expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + }); + + test('downloadLanguageServer set to false', () => { + pythonSettings.setup((p) => p.downloadLanguageServer).returns(() => false); + appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: 'fakeversion' })); + workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => undefined); + + const folderService = new NodeLanguageServerFolderService( + serviceContainer.object, + configService.object, workspaceService.object, appEnvironment.object ); @@ -65,10 +90,12 @@ suite('Node Language Server Folder Service', () => { let folderService: NodeLanguageServerFolderService; setup(() => { + pythonSettings.setup((p) => p.downloadLanguageServer).returns(() => true); appEnvironment.setup((e) => e.packageJson).returns(() => ({ [NodeLanguageServerVersionKey]: version })); workspaceConfiguration.setup((wc) => wc.get('packageName')).returns(() => undefined); folderService = new NodeLanguageServerFolderService( serviceContainer.object, + configService.object, workspaceService.object, appEnvironment.object ); @@ -80,7 +107,7 @@ suite('Node Language Server Folder Service', () => { test('getLanguageServerFolderName', async () => { const folderName = await folderService.getLanguageServerFolderName(resource); - expect(folderName).to.be.equal(NodeLanguageServerFolder); + expect(folderName).to.be.equal(BundledLanguageServerFolder); }); test('getLatestLanguageServerVersion', async () => { @@ -91,7 +118,7 @@ suite('Node Language Server Folder Service', () => { test('Method getCurrentLanguageServerDirectory()', async () => { const dir = await folderService.getCurrentLanguageServerDirectory(); assert(dir); - expect(dir!.path).to.equal(NodeLanguageServerFolder); + expect(dir!.path).to.equal(BundledLanguageServerFolder); expect(dir!.version.format()).to.be.equal(version); }); }); From 19d99e022a15093e73aa6ae1ba71cb8d97c82569 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 28 May 2020 13:00:08 -0700 Subject: [PATCH 06/11] Test isBundled --- .../node/langaugeServerFolderSerivce.unit.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts index 4f42c7770cb7..0573fb681fd9 100644 --- a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts +++ b/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts @@ -54,6 +54,7 @@ suite('Node Language Server Folder Service', () => { ); expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + expect(folderService.isBundled()).to.be.equal(false, 'isBundled should be false'); }); test('Invalid version', () => { @@ -69,6 +70,7 @@ suite('Node Language Server Folder Service', () => { ); expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + expect(folderService.isBundled()).to.be.equal(false, 'isBundled should be false'); }); test('downloadLanguageServer set to false', () => { @@ -84,6 +86,7 @@ suite('Node Language Server Folder Service', () => { ); expect(folderService.bundledVersion).to.be.equal(undefined, 'expected bundledVersion to be undefined'); + expect(folderService.isBundled()).to.be.equal(false, 'isBundled should be false'); }); suite('Valid configuration', () => { @@ -101,6 +104,10 @@ suite('Node Language Server Folder Service', () => { ); }); + test('isBundled is true', () => { + expect(folderService.isBundled()).to.be.equal(true, 'isBundled should be true'); + }); + test('Parsed version is correct', () => { expect(folderService.bundledVersion!.format()).to.be.equal(version); }); From 96e6596f07545020314a62cc510adae3627810da Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 28 May 2020 13:04:51 -0700 Subject: [PATCH 07/11] Test DotNet isBundled --- .../languageServerFolderService.unit.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/test/activation/languageServer/languageServerFolderService.unit.test.ts b/src/test/activation/languageServer/languageServerFolderService.unit.test.ts index a653bc4e58ec..8fc410d0f886 100644 --- a/src/test/activation/languageServer/languageServerFolderService.unit.test.ts +++ b/src/test/activation/languageServer/languageServerFolderService.unit.test.ts @@ -267,4 +267,15 @@ suite('Language Server Folder Service', () => { assert.deepEqual(result, expectedLSDirectory); }); }); + + suite('Method isBundled()', () => { + setup(() => { + serviceContainer = TypeMoq.Mock.ofType(); + languageServerFolderService = new DotNetLanguageServerFolderService(serviceContainer.object); + }); + + test('isBundled is false', () => { + expect(languageServerFolderService.isBundled()).to.be.equal(false, 'isBundled should be false'); + }); + }); }); From d2856cdf0ea53c9a03a9cbefba5e1637d9c9b0ac Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 1 Jun 2020 10:42:39 -0700 Subject: [PATCH 08/11] Apply suggestions from code review Co-authored-by: Eric Snow --- src/client/activation/node/languageServerFolderService.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index bc18d0f1a1db..ab19594f9411 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -52,6 +52,9 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer ) { const ver = appEnv.packageJson[NodeLanguageServerVersionKey] as string; this._bundledVersion = semver.parse(ver) || undefined; + if (this._bundledVersion === undefined) { + traceWarning(`invalid language server version ${ver} in package.json (${NodeLanguageServerVersionKey})`) + } } } @@ -60,7 +63,7 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer } public isBundled(): boolean { - return !!this._bundledVersion; + return this._bundledVersion !== undefined; } public async getLanguageServerFolderName(resource: Resource): Promise { From b68ed8f901c78289b22565b9b6b3c7ac2303fc1e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 1 Jun 2020 11:33:43 -0700 Subject: [PATCH 09/11] Fix bad import, test that no download happens on bundle --- .../node/languageServerFolderService.ts | 5 ++- .../languageServer/downloader.unit.test.ts | 40 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/client/activation/node/languageServerFolderService.ts b/src/client/activation/node/languageServerFolderService.ts index ab19594f9411..a2a15eb7908f 100644 --- a/src/client/activation/node/languageServerFolderService.ts +++ b/src/client/activation/node/languageServerFolderService.ts @@ -9,6 +9,7 @@ import { IApplicationEnvironment, IWorkspaceService } from '../../common/applica import { NugetPackage } from '../../common/nuget/types'; import { IConfigurationService, Resource } from '../../common/types'; import { IServiceContainer } from '../../ioc/types'; +import { traceWarning } from '../../logging'; import { LanguageServerFolderService } from '../common/languageServerFolderService'; import { BundledLanguageServerFolder, @@ -53,7 +54,9 @@ export class NodeLanguageServerFolderService implements ILanguageServerFolderSer const ver = appEnv.packageJson[NodeLanguageServerVersionKey] as string; this._bundledVersion = semver.parse(ver) || undefined; if (this._bundledVersion === undefined) { - traceWarning(`invalid language server version ${ver} in package.json (${NodeLanguageServerVersionKey})`) + traceWarning( + `invalid language server version ${ver} in package.json (${NodeLanguageServerVersionKey})` + ); } } } diff --git a/src/test/activation/languageServer/downloader.unit.test.ts b/src/test/activation/languageServer/downloader.unit.test.ts index e0fc4e2b9e1f..ac2a4e8b4ab3 100644 --- a/src/test/activation/languageServer/downloader.unit.test.ts +++ b/src/test/activation/languageServer/downloader.unit.test.ts @@ -260,16 +260,32 @@ suite('Language Server Activation - Downloader', () => { throw failure; } } + class LanguageServeBundledTest extends LanguageServerDownloader { + // tslint:disable-next-line:no-unnecessary-override + public async downloadLanguageServer(destinationFolder: string, res?: Resource): Promise { + return super.downloadLanguageServer(destinationFolder, res); + } + // tslint:disable-next-line:no-unnecessary-override + public async getDownloadInfo(_res?: Resource): Promise { + throw failure; + } + public async downloadFile(): Promise { + throw failure; + } + protected async unpackArchive(_extensionPath: string, _tempFilePath: string): Promise { + throw failure; + } + } let output: TypeMoq.IMock; let appShell: TypeMoq.IMock; let fs: TypeMoq.IMock; let platformData: TypeMoq.IMock; let languageServerDownloaderTest: LanguageServerDownloaderTest; let languageServerExtractorTest: LanguageServerExtractorTest; + let languageServerBundledTest: LanguageServeBundledTest; setup(() => { appShell = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); folderService = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); - folderService.setup((f) => f.isBundled()).returns(() => false); output = TypeMoq.Mock.ofType(); fs = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); platformData = TypeMoq.Mock.ofType(undefined, TypeMoq.MockBehavior.Strict); @@ -294,8 +310,18 @@ suite('Language Server Activation - Downloader', () => { workspaceService.object, undefined as any ); + languageServerBundledTest = new LanguageServeBundledTest( + lsOutputChannel.object, + undefined as any, + folderService.object, + appShell.object, + fs.object, + workspaceService.object, + undefined as any + ); }); test('Display error message if LS downloading fails', async () => { + folderService.setup((f) => f.isBundled()).returns(() => false); const pkg = makePkgInfo('ls', 'xyz'); folderService.setup((f) => f.getLatestLanguageServerVersion(resource)).returns(() => Promise.resolve(pkg)); output.setup((o) => o.appendLine(LanguageService.downloadFailedOutputMessage())); @@ -319,6 +345,7 @@ suite('Language Server Activation - Downloader', () => { platformData.verifyAll(); }); test('Display error message if LS extraction fails', async () => { + folderService.setup((f) => f.isBundled()).returns(() => false); const pkg = makePkgInfo('ls', 'xyz'); folderService.setup((f) => f.getLatestLanguageServerVersion(resource)).returns(() => Promise.resolve(pkg)); output.setup((o) => o.appendLine(LanguageService.extractionFailedOutputMessage())); @@ -341,6 +368,17 @@ suite('Language Server Activation - Downloader', () => { fs.verifyAll(); platformData.verifyAll(); }); + test('No download if bundled', async () => { + folderService.setup((f) => f.isBundled()).returns(() => true); + + await languageServerBundledTest.downloadLanguageServer('', resource); + + folderService.verifyAll(); + output.verifyAll(); + appShell.verifyAll(); + fs.verifyAll(); + platformData.verifyAll(); + }); }); }); From d0a56e00bd29f03448e09a36b96a53c3c919aad3 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 1 Jun 2020 11:52:38 -0700 Subject: [PATCH 10/11] Revert existing key rename --- package.json | 2 +- .../activation/languageServer/languageServerFolderService.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ef0f1e521f4f..8285e8f5ae92 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "featureFlags": { "usingNewInterpreterStorage": true }, - "languageServerVersionV1": "0.5.30", + "languageServerVersion": "0.5.30", "publisher": "ms-python", "enableProposedApi": false, "author": { diff --git a/src/client/activation/languageServer/languageServerFolderService.ts b/src/client/activation/languageServer/languageServerFolderService.ts index f3e34b589149..bf541ab4690f 100644 --- a/src/client/activation/languageServer/languageServerFolderService.ts +++ b/src/client/activation/languageServer/languageServerFolderService.ts @@ -10,7 +10,7 @@ import { LanguageServerFolderService } from '../common/languageServerFolderServi import { DotNetLanguageServerFolder } from '../types'; // Must match languageServerVersion* keys in package.json -export const DotNetLanguageServerMinVersionKey = 'languageServerVersionV1'; +export const DotNetLanguageServerMinVersionKey = 'languageServerVersion'; @injectable() export class DotNetLanguageServerFolderService extends LanguageServerFolderService { From d3ddb7484793bcd3c9674e5bceb61f23962013c7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 1 Jun 2020 12:54:30 -0700 Subject: [PATCH 11/11] Fix typos in filename --- ...ivce.unit.test.ts => languageServerFolderService.unit.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/test/activation/node/{langaugeServerFolderSerivce.unit.test.ts => languageServerFolderService.unit.test.ts} (100%) diff --git a/src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts b/src/test/activation/node/languageServerFolderService.unit.test.ts similarity index 100% rename from src/test/activation/node/langaugeServerFolderSerivce.unit.test.ts rename to src/test/activation/node/languageServerFolderService.unit.test.ts