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