Skip to content

Commit

Permalink
Make sure conda activate is used for micromamba (#20760)
Browse files Browse the repository at this point in the history
Closes #20756
  • Loading branch information
Kartik Raj authored Feb 27, 2023
1 parent 29bee00 commit e624eff
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ import { IPlatformService } from '../../platform/types';
import { IConfigurationService } from '../../types';
import { ITerminalActivationCommandProvider, TerminalShellType } from '../types';

// Version number of conda that requires we call activate with 'conda activate' instead of just 'activate'
const CondaRequiredMajor = 4;
const CondaRequiredMinor = 4;
const CondaRequiredMinorForPowerShell = 6;

/**
* Support conda env activation (in the terminal).
*/
Expand Down Expand Up @@ -65,57 +60,38 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman

const condaEnv = envInfo.name.length > 0 ? envInfo.name : envInfo.path;

// Algorithm differs based on version
// Old version, just call activate directly.
// New version, call activate from the same path as our python path, then call it again to activate our environment.
// -- note that the 'default' conda location won't allow activate to work for the environment sometimes.
const versionInfo = await this.condaService.getCondaVersion();
if (versionInfo && versionInfo.major >= CondaRequiredMajor) {
// Conda added support for powershell in 4.6.
// New version.
const interpreterPath = await this.condaService.getInterpreterPathForEnvironment(envInfo);
const activatePath = await this.condaService.getActivationScriptFromInterpreter(interpreterPath, envInfo.name);
// eslint-disable-next-line camelcase
if (activatePath?.path) {
if (
versionInfo.minor >= CondaRequiredMinorForPowerShell &&
(targetShell === TerminalShellType.powershell || targetShell === TerminalShellType.powershellCore)
this.platform.isWindows &&
targetShell !== TerminalShellType.bash &&
targetShell !== TerminalShellType.gitbash
) {
return _getPowershellCommands(condaEnv);
return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
}
if (versionInfo.minor >= CondaRequiredMinor) {
// New version.
const interpreterPath = await this.condaService.getInterpreterPathForEnvironment(envInfo);
const activatePath = await this.condaService.getActivationScriptFromInterpreter(
interpreterPath,
envInfo.name,
);

const condaInfo = await this.condaService.getCondaInfo();

if (
activatePath.type !== 'global' ||
// eslint-disable-next-line camelcase
if (activatePath?.path) {
if (
this.platform.isWindows &&
targetShell !== TerminalShellType.bash &&
targetShell !== TerminalShellType.gitbash
) {
return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
}

const condaInfo = await this.condaService.getCondaInfo();

if (
activatePath.type !== 'global' ||
// eslint-disable-next-line camelcase
condaInfo?.conda_shlvl === undefined ||
condaInfo.conda_shlvl === -1
) {
// activatePath is not the global activate path, or we don't have a shlvl, or it's -1(conda never sourced).
// and we need to source the activate path.
if (activatePath.path === 'activate') {
return [
`source ${activatePath.path}`,
`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`,
];
}
return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`];
}
return [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
condaInfo?.conda_shlvl === undefined ||
condaInfo.conda_shlvl === -1
) {
// activatePath is not the global activate path, or we don't have a shlvl, or it's -1(conda never sourced).
// and we need to source the activate path.
if (activatePath.path === 'activate') {
return [
`source ${activatePath.path}`,
`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`,
];
}
return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonExt()}`];
}
return [`conda activate ${condaEnv.toCommandArgumentForPythonExt()}`];
}

switch (targetShell) {
Expand Down
34 changes: 0 additions & 34 deletions src/test/common/terminals/activation.conda.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import { expect } from 'chai';
import * as path from 'path';
import { parse } from 'semver';
import { anything, instance, mock, when } from 'ts-mockito';
import * as TypeMoq from 'typemoq';
import { Disposable } from 'vscode';
Expand Down Expand Up @@ -145,37 +144,6 @@ suite('Terminal Environment Activation conda', () => {
expect(activationCommands).to.deep.equal(expected, 'Incorrect Activation command');
});

test('Conda activation on bash uses "source" before 4.4.0', async () => {
const envName = 'EnvA';
const pythonPath = 'python3';
const condaPath = path.join('a', 'b', 'c', 'conda');
platformService.setup((p) => p.isWindows).returns(() => false);
condaService.reset();
componentAdapter
.setup((c) => c.getCondaEnvironment(TypeMoq.It.isAny()))
.returns(() =>
Promise.resolve({
name: envName,
path: path.dirname(pythonPath),
}),
);
condaService.setup((c) => c.getCondaFile()).returns(() => Promise.resolve(condaPath));
condaService.setup((c) => c.getCondaVersion()).returns(() => Promise.resolve(parse('4.3.1', true)!));
const expected = [
`source ${path.join(path.dirname(condaPath), 'activate').fileToCommandArgumentForPythonExt()} EnvA`,
];

const provider = new CondaActivationCommandProvider(
condaService.object,
platformService.object,
configService.object,
componentAdapter.object,
);
const activationCommands = await provider.getActivationCommands(undefined, TerminalShellType.bash);

expect(activationCommands).to.deep.equal(expected, 'Incorrect Activation command');
});

test('Conda activation on bash uses "conda" after 4.4.0', async () => {
const envName = 'EnvA';
const pythonPath = 'python3';
Expand All @@ -191,7 +159,6 @@ suite('Terminal Environment Activation conda', () => {
}),
);
condaService.setup((c) => c.getCondaFile()).returns(() => Promise.resolve(condaPath));
condaService.setup((c) => c.getCondaVersion()).returns(() => Promise.resolve(parse('4.4.0', true)!));
const expected = [
`source ${path.join(path.dirname(condaPath), 'activate').fileToCommandArgumentForPythonExt()} EnvA`,
];
Expand Down Expand Up @@ -308,7 +275,6 @@ suite('Terminal Environment Activation conda', () => {
path: path.dirname(pythonPath),
}),
);
condaService.setup((c) => c.getCondaVersion()).returns(() => Promise.resolve(parse('4.4.0', true)!));
condaService
.setup((c) => c.getCondaFileFromInterpreter(TypeMoq.It.isAny(), TypeMoq.It.isAny()))
.returns(() => Promise.resolve(interpreterPath));
Expand Down

0 comments on commit e624eff

Please sign in to comment.