| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent e3a6bc2 commit 3ab005e
12 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -133,4 +133,4 @@ | |||
| 133 | 133 | ] | |
| 134 | 134 | } | |
| 135 | 135 | ] | |
| 136 | - } | ||
| 136 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Make use of the `http.proxy` field in settings.json when downloading the Python Language Server. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,17 +3,14 @@ | |||
| 3 | 3 | ||
| 4 | 4 | 'use strict'; | |
| 5 | 5 | ||
| 6 | - import * as fileSystem from 'fs'; | ||
| 7 | 6 | import * as path from 'path'; | |
| 8 | - import * as request from 'request'; | ||
| 9 | 7 | import * as requestProgress from 'request-progress'; | |
| 10 | - import { OutputChannel, ProgressLocation, window } from 'vscode'; | ||
| 11 | - import { STANDARD_OUTPUT_CHANNEL } from '../common/constants'; | ||
| 8 | + import { ProgressLocation, window } from 'vscode'; | ||
| 12 | 9 | import { createDeferred } from '../common/helpers'; | |
| 13 | - import { IFileSystem, IPlatformService } from '../common/platform/types'; | ||
| 10 | + import { IFileSystem } from '../common/platform/types'; | ||
| 14 | 11 | import { IExtensionContext, IOutputChannel } from '../common/types'; | |
| 15 | - import { IServiceContainer } from '../ioc/types'; | ||
| 16 | 12 | import { PlatformData, PlatformName } from './platformData'; | |
| 13 | + import { IDownloadFileService } from './types'; | ||
| 17 | 14 | ||
| 18 | 15 | // tslint:disable-next-line:no-require-imports no-var-requires | |
| 19 | 16 | const StreamZip = require('node-stream-zip'); | |
@@ -31,25 +28,21 @@ export const DownloadLinks = { | |||
| 31 | 28 | }; | |
| 32 | 29 | ||
| 33 | 30 | export class LanguageServerDownloader { | |
| 34 | - private readonly output: OutputChannel; | ||
| 35 | - private readonly platform: IPlatformService; | ||
| 36 | - private readonly platformData: PlatformData; | ||
| 37 | - private readonly fs: IFileSystem; | ||
| 38 | - | ||
| 39 | - constructor(private readonly services: IServiceContainer, private engineFolder: string) { | ||
| 40 | - this.output = this.services.get<OutputChannel>(IOutputChannel, STANDARD_OUTPUT_CHANNEL); | ||
| 41 | - this.fs = this.services.get<IFileSystem>(IFileSystem); | ||
| 42 | - this.platform = this.services.get<IPlatformService>(IPlatformService); | ||
| 43 | - this.platformData = new PlatformData(this.platform, this.fs); | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - public async getDownloadUri() { | ||
| 47 | - const platformString = await this.platformData.getPlatformName(); | ||
| 31 | + constructor( | ||
| 32 | + private readonly output: IOutputChannel, | ||
| 33 | + private readonly fs: IFileSystem, | ||
| 34 | + private readonly platformData: PlatformData, | ||
| 35 | + private requestHandler: IDownloadFileService, | ||
| 36 | + private engineFolder: string | ||
| 37 | + ) { } | ||
| 38 | + | ||
| 39 | + public getDownloadUri() { | ||
| 40 | + const platformString = this.platformData.getPlatformName(); | ||
| 48 | 41 | return DownloadLinks[platformString]; | |
| 49 | 42 | } | |
| 50 | 43 | ||
| 51 | 44 | public async downloadLanguageServer(context: IExtensionContext): Promise<void> { | |
| 52 | - const downloadUri = await this.getDownloadUri(); | ||
| 45 | + const downloadUri = this.getDownloadUri(); | ||
| 53 | 46 | ||
| 54 | 47 | let localTempFilePath = ''; | |
| 55 | 48 | try { | |
@@ -71,7 +64,7 @@ export class LanguageServerDownloader { | |||
| 71 | 64 | const tempFile = await this.fs.createTemporaryFile(downloadFileExtension); | |
| 72 | 65 | ||
| 73 | 66 | const deferred = createDeferred(); | |
| 74 | - const fileStream = fileSystem.createWriteStream(tempFile.filePath); | ||
| 67 | + const fileStream = this.fs.createWriteStream(tempFile.filePath); | ||
| 75 | 68 | fileStream.on('finish', () => { | |
| 76 | 69 | fileStream.close(); | |
| 77 | 70 | }).on('error', (err) => { | |
@@ -83,7 +76,8 @@ export class LanguageServerDownloader { | |||
| 83 | 76 | location: ProgressLocation.Window | |
| 84 | 77 | }, (progress) => { | |
| 85 | 78 | ||
| 86 | - requestProgress(request(uri)) | ||
| 79 | + requestProgress( | ||
| 80 | + this.requestHandler!.downloadFile(uri)) | ||
| 87 | 81 | .on('progress', (state) => { | |
| 88 | 82 | // https://www.npmjs.com/package/request-progress | |
| 89 | 83 | const received = Math.round(state.size.transferred / 1024); | |
@@ -147,11 +141,10 @@ export class LanguageServerDownloader { | |||
| 147 | 141 | return deferred.promise; | |
| 148 | 142 | }); | |
| 149 | 143 | ||
| 150 | - // Set file to executable | ||
| 151 | - if (!this.platform.isWindows) { | ||
| 152 | - const executablePath = path.join(installFolder, this.platformData.getEngineExecutableName()); | ||
| 153 | - fileSystem.chmodSync(executablePath, '0764'); // -rwxrw-r-- | ||
| 154 | - } | ||
| 144 | + // Set file to executable (nothing happens in Windows, as chmod has no definition there) | ||
| 145 | + const executablePath = path.join(installFolder, this.platformData.getEngineExecutableName()); | ||
| 146 | + await this.fs.chmod(executablePath, '0764'); // -rwxrw-r-- | ||
| 147 | + | ||
| 155 | 148 | this.output.appendLine('done.'); | |
| 156 | 149 | } | |
| 157 | 150 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,6 +33,7 @@ import { LanguageServerDownloader } from './downloader'; | |||
| 33 | 33 | import { InterpreterData, InterpreterDataService } from './interpreterDataService'; | |
| 34 | 34 | import { PlatformData } from './platformData'; | |
| 35 | 35 | import { ProgressReporting } from './progress'; | |
| 36 | + import { RequestWithProxy } from './requestWithProxy'; | ||
| 36 | 37 | import { IExtensionActivator } from './types'; | |
| 37 | 38 | ||
| 38 | 39 | const PYTHON = 'python'; | |
@@ -137,7 +138,12 @@ export class LanguageServerExtensionActivator implements IExtensionActivator { | |||
| 137 | 138 | ||
| 138 | 139 | const mscorlib = path.join(this.context.extensionPath, languageServerFolder, 'mscorlib.dll'); | |
| 139 | 140 | if (!await this.fs.fileExists(mscorlib)) { | |
| 140 | - const downloader = new LanguageServerDownloader(this.services, languageServerFolder); | ||
| 141 | + const downloader = new LanguageServerDownloader( | ||
| 142 | + this.output, | ||
| 143 | + this.fs, | ||
| 144 | + this.platformData, | ||
| 145 | + new RequestWithProxy(this.workspace.getConfiguration('http').get('proxy', '')), | ||
| 146 | + languageServerFolder); | ||
| 141 | 147 | await downloader.downloadLanguageServer(this.context); | |
| 142 | 148 | reporter.sendTelemetryEvent(PYTHON_LANGUAGE_SERVER_DOWNLOADED); | |
| 143 | 149 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,7 +24,7 @@ export enum PlatformLSExecutables { | |||
| 24 | 24 | ||
| 25 | 25 | export class PlatformData { | |
| 26 | 26 | constructor(private platform: IPlatformService, fs: IFileSystem) { } | |
| 27 | - public async getPlatformName(): Promise<PlatformName> { | ||
| 27 | + public getPlatformName(): PlatformName { | ||
| 28 | 28 | if (this.platform.isWindows) { | |
| 29 | 29 | return this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit; | |
| 30 | 30 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,28 @@ | |||
| 1 | + // Copyright (c) Microsoft Corporation. All rights reserved. | ||
| 2 | + // Licensed under the MIT License. | ||
| 3 | + | ||
| 4 | + 'use strict'; | ||
| 5 | + | ||
| 6 | + import * as request from 'request'; | ||
| 7 | + import { IDownloadFileService } from './types'; | ||
| 8 | + | ||
| 9 | + // Simple wrapper for request to allow for the use of a proxy server being | ||
| 10 | + // specified in the request options. | ||
| 11 | + export class RequestWithProxy implements IDownloadFileService { | ||
| 12 | + constructor(private proxyUri: string) { } | ||
| 13 | + | ||
| 14 | + public get requestOptions(): request.CoreOptions | undefined { | ||
| 15 | + if (this.proxyUri && this.proxyUri.length > 0) { | ||
| 16 | + return { | ||
| 17 | + proxy: this.proxyUri | ||
| 18 | + }; | ||
| 19 | + } else { | ||
| 20 | + return; | ||
| 21 | + } | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + public downloadFile(uri: string): request.Request { | ||
| 25 | + const requestOptions: request.CoreOptions | undefined = this.requestOptions; | ||
| 26 | + return request(uri, requestOptions); | ||
| 27 | + } | ||
| 28 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,10 @@ | |||
| 1 | 1 | // Copyright (c) Microsoft Corporation. All rights reserved. | |
| 2 | 2 | // Licensed under the MIT License. | |
| 3 | 3 | ||
| 4 | + 'use strict'; | ||
| 5 | + | ||
| 6 | + import { Request as RequestResult } from 'request'; | ||
| 7 | + | ||
| 4 | 8 | export const IExtensionActivationService = Symbol('IExtensionActivationService'); | |
| 5 | 9 | export interface IExtensionActivationService { | |
| 6 | 10 | activate(): Promise<void>; | |
@@ -16,3 +20,7 @@ export interface IExtensionActivator { | |||
| 16 | 20 | activate(): Promise<boolean>; | |
| 17 | 21 | deactivate(): Promise<void>; | |
| 18 | 22 | } | |
| 23 | + | ||
| 24 | + export interface IDownloadFileService { | ||
| 25 | + downloadFile(uri: string): RequestResult; | ||
| 26 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | 'use strict'; | |
| 4 | 4 | ||
| 5 | 5 | import { createHash } from 'crypto'; | |
| 6 | + import * as fileSystem from 'fs'; | ||
| 6 | 7 | import * as fs from 'fs-extra'; | |
| 7 | 8 | import * as glob from 'glob'; | |
| 8 | 9 | import { inject, injectable } from 'inversify'; | |
@@ -151,6 +152,20 @@ export class FileSystem implements IFileSystem { | |||
| 151 | 152 | resolve({ filePath: tmpFile, dispose: cleanupCallback }); | |
| 152 | 153 | }); | |
| 153 | 154 | }); | |
| 155 | + } | ||
| 156 | + | ||
| 157 | + public createWriteStream(filePath: string): fileSystem.WriteStream { | ||
| 158 | + return fileSystem.createWriteStream(filePath); | ||
| 159 | + } | ||
| 154 | 160 | ||
| 161 | + public chmod(filePath: string, mode: string): Promise<void> { | ||
| 162 | + return new Promise<void>((resolve, reject) => { | ||
| 163 | + fileSystem.chmod(filePath, mode, (err: NodeJS.ErrnoException) => { | ||
| 164 | + if (err) { | ||
| 165 | + return reject(err); | ||
| 166 | + } | ||
| 167 | + resolve(); | ||
| 168 | + }); | ||
| 169 | + }); | ||
| 155 | 170 | } | |
| 156 | 171 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -86,4 +86,6 @@ export interface IFileSystem { | |||
| 86 | 86 | getFileHash(filePath: string): Promise<string | undefined>; | |
| 87 | 87 | search(globPattern: string): Promise<string[]>; | |
| 88 | 88 | createTemporaryFile(extension: string): Promise<TemporaryFile>; | |
| 89 | + createWriteStream(path: string): fs.WriteStream; | ||
| 90 | + chmod(path: string, mode: string): Promise<void>; | ||
| 89 | 91 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6,28 +6,38 @@ | |||
| 6 | 6 | // tslint:disable:no-unused-variable | |
| 7 | 7 | ||
| 8 | 8 | import * as assert from 'assert'; | |
| 9 | + import * as request from 'request'; | ||
| 9 | 10 | import * as TypeMoq from 'typemoq'; | |
| 11 | + import { WorkspaceConfiguration } from 'vscode'; | ||
| 10 | 12 | import { DownloadLinks, LanguageServerDownloader } from '../../client/activation/downloader'; | |
| 11 | - import { PlatformName } from '../../client/activation/platformData'; | ||
| 13 | + import { PlatformData, PlatformName } from '../../client/activation/platformData'; | ||
| 14 | + import { RequestWithProxy } from '../../client/activation/requestWithProxy'; | ||
| 15 | + import { IDownloadFileService } from '../../client/activation/types'; | ||
| 16 | + import { IWorkspaceService } from '../../client/common/application/types'; | ||
| 12 | 17 | import { IFileSystem, IPlatformService } from '../../client/common/platform/types'; | |
| 13 | 18 | import { IOutputChannel } from '../../client/common/types'; | |
| 14 | - import { IServiceContainer } from '../../client/ioc/types'; | ||
| 15 | 19 | ||
| 16 | 20 | suite('Activation - Downloader', () => { | |
| 17 | 21 | let languageServerDownloader: LanguageServerDownloader; | |
| 18 | - let serviceContainer: TypeMoq.IMock<IServiceContainer>; | ||
| 19 | 22 | let platformService: TypeMoq.IMock<IPlatformService>; | |
| 23 | + | ||
| 20 | 24 | setup(() => { | |
| 21 | - serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>(); | ||
| 22 | 25 | platformService = TypeMoq.Mock.ofType<IPlatformService>(); | |
| 23 | 26 | const fs = TypeMoq.Mock.ofType<IFileSystem>(); | |
| 24 | 27 | const output = TypeMoq.Mock.ofType<IOutputChannel>(); | |
| 28 | + const workspace = TypeMoq.Mock.ofType<IWorkspaceService>(); | ||
| 29 | + const platformData: PlatformData = new PlatformData(platformService.object, fs.object); | ||
| 30 | + const wsConfig = TypeMoq.Mock.ofType<WorkspaceConfiguration>(); | ||
| 31 | + workspace.setup(a => a.getConfiguration(TypeMoq.It.isValue('http'))).returns(() => wsConfig.object); | ||
| 32 | + wsConfig.setup(a => a.get(TypeMoq.It.isValue('proxy'), TypeMoq.It.isAnyString())).returns(() => ''); | ||
| 25 | 33 | ||
| 26 | - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IOutputChannel), TypeMoq.It.isAny())).returns(() => output.object); | ||
| 27 | - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPlatformService))).returns(() => platformService.object); | ||
| 28 | - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fs.object); | ||
| 34 | + languageServerDownloader = new LanguageServerDownloader( | ||
| 35 | + output.object, | ||
| 36 | + fs.object, | ||
| 37 | + platformData, | ||
| 38 | + new RequestWithProxy(''), | ||
| 39 | + ''); | ||
| 29 | 40 | ||
| 30 | - languageServerDownloader = new LanguageServerDownloader(serviceContainer.object, ''); | ||
| 31 | 41 | }); | |
| 32 | 42 | type PlatformIdentifier = { | |
| 33 | 43 | windows?: boolean; | |
@@ -43,22 +53,22 @@ suite('Activation - Downloader', () => { | |||
| 43 | 53 | } | |
| 44 | 54 | test('Windows 32Bit', async () => { | |
| 45 | 55 | setupPlatform({ windows: true }); | |
| 46 | - const link = await languageServerDownloader.getDownloadUri(); | ||
| 56 | + const link = languageServerDownloader.getDownloadUri(); | ||
| 47 | 57 | assert.equal(link, DownloadLinks[PlatformName.Windows32Bit]); | |
| 48 | 58 | }); | |
| 49 | 59 | test('Windows 64Bit', async () => { | |
| 50 | 60 | setupPlatform({ windows: true, is64Bit: true }); | |
| 51 | - const link = await languageServerDownloader.getDownloadUri(); | ||
| 61 | + const link = languageServerDownloader.getDownloadUri(); | ||
| 52 | 62 | assert.equal(link, DownloadLinks[PlatformName.Windows64Bit]); | |
| 53 | 63 | }); | |
| 54 | 64 | test('Mac 64Bit', async () => { | |
| 55 | 65 | setupPlatform({ mac: true, is64Bit: true }); | |
| 56 | - const link = await languageServerDownloader.getDownloadUri(); | ||
| 66 | + const link = languageServerDownloader.getDownloadUri(); | ||
| 57 | 67 | assert.equal(link, DownloadLinks[PlatformName.Mac64Bit]); | |
| 58 | 68 | }); | |
| 59 | 69 | test('Linux 64Bit', async () => { | |
| 60 | 70 | setupPlatform({ linux: true, is64Bit: true }); | |
| 61 | - const link = await languageServerDownloader.getDownloadUri(); | ||
| 71 | + const link = languageServerDownloader.getDownloadUri(); | ||
| 62 | 72 | assert.equal(link, DownloadLinks[PlatformName.Linux64Bit]); | |
| 63 | 73 | }); | |
| 64 | 74 | }); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments