|  | 
| 1 |  | -// Copyright (c) Microsoft Corporation. All rights reserved. | 
| 2 |  | -// Licensed under the MIT License. | 
| 3 |  | - | 
| 4 |  | -'use strict'; | 
| 5 |  | - | 
| 6 |  | -import { inject, injectable } from 'inversify'; | 
| 7 |  | -import { parse, SemVer } from 'semver'; | 
| 8 |  | -import { IApplicationEnvironment } from '../../common/application/types'; | 
| 9 |  | -import { PVSC_EXTENSION_ID } from '../../common/constants'; | 
| 10 |  | -import { traceDecorators, traceVerbose } from '../../common/logger'; | 
| 11 |  | -import { INugetRepository, INugetService, NugetPackage } from '../../common/nuget/types'; | 
| 12 |  | -import { IPlatformService } from '../../common/platform/types'; | 
| 13 |  | -import { | 
| 14 |  | - IConfigurationService, IExtensions, LanguageServerDownloadChannels, Resource | 
| 15 |  | -} from '../../common/types'; | 
| 16 |  | -import { OSType } from '../../common/utils/platform'; | 
| 17 |  | -import { IServiceContainer } from '../../ioc/types'; | 
| 18 |  | -import { ILanguageServerPackageService, PlatformName } from '../types'; | 
| 19 |  | -import { azureCDNBlobStorageAccount, LanguageServerPackageStorageContainers } from './languageServerPackageRepository'; | 
| 20 |  | - | 
| 21 |  | -const downloadBaseFileName = 'Python-Language-Server'; | 
| 22 |  | -export const maxMajorVersion = 0; | 
| 23 |  | -export const PackageNames = { | 
| 24 |  | - [PlatformName.Windows32Bit]: `${downloadBaseFileName}-${PlatformName.Windows32Bit}`, | 
| 25 |  | - [PlatformName.Windows64Bit]: `${downloadBaseFileName}-${PlatformName.Windows64Bit}`, | 
| 26 |  | - [PlatformName.Linux64Bit]: `${downloadBaseFileName}-${PlatformName.Linux64Bit}`, | 
| 27 |  | - [PlatformName.Mac64Bit]: `${downloadBaseFileName}-${PlatformName.Mac64Bit}` | 
| 28 |  | -}; | 
| 29 |  | - | 
| 30 |  | -@injectable() | 
| 31 |  | -export class LanguageServerPackageService implements ILanguageServerPackageService { | 
| 32 |  | - public maxMajorVersion: number = maxMajorVersion; | 
| 33 |  | - constructor(@inject(IServiceContainer) protected readonly serviceContainer: IServiceContainer, | 
| 34 |  | - @inject(IApplicationEnvironment) private readonly appEnv: IApplicationEnvironment, | 
| 35 |  | - @inject(IPlatformService) private readonly platform: IPlatformService) { } | 
| 36 |  | - public getNugetPackageName(): string { | 
| 37 |  | - switch (this.platform.osType) { | 
| 38 |  | - case OSType.Windows: { | 
| 39 |  | - return PackageNames[this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit]; | 
| 40 |  | - } | 
| 41 |  | - case OSType.OSX: { | 
| 42 |  | - return PackageNames[PlatformName.Mac64Bit]; | 
| 43 |  | - } | 
| 44 |  | - default: { | 
| 45 |  | - return PackageNames[PlatformName.Linux64Bit]; | 
| 46 |  | - } | 
| 47 |  | - } | 
| 48 |  | - } | 
| 49 |  | - | 
| 50 |  | - @traceDecorators.verbose('Get latest language server nuget package version') | 
| 51 |  | - public async getLatestNugetPackageVersion(resource: Resource): Promise<NugetPackage> { | 
| 52 |  | - const downloadChannel = this.getLanguageServerDownloadChannel(); | 
| 53 |  | - const nugetRepo = this.serviceContainer.get<INugetRepository>(INugetRepository, downloadChannel); | 
| 54 |  | - const packageName = this.getNugetPackageName(); | 
| 55 |  | - traceVerbose(`Listing packages for ${downloadChannel} for ${packageName}`); | 
| 56 |  | - const packages = await nugetRepo.getPackages(packageName, resource); | 
| 57 |  | - | 
| 58 |  | - return this.getValidPackage(packages); | 
| 59 |  | - } | 
| 60 |  | - | 
| 61 |  | - public getLanguageServerDownloadChannel(): LanguageServerDownloadChannels { | 
| 62 |  | - const configService = this.serviceContainer.get<IConfigurationService>(IConfigurationService); | 
| 63 |  | - const settings = configService.getSettings(); | 
| 64 |  | - if (settings.analysis.downloadChannel) { | 
| 65 |  | - return settings.analysis.downloadChannel; | 
| 66 |  | - } | 
| 67 |  | - | 
| 68 |  | - const isAlphaVersion = this.isAlphaVersionOfExtension(); | 
| 69 |  | - return isAlphaVersion ? 'beta' : 'stable'; | 
| 70 |  | - } | 
| 71 |  | - protected getValidPackage(packages: NugetPackage[]): NugetPackage { | 
| 72 |  | - const nugetService = this.serviceContainer.get<INugetService>(INugetService); | 
| 73 |  | - const validPackages = packages | 
| 74 |  | - .filter(item => item.version.major === this.maxMajorVersion) | 
| 75 |  | - .filter(item => nugetService.isReleaseVersion(item.version)) | 
| 76 |  | - .sort((a, b) => a.version.compare(b.version)); | 
| 77 |  | - | 
| 78 |  | - const pkg = validPackages[validPackages.length - 1]; | 
| 79 |  | - const minimumVersion = this.appEnv.packageJson.languageServerVersion as string; | 
| 80 |  | - if (pkg.version.compare(minimumVersion) >= 0) { | 
| 81 |  | - return validPackages[validPackages.length - 1]; | 
| 82 |  | - } | 
| 83 |  | - | 
| 84 |  | - // This is a fall back, if the wrong version is returned, e.g. version is cached downstream in some proxy server or similar. | 
| 85 |  | - // This way, we always ensure we have the minimum version that's compatible. | 
| 86 |  | - return { | 
| 87 |  | - version: new SemVer(minimumVersion), | 
| 88 |  | - package: LanguageServerPackageStorageContainers.stable, | 
| 89 |  | - uri: `${azureCDNBlobStorageAccount}/${LanguageServerPackageStorageContainers.stable}/${this.getNugetPackageName()}.${minimumVersion}.nupkg` | 
| 90 |  | - }; | 
| 91 |  | - } | 
| 92 |  | - | 
| 93 |  | - private isAlphaVersionOfExtension() { | 
| 94 |  | - const extensions = this.serviceContainer.get<IExtensions>(IExtensions); | 
| 95 |  | - const extension = extensions.getExtension(PVSC_EXTENSION_ID)!; | 
| 96 |  | - const version = parse(extension.packageJSON.version)!; | 
| 97 |  | - return version.prerelease.length > 0 && version.prerelease[0] === 'alpha'; | 
| 98 |  | - } | 
| 99 |  | -} | 
|  | 1 | +// Copyright (c) Microsoft Corporation. All rights reserved. | 
|  | 2 | +// Licensed under the MIT License. | 
|  | 3 | + | 
|  | 4 | +'use strict'; | 
|  | 5 | + | 
|  | 6 | +import { inject, injectable } from 'inversify'; | 
|  | 7 | +import { parse, SemVer } from 'semver'; | 
|  | 8 | +import { IApplicationEnvironment } from '../../common/application/types'; | 
|  | 9 | +import { PVSC_EXTENSION_ID } from '../../common/constants'; | 
|  | 10 | +import { traceDecorators, traceVerbose } from '../../common/logger'; | 
|  | 11 | +import { INugetRepository, INugetService, NugetPackage } from '../../common/nuget/types'; | 
|  | 12 | +import { IPlatformService } from '../../common/platform/types'; | 
|  | 13 | +import { | 
|  | 14 | + IConfigurationService, IExtensions, LanguageServerDownloadChannels, Resource | 
|  | 15 | +} from '../../common/types'; | 
|  | 16 | +import { OSType } from '../../common/utils/platform'; | 
|  | 17 | +import { IServiceContainer } from '../../ioc/types'; | 
|  | 18 | +import { ILanguageServerPackageService, PlatformName } from '../types'; | 
|  | 19 | +import { azureCDNBlobStorageAccount, LanguageServerPackageStorageContainers } from './languageServerPackageRepository'; | 
|  | 20 | + | 
|  | 21 | +const downloadBaseFileName = 'Python-Language-Server'; | 
|  | 22 | +export const maxMajorVersion = 0; | 
|  | 23 | +export const PackageNames = { | 
|  | 24 | + [PlatformName.Windows32Bit]: `${downloadBaseFileName}-${PlatformName.Windows32Bit}`, | 
|  | 25 | + [PlatformName.Windows64Bit]: `${downloadBaseFileName}-${PlatformName.Windows64Bit}`, | 
|  | 26 | + [PlatformName.Linux64Bit]: `${downloadBaseFileName}-${PlatformName.Linux64Bit}`, | 
|  | 27 | + [PlatformName.Mac64Bit]: `${downloadBaseFileName}-${PlatformName.Mac64Bit}` | 
|  | 28 | +}; | 
|  | 29 | + | 
|  | 30 | +@injectable() | 
|  | 31 | +export class LanguageServerPackageService implements ILanguageServerPackageService { | 
|  | 32 | + public maxMajorVersion: number = maxMajorVersion; | 
|  | 33 | + constructor(@inject(IServiceContainer) protected readonly serviceContainer: IServiceContainer, | 
|  | 34 | + @inject(IApplicationEnvironment) private readonly appEnv: IApplicationEnvironment, | 
|  | 35 | + @inject(IPlatformService) private readonly platform: IPlatformService) { } | 
|  | 36 | + public getNugetPackageName(): string { | 
|  | 37 | + switch (this.platform.osType) { | 
|  | 38 | + case OSType.Windows: { | 
|  | 39 | + return PackageNames[this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit]; | 
|  | 40 | + } | 
|  | 41 | + case OSType.OSX: { | 
|  | 42 | + return PackageNames[PlatformName.Mac64Bit]; | 
|  | 43 | + } | 
|  | 44 | + default: { | 
|  | 45 | + return PackageNames[PlatformName.Linux64Bit]; | 
|  | 46 | + } | 
|  | 47 | + } | 
|  | 48 | + } | 
|  | 49 | + | 
|  | 50 | + @traceDecorators.verbose('Get latest language server nuget package version') | 
|  | 51 | + public async getLatestNugetPackageVersion(resource: Resource): Promise<NugetPackage> { | 
|  | 52 | + const downloadChannel = this.getLanguageServerDownloadChannel(); | 
|  | 53 | + const nugetRepo = this.serviceContainer.get<INugetRepository>(INugetRepository, downloadChannel); | 
|  | 54 | + const packageName = this.getNugetPackageName(); | 
|  | 55 | + traceVerbose(`Listing packages for ${downloadChannel} for ${packageName}`); | 
|  | 56 | + const packages = await nugetRepo.getPackages(packageName, resource); | 
|  | 57 | + | 
|  | 58 | + return this.getValidPackage(packages); | 
|  | 59 | + } | 
|  | 60 | + | 
|  | 61 | + public getLanguageServerDownloadChannel(): LanguageServerDownloadChannels { | 
|  | 62 | + const configService = this.serviceContainer.get<IConfigurationService>(IConfigurationService); | 
|  | 63 | + const settings = configService.getSettings(); | 
|  | 64 | + if (settings.analysis.downloadChannel) { | 
|  | 65 | + return settings.analysis.downloadChannel; | 
|  | 66 | + } | 
|  | 67 | + | 
|  | 68 | + if (settings.insidersChannel === 'daily' || settings.insidersChannel === 'weekly') { | 
|  | 69 | + return 'beta'; | 
|  | 70 | + } | 
|  | 71 | + const isAlphaVersion = this.isAlphaVersionOfExtension(); | 
|  | 72 | + return isAlphaVersion ? 'beta' : 'stable'; | 
|  | 73 | + } | 
|  | 74 | + | 
|  | 75 | + public isAlphaVersionOfExtension() { | 
|  | 76 | + const extensions = this.serviceContainer.get<IExtensions>(IExtensions); | 
|  | 77 | + const extension = extensions.getExtension(PVSC_EXTENSION_ID)!; | 
|  | 78 | + const version = parse(extension.packageJSON.version)!; | 
|  | 79 | + return version.prerelease.length > 0 && version.prerelease[0] === 'alpha'; | 
|  | 80 | + } | 
|  | 81 | + protected getValidPackage(packages: NugetPackage[]): NugetPackage { | 
|  | 82 | + const nugetService = this.serviceContainer.get<INugetService>(INugetService); | 
|  | 83 | + const validPackages = packages | 
|  | 84 | + .filter(item => item.version.major === this.maxMajorVersion) | 
|  | 85 | + .filter(item => nugetService.isReleaseVersion(item.version)) | 
|  | 86 | + .sort((a, b) => a.version.compare(b.version)); | 
|  | 87 | + | 
|  | 88 | + const pkg = validPackages[validPackages.length - 1]; | 
|  | 89 | + const minimumVersion = this.appEnv.packageJson.languageServerVersion as string; | 
|  | 90 | + if (pkg.version.compare(minimumVersion) >= 0) { | 
|  | 91 | + return validPackages[validPackages.length - 1]; | 
|  | 92 | + } | 
|  | 93 | + | 
|  | 94 | + // This is a fall back, if the wrong version is returned, e.g. version is cached downstream in some proxy server or similar. | 
|  | 95 | + // This way, we always ensure we have the minimum version that's compatible. | 
|  | 96 | + return { | 
|  | 97 | + version: new SemVer(minimumVersion), | 
|  | 98 | + package: LanguageServerPackageStorageContainers.stable, | 
|  | 99 | + uri: `${azureCDNBlobStorageAccount}/${LanguageServerPackageStorageContainers.stable}/${this.getNugetPackageName()}.${minimumVersion}.nupkg` | 
|  | 100 | + }; | 
|  | 101 | + } | 
|  | 102 | +} | 
0 commit comments