Skip to content

Commit d0c07e4

Browse files
authored
add in version selection for conda env creation (#760)
fixes #733
1 parent 33e2a79 commit d0c07e4

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

src/managers/conda/condaUtils.ts

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,52 @@ async function getLocation(api: PythonEnvironmentApi, uris: Uri | Uri[]): Promis
733733
}
734734
return api.getPythonProject(Array.isArray(uris) ? uris[0] : uris)?.uri.fsPath;
735735
}
736+
const RECOMMENDED_CONDA_PYTHON = '3.11.11';
737+
738+
function trimVersionToMajorMinor(version: string): string {
739+
const match = version.match(/^(\d+\.\d+\.\d+)/);
740+
return match ? match[1] : version;
741+
}
742+
743+
export async function pickPythonVersion(
744+
api: PythonEnvironmentApi,
745+
token?: CancellationToken,
746+
): Promise<string | undefined> {
747+
const envs = await api.getEnvironments('global');
748+
let versions = Array.from(
749+
new Set(
750+
envs
751+
.map((env) => env.version)
752+
.filter(Boolean)
753+
.map((v) => trimVersionToMajorMinor(v)), // cut to 3 digits
754+
),
755+
)
756+
.sort()
757+
.reverse();
758+
if (!versions) {
759+
versions = ['3.11', '3.10', '3.9', '3.12', '3.13'];
760+
}
761+
const items: QuickPickItem[] = versions.map((v) => ({
762+
label: v === RECOMMENDED_CONDA_PYTHON ? `$(star-full) Python` : 'Python',
763+
description: v,
764+
}));
765+
const selection = await showQuickPickWithButtons(
766+
items,
767+
{
768+
placeHolder: l10n.t('Select the version of Python to install in the environment'),
769+
matchOnDescription: true,
770+
ignoreFocusOut: true,
771+
showBackButton: true,
772+
},
773+
token,
774+
);
775+
776+
if (selection) {
777+
return (selection as QuickPickItem).description;
778+
}
779+
780+
return undefined;
781+
}
736782

737783
export async function createCondaEnvironment(
738784
api: PythonEnvironmentApi,
@@ -757,10 +803,11 @@ export async function createCondaEnvironment(
757803
)
758804
)?.label;
759805

806+
const pythonVersion = await pickPythonVersion(api);
760807
if (envType) {
761808
return envType === CondaStrings.condaNamed
762-
? await createNamedCondaEnvironment(api, log, manager, getName(api, uris ?? []))
763-
: await createPrefixCondaEnvironment(api, log, manager, await getLocation(api, uris ?? []));
809+
? await createNamedCondaEnvironment(api, log, manager, getName(api, uris ?? []), pythonVersion)
810+
: await createPrefixCondaEnvironment(api, log, manager, await getLocation(api, uris ?? []), pythonVersion);
764811
}
765812
return undefined;
766813
}
@@ -770,6 +817,7 @@ async function createNamedCondaEnvironment(
770817
log: LogOutputChannel,
771818
manager: EnvironmentManager,
772819
name?: string,
820+
pythonVersion?: string,
773821
): Promise<PythonEnvironment | undefined> {
774822
name = await showInputBox({
775823
prompt: CondaStrings.condaNamedInput,
@@ -781,6 +829,12 @@ async function createNamedCondaEnvironment(
781829
}
782830

783831
const envName: string = name;
832+
const runArgs = ['create', '--yes', '--name', envName];
833+
if (pythonVersion) {
834+
runArgs.push(`python=${pythonVersion}`);
835+
} else {
836+
runArgs.push('python');
837+
}
784838

785839
return await withProgress(
786840
{
@@ -790,7 +844,7 @@ async function createNamedCondaEnvironment(
790844
async () => {
791845
try {
792846
const bin = os.platform() === 'win32' ? 'python.exe' : 'python';
793-
const output = await runCondaExecutable(['create', '--yes', '--name', envName, 'python']);
847+
const output = await runCondaExecutable(runArgs);
794848
log.info(output);
795849

796850
const prefixes = await getPrefixes();
@@ -830,6 +884,7 @@ async function createPrefixCondaEnvironment(
830884
log: LogOutputChannel,
831885
manager: EnvironmentManager,
832886
fsPath?: string,
887+
pythonVersion?: string,
833888
): Promise<PythonEnvironment | undefined> {
834889
if (!fsPath) {
835890
return;
@@ -856,6 +911,13 @@ async function createPrefixCondaEnvironment(
856911

857912
const prefix: string = path.isAbsolute(name) ? name : path.join(fsPath, name);
858913

914+
const runArgs = ['create', '--yes', '--prefix', prefix];
915+
if (pythonVersion) {
916+
runArgs.push(`python=${pythonVersion}`);
917+
} else {
918+
runArgs.push('python');
919+
}
920+
859921
return await withProgress(
860922
{
861923
location: ProgressLocation.Notification,
@@ -864,7 +926,7 @@ async function createPrefixCondaEnvironment(
864926
async () => {
865927
try {
866928
const bin = os.platform() === 'win32' ? 'python.exe' : 'python';
867-
const output = await runCondaExecutable(['create', '--yes', '--prefix', prefix, 'python']);
929+
const output = await runCondaExecutable(runArgs);
868930
log.info(output);
869931
const version = await getVersion(prefix);
870932

0 commit comments

Comments
 (0)