From 863c56360a998fa209f02a0bd7f8b95075b77670 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Wed, 18 Jul 2018 12:30:34 -0700 Subject: [PATCH] Change the download links of the language server files --- news/3 Code Health/2180.md | 1 + src/client/activation/downloader.ts | 24 +++++-- src/client/activation/platformData.ts | 15 ++-- src/test/activation/downloader.unit.test.ts | 68 +++++++++++++++++++ ...Data.test.ts => platformData.unit.test.ts} | 13 ++-- 5 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 news/3 Code Health/2180.md create mode 100644 src/test/activation/downloader.unit.test.ts rename src/test/activation/{platformData.test.ts => platformData.unit.test.ts} (90%) diff --git a/news/3 Code Health/2180.md b/news/3 Code Health/2180.md new file mode 100644 index 000000000000..d49e681aa8c7 --- /dev/null +++ b/news/3 Code Health/2180.md @@ -0,0 +1 @@ +Change the download links of the language server files. diff --git a/src/client/activation/downloader.ts b/src/client/activation/downloader.ts index c80b7dd40856..8b7ed686babe 100644 --- a/src/client/activation/downloader.ts +++ b/src/client/activation/downloader.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +'use strict'; + import * as fileSystem from 'fs'; import * as path from 'path'; import * as request from 'request'; @@ -11,7 +13,7 @@ import { createDeferred } from '../common/helpers'; import { IFileSystem, IPlatformService } from '../common/platform/types'; import { IExtensionContext, IOutputChannel } from '../common/types'; import { IServiceContainer } from '../ioc/types'; -import { PlatformData } from './platformData'; +import { PlatformData, PlatformName } from './platformData'; // tslint:disable-next-line:no-require-imports no-var-requires const StreamZip = require('node-stream-zip'); @@ -21,6 +23,13 @@ const downloadBaseFileName = 'Python-Language-Server'; const downloadVersion = '0.1.0'; const downloadFileExtension = '.nupkg'; +const DownloadLinks = { + [PlatformName.Windows32Bit]: `${downloadUriPrefix}/${downloadBaseFileName}-${PlatformName.Windows32Bit}.${downloadVersion}${downloadFileExtension}`, + [PlatformName.Windows64Bit]: `${downloadUriPrefix}/${downloadBaseFileName}-${PlatformName.Windows64Bit}.${downloadVersion}${downloadFileExtension}`, + [PlatformName.Linux64Bit]: `${downloadUriPrefix}/${downloadBaseFileName}-${PlatformName.Linux64Bit}.${downloadVersion}${downloadFileExtension}`, + [PlatformName.Mac64Bit]: `${downloadUriPrefix}/${downloadBaseFileName}-${PlatformName.Mac64Bit}.${downloadVersion}${downloadFileExtension}` +}; + export class LanguageServerDownloader { private readonly output: OutputChannel; private readonly platform: IPlatformService; @@ -34,13 +43,17 @@ export class LanguageServerDownloader { this.platformData = new PlatformData(this.platform, this.fs); } - public async downloadLanguageServer(context: IExtensionContext): Promise { + public async getDownloadUri() { const platformString = await this.platformData.getPlatformName(); - const enginePackageFileName = `${downloadBaseFileName}-${platformString}.${downloadVersion}${downloadFileExtension}`; + return DownloadLinks[platformString]; + } + + public async downloadLanguageServer(context: IExtensionContext): Promise { + const downloadUri = await this.getDownloadUri(); let localTempFilePath = ''; try { - localTempFilePath = await this.downloadFile(downloadUriPrefix, enginePackageFileName, 'Downloading Microsoft Python Language Server... '); + localTempFilePath = await this.downloadFile(downloadUri, 'Downloading Microsoft Python Language Server... '); await this.unpackArchive(context.extensionPath, localTempFilePath); } catch (err) { this.output.appendLine('failed.'); @@ -53,8 +66,7 @@ export class LanguageServerDownloader { } } - private async downloadFile(location: string, fileName: string, title: string): Promise { - const uri = `${location}/${fileName}`; + private async downloadFile(uri: string, title: string): Promise { this.output.append(`Downloading ${uri}... `); const tempFile = await this.fs.createTemporaryFile(downloadFileExtension); diff --git a/src/client/activation/platformData.ts b/src/client/activation/platformData.ts index 60448dccc850..8564b8625b44 100644 --- a/src/client/activation/platformData.ts +++ b/src/client/activation/platformData.ts @@ -9,20 +9,27 @@ import { language_server_win_x86_sha512 } from './languageServerHashes'; +export enum PlatformName { + Windows32Bit = 'win-x86', + Windows64Bit = 'win-x64', + Mac64Bit = 'osx-x64', + Linux64Bit = 'linux-x64' +} + export class PlatformData { constructor(private platform: IPlatformService, fs: IFileSystem) { } - public async getPlatformName(): Promise { + public async getPlatformName(): Promise { if (this.platform.isWindows) { - return this.platform.is64bit ? 'win-x64' : 'win-x86'; + return this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit; } if (this.platform.isMac) { - return 'osx-x64'; + return PlatformName.Mac64Bit; } if (this.platform.isLinux) { if (!this.platform.is64bit) { throw new Error('Microsoft Python Language Server does not support 32-bit Linux.'); } - return 'linux-x64'; + return PlatformName.Linux64Bit; } throw new Error('Unknown OS platform.'); } diff --git a/src/test/activation/downloader.unit.test.ts b/src/test/activation/downloader.unit.test.ts new file mode 100644 index 000000000000..c75b5e3b3d49 --- /dev/null +++ b/src/test/activation/downloader.unit.test.ts @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +// tslint:disable:no-unused-variable + +import * as assert from 'assert'; +import * as TypeMoq from 'typemoq'; +import { LanguageServerDownloader } from '../../client/activation/downloader'; +import { IFileSystem, IPlatformService } from '../../client/common/platform/types'; +import { IOutputChannel } from '../../client/common/types'; +import { IServiceContainer } from '../../client/ioc/types'; + +const downloadUriPrefix = 'https://pvsc.blob.core.windows.net/python-language-server'; +const downloadBaseFileName = 'Python-Language-Server'; +const downloadVersion = '0.1.0'; +const downloadFileExtension = '.nupkg'; + +suite('Activation - Downloader', () => { + let languageServerDownloader: LanguageServerDownloader; + let serviceContainer: TypeMoq.IMock; + let platformService: TypeMoq.IMock; + setup(() => { + serviceContainer = TypeMoq.Mock.ofType(); + platformService = TypeMoq.Mock.ofType(); + const fs = TypeMoq.Mock.ofType(); + const output = TypeMoq.Mock.ofType(); + + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IOutputChannel), TypeMoq.It.isAny())).returns(() => output.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPlatformService))).returns(() => platformService.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fs.object); + + languageServerDownloader = new LanguageServerDownloader(serviceContainer.object, ''); + }); + type PlatformIdentifier = { + windows?: boolean; + mac?: boolean; + linux?: boolean; + is64Bit?: boolean; + }; + function setupPlatform(platform: PlatformIdentifier) { + platformService.setup(x => x.isWindows).returns(() => platform.windows === true); + platformService.setup(x => x.isMac).returns(() => platform.mac === true); + platformService.setup(x => x.isLinux).returns(() => platform.linux === true); + platformService.setup(x => x.is64bit).returns(() => platform.is64Bit === true); + } + test('Windows 32Bit', async () => { + setupPlatform({ windows: true }); + const link = await languageServerDownloader.getDownloadUri(); + assert.equal(link, `${downloadUriPrefix}/${downloadBaseFileName}-win-x86.${downloadVersion}${downloadFileExtension}`); + }); + test('Windows 64Bit', async () => { + setupPlatform({ windows: true, is64Bit: true }); + const link = await languageServerDownloader.getDownloadUri(); + assert.equal(link, `${downloadUriPrefix}/${downloadBaseFileName}-win-x64.${downloadVersion}${downloadFileExtension}`); + }); + test('Mac 64Bit', async () => { + setupPlatform({ mac: true, is64Bit: true }); + const link = await languageServerDownloader.getDownloadUri(); + assert.equal(link, `${downloadUriPrefix}/${downloadBaseFileName}-osx-x64.${downloadVersion}${downloadFileExtension}`); + }); + test('Linux 64Bit', async () => { + setupPlatform({ linux: true, is64Bit: true }); + const link = await languageServerDownloader.getDownloadUri(); + assert.equal(link, `${downloadUriPrefix}/${downloadBaseFileName}-linux-x64.${downloadVersion}${downloadFileExtension}`); + }); +}); diff --git a/src/test/activation/platformData.test.ts b/src/test/activation/platformData.unit.test.ts similarity index 90% rename from src/test/activation/platformData.test.ts rename to src/test/activation/platformData.unit.test.ts index 6d847253c05f..80ce2ce494be 100644 --- a/src/test/activation/platformData.test.ts +++ b/src/test/activation/platformData.unit.test.ts @@ -6,7 +6,6 @@ import * as assert from 'assert'; import * as TypeMoq from 'typemoq'; import { PlatformData } from '../../client/activation/platformData'; import { IFileSystem, IPlatformService } from '../../client/common/platform/types'; -import { initialize } from '../initialize'; const testDataWinMac = [ { isWindows: true, is64Bit: true, expectedName: 'win-x64' }, @@ -31,8 +30,6 @@ const testDataModuleName = [ // tslint:disable-next-line:max-func-body-length suite('Activation - platform data', () => { - suiteSetup(initialize); - test('Name and hash (Windows/Mac)', async () => { for (const t of testDataWinMac) { const platformService = TypeMoq.Mock.ofType(); @@ -43,11 +40,11 @@ suite('Activation - platform data', () => { const fs = TypeMoq.Mock.ofType(); const pd = new PlatformData(platformService.object, fs.object); - let actual = await pd.getPlatformName(); + const actual = await pd.getPlatformName(); assert.equal(actual, t.expectedName, `${actual} does not match ${t.expectedName}`); - actual = await pd.getExpectedHash(); - assert.equal(actual, t.expectedName, `${actual} hash not match ${t.expectedName}`); + const actualHash = await pd.getExpectedHash(); + assert.equal(actualHash, t.expectedName, `${actual} hash not match ${t.expectedName}`); } }); test('Name and hash (Linux)', async () => { @@ -62,10 +59,10 @@ suite('Activation - platform data', () => { fs.setup(x => x.readFile(TypeMoq.It.isAnyString())).returns(() => Promise.resolve(`NAME="name"\nID=${t.name}\nID_LIKE=debian`)); const pd = new PlatformData(platformService.object, fs.object); - let actual = await pd.getPlatformName(); + const actual = await pd.getPlatformName(); assert.equal(actual, t.expectedName, `${actual} does not match ${t.expectedName}`); - actual = await pd.getExpectedHash(); + const actualHash = await pd.getExpectedHash(); assert.equal(actual, t.expectedName, `${actual} hash not match ${t.expectedName}`); } });