public async install()

in src/client/common/installer/productInstaller.ts [405:530]


    public async install(
        product: Product,
        interpreterUri?: InterpreterUri,
        cancel?: CancellationToken,
        flags?: ModuleInstallFlags,
    ): Promise<InstallerResponse> {
        // Precondition
        if (isResource(interpreterUri)) {
            throw new Error('All data science packages require an interpreter be passed in');
        }

        // At this point we know that `interpreterUri` is of type PythonInterpreter
        const interpreter = interpreterUri as PythonEnvironment;

        // Get a list of known installation channels, pip, conda, etc.
        let channels: IModuleInstaller[] = await this.serviceContainer
            .get<IInstallationChannelManager>(IInstallationChannelManager)
            .getInstallationChannels(interpreter);

        // Pick an installerModule based on whether the interpreter is conda or not. Default is pip.
        const moduleName = translateProductToModule(product);
        const version = `${interpreter.version?.major || ''}.${interpreter.version?.minor || ''}.${
            interpreter.version?.patch || ''
        }`;

        // If this is a non-conda environment & pip isn't installed, we need to install pip.
        // The prompt would have been disabled prior to this point, so we can assume that.
        if (
            flags &&
            flags & ModuleInstallFlags.installPipIfRequired &&
            interpreter.envType !== EnvironmentType.Conda &&
            !channels.some((channel) => channel.type === ModuleInstallerType.Pip)
        ) {
            const installers = this.serviceContainer.getAll<IModuleInstaller>(IModuleInstaller);
            const pipInstaller = installers.find((installer) => installer.type === ModuleInstallerType.Pip);
            if (pipInstaller) {
                traceInfo(`Installing pip as its not available to install ${moduleName}.`);
                await pipInstaller
                    .installModule(Product.pip, interpreter, cancel)
                    .catch((ex) =>
                        traceError(
                            `Error in installing the module '${moduleName} as Pip could not be installed', ${ex}`,
                        ),
                    );

                await this.isInstalled(Product.pip, interpreter)
                    .then((isInstalled) => {
                        sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, {
                            installer: pipInstaller.displayName,
                            requiredInstaller: ModuleInstallerType.Pip,
                            version,
                            envType: interpreter.envType,
                            isInstalled,
                            productName: ProductNames.get(Product.pip),
                        });
                    })
                    .catch(noop);

                // Refresh the list of channels (pip may be avaialble now).
                channels = await this.serviceContainer
                    .get<IInstallationChannelManager>(IInstallationChannelManager)
                    .getInstallationChannels(interpreter);
            } else {
                sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, {
                    installer: 'unavailable',
                    requiredInstaller: ModuleInstallerType.Pip,
                    productName: ProductNames.get(Product.pip),
                    version,
                    envType: interpreter.envType,
                });
                traceError(`Unable to install pip when its required.`);
            }
        }

        const isAvailableThroughConda = !UnsupportedChannelsForProduct.get(product)?.has(EnvironmentType.Conda);
        let requiredInstaller = ModuleInstallerType.Unknown;
        if (interpreter.envType === EnvironmentType.Conda && isAvailableThroughConda) {
            requiredInstaller = ModuleInstallerType.Conda;
        } else if (interpreter.envType === EnvironmentType.Conda && !isAvailableThroughConda) {
            // This case is temporary and can be removed when https://github.com/microsoft/vscode-jupyter/issues/5034 is unblocked
            traceInfo(
                `Interpreter type is conda but package ${moduleName} is not available through conda, using pip instead.`,
            );
            requiredInstaller = ModuleInstallerType.Pip;
        } else {
            switch (interpreter.envType) {
                case EnvironmentType.Pipenv:
                    requiredInstaller = ModuleInstallerType.Pipenv;
                    break;
                case EnvironmentType.Poetry:
                    requiredInstaller = ModuleInstallerType.Poetry;
                    break;
                default:
                    requiredInstaller = ModuleInstallerType.Pip;
            }
        }
        const installerModule: IModuleInstaller | undefined = channels.find((v) => v.type === requiredInstaller);

        if (!installerModule) {
            this.appShell.showErrorMessage(Installer.couldNotInstallLibrary().format(moduleName)).then(noop, noop);
            sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, {
                installer: 'unavailable',
                requiredInstaller,
                productName: ProductNames.get(product),
                version,
                envType: interpreter.envType,
            });
            return InstallerResponse.Ignore;
        }

        await installerModule
            .installModule(product, interpreter, cancel, flags)
            .catch((ex) => traceError(`Error in installing the module '${moduleName}', ${ex}`));

        return this.isInstalled(product, interpreter).then((isInstalled) => {
            sendTelemetryEvent(EventName.PYTHON_INSTALL_PACKAGE, undefined, {
                installer: installerModule.displayName || '',
                requiredInstaller,
                version,
                envType: interpreter.envType,
                isInstalled,
                productName: ProductNames.get(product),
            });
            return isInstalled ? InstallerResponse.Installed : InstallerResponse.Ignore;
        });
    }