Skip to content

Commit 68c0333

Browse files
author
David Kutugata
authored
auto detect environment when installing jupyter (microsoft#6629)
* instead of asking the user to select an installer, we now autodetect the environment being used, and use that installer. * added comments and a constant for a product name * changed errorHandler to use the installer with most priority, fixed channelManager so it returns the highest priority installer, increased the priority of the conda installer to 1 * updated the condaInstaller unit tests and changed channel manager to return all supported installers. * Added InstrallerNames.ts with an enum and a Map to help identify the installers used by the extension. Also updated all installers to use it. And returned channel Manager to work as it used to. * removed installerNames.ts and added 'name' to the IModuleInstaller, to be able to use it in code to identify the different installers.
1 parent 13ea009 commit 68c0333

File tree

10 files changed

+42
-7
lines changed

10 files changed

+42
-7
lines changed

news/1 Enhancements/6569.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
instead of asking the user to select an installer, we now autodetect the environment being used, and use that installer.

src/client/common/installer/condaInstaller.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export class CondaInstaller extends ModuleInstaller implements IModuleInstaller
2222
super(serviceContainer);
2323
}
2424

25+
public get name(): string {
26+
return 'Conda';
27+
}
28+
2529
public get displayName() {
2630
return 'Conda';
2731
}

src/client/common/installer/moduleInstaller.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { noop } from '../utils/misc';
1616

1717
@injectable()
1818
export abstract class ModuleInstaller {
19+
public abstract get name(): string;
1920
public abstract get displayName(): string
2021
constructor(protected serviceContainer: IServiceContainer) { }
2122
public async installModule(name: string, resource?: vscode.Uri): Promise<void> {

src/client/common/installer/pipEnvInstaller.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ export const pipenvName = 'pipenv';
1515
export class PipEnvInstaller extends ModuleInstaller implements IModuleInstaller {
1616
private readonly pipenv: IInterpreterLocatorService;
1717

18+
public get name(): string {
19+
return 'pipenv';
20+
}
21+
1822
public get displayName() {
1923
return pipenvName;
2024
}

src/client/common/installer/pipInstaller.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import { IModuleInstaller } from './types';
1212

1313
@injectable()
1414
export class PipInstaller extends ModuleInstaller implements IModuleInstaller {
15+
public get name(): string {
16+
return 'Pip';
17+
}
18+
1519
public get displayName() {
1620
return 'Pip';
1721
}

src/client/common/installer/poetryInstaller.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const poetryFile = 'poetry.lock';
2020
@injectable()
2121
export class PoetryInstaller extends ModuleInstaller implements IModuleInstaller {
2222

23+
public get name(): string {
24+
return 'poetry';
25+
}
26+
2327
public get displayName() {
2428
return poetryName;
2529
}

src/client/common/installer/serviceRegistry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { InsidersBuildInstaller, StableBuildInstaller } from './extensionBuildIn
1212
import { PipEnvInstaller } from './pipEnvInstaller';
1313
import { PipInstaller } from './pipInstaller';
1414
import { PoetryInstaller } from './poetryInstaller';
15-
import { CTagsProductPathService, FormatterProductPathService, LinterProductPathService, RefactoringLibraryProductPathService, TestFrameworkProductPathService, DataScienceProductPathService } from './productPath';
15+
import { CTagsProductPathService, DataScienceProductPathService, FormatterProductPathService, LinterProductPathService, RefactoringLibraryProductPathService, TestFrameworkProductPathService } from './productPath';
1616
import { ProductService } from './productService';
1717
import { IExtensionBuildInstaller, IInstallationChannelManager, IModuleInstaller, INSIDERS_INSTALLER, IProductPathService, IProductService, STABLE_INSTALLER } from './types';
1818

src/client/common/installer/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Product, ProductType } from '../types';
66

77
export const IModuleInstaller = Symbol('IModuleInstaller');
88
export interface IModuleInstaller {
9+
readonly name: string;
910
readonly displayName: string;
1011
readonly priority: number;
1112
installModule(name: string, resource?: Uri): Promise<void>;

src/client/datascience/errorHandler/errorHandler.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33
import { inject, injectable } from 'inversify';
44
import { IApplicationShell } from '../../common/application/types';
5+
import { ProductNames } from '../../common/installer/productNames';
56
import { IInstallationChannelManager } from '../../common/installer/types';
67
import { ILogger, Product } from '../../common/types';
78
import * as localize from '../../common/utils/localize';
@@ -25,7 +26,22 @@ export class DataScienceErrorHandler implements IDataScienceErrorHandler {
2526
localize.DataScience.notebookCheckForImportNo())
2627
.then(response => {
2728
if (response === localize.DataScience.jupyterInstall()) {
28-
return this.channels.getInstallationChannel(Product.jupyter);
29+
return this.channels.getInstallationChannels()
30+
.then(installers => {
31+
if (installers) {
32+
// If Conda is available, always pick it as the user must have a Conda Environment
33+
const installer = installers.find(ins => ins.name === 'Conda');
34+
const product = ProductNames.get(Product.jupyter);
35+
36+
if (installer && product) {
37+
installer.installModule(product)
38+
.catch(e => this.applicationShell.showErrorMessage(e.message, localize.DataScience.pythonInteractiveHelpLink()));
39+
} else if (installers[0] && product) {
40+
installers[0].installModule(product)
41+
.catch(e => this.applicationShell.showErrorMessage(e.message, localize.DataScience.pythonInteractiveHelpLink()));
42+
}
43+
}
44+
});
2945
} else {
3046
const jupyterError = err as JupyterInstallError;
3147

@@ -37,11 +53,6 @@ export class DataScienceErrorHandler implements IDataScienceErrorHandler {
3753
}
3854
});
3955
}
40-
}).then(installer => {
41-
if (installer) {
42-
installer.installModule('jupyter')
43-
.catch(e => this.applicationShell.showErrorMessage(e.message, localize.DataScience.pythonInteractiveHelpLink()));
44-
}
4556
});
4657
} else if (err instanceof JupyterSelfCertsError) {
4758
// Don't show the message for self cert errors

src/test/mocks/moduleInstaller.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ export class MockModuleInstaller extends EventEmitter implements IModuleInstalle
66
constructor(public readonly displayName: string, private supported: boolean) {
77
super();
88
}
9+
10+
public get name(): string {
11+
return 'mock';
12+
}
13+
914
public get priority(): number {
1015
return 0;
1116
}

0 commit comments

Comments
 (0)