forked from DonJayamanne/pythonVSCode
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathchannelManager.ts
102 lines (94 loc) · 4.3 KB
/
channelManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import { inject, injectable } from 'inversify';
import { Uri } from 'vscode';
import { IInterpreterService } from '../../interpreter/contracts';
import { IServiceContainer } from '../../ioc/types';
import { EnvironmentType } from '../../pythonEnvironments/info';
import { IApplicationShell } from '../application/types';
import { IPlatformService } from '../platform/types';
import { Product } from '../types';
import { Installer } from '../utils/localize';
import { isResource } from '../utils/misc';
import { ProductNames } from './productNames';
import { IInstallationChannelManager, IModuleInstaller, InterpreterUri } from './types';
@injectable()
export class InstallationChannelManager implements IInstallationChannelManager {
constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) {}
public async getInstallationChannel(
product: Product,
resource?: InterpreterUri,
): Promise<IModuleInstaller | undefined> {
const channels = await this.getInstallationChannels(resource);
if (channels.length === 1) {
return channels[0];
}
const productName = ProductNames.get(product)!;
const appShell = this.serviceContainer.get<IApplicationShell>(IApplicationShell);
if (channels.length === 0) {
await this.showNoInstallersMessage(isResource(resource) ? resource : undefined);
return;
}
const placeHolder = `Select an option to install ${productName}`;
const options = channels.map((installer) => {
return {
label: `Install using ${installer.displayName}`,
description: '',
installer,
};
});
const selection = await appShell.showQuickPick<typeof options[0]>(options, {
matchOnDescription: true,
matchOnDetail: true,
placeHolder,
});
return selection ? selection.installer : undefined;
}
public async getInstallationChannels(resource?: InterpreterUri): Promise<IModuleInstaller[]> {
const installers = this.serviceContainer.getAll<IModuleInstaller>(IModuleInstaller);
const supportedInstallers: IModuleInstaller[] = [];
if (installers.length === 0) {
return [];
}
// group by priority and pick supported from the highest priority
installers.sort((a, b) => b.priority - a.priority);
let currentPri = installers[0].priority;
for (const mi of installers) {
if (mi.priority !== currentPri) {
if (supportedInstallers.length > 0) {
break; // return highest priority supported installers
}
// If none supported, try next priority group
currentPri = mi.priority;
}
if (await mi.isSupported(resource)) {
supportedInstallers.push(mi);
}
}
return supportedInstallers;
}
public async showNoInstallersMessage(resource?: Uri): Promise<void> {
const interpreters = this.serviceContainer.get<IInterpreterService>(IInterpreterService);
const interpreter = await interpreters.getActiveInterpreter(resource);
if (!interpreter) {
return; // Handled in the Python installation check.
}
const appShell = this.serviceContainer.get<IApplicationShell>(IApplicationShell);
const search = 'Search for help';
let result: string | undefined;
if (interpreter.envType === EnvironmentType.Conda) {
result = await appShell.showErrorMessage(Installer.noCondaOrPipInstaller, Installer.searchForHelp);
} else {
result = await appShell.showErrorMessage(Installer.noPipInstaller, Installer.searchForHelp);
}
if (result === search) {
const platform = this.serviceContainer.get<IPlatformService>(IPlatformService);
const osName = platform.isWindows ? 'Windows' : platform.isMac ? 'MacOS' : 'Linux';
appShell.openUrl(
`https://www.bing.com/search?q=Install Pip ${osName} ${
interpreter.envType === EnvironmentType.Conda ? 'Conda' : ''
}`,
);
}
}
}