Skip to content

Commit 429f523

Browse files
committed
feat: Add configurable conda-forge URL for Python installation
- Implement getCondaForgeUrl function to fetch URL from config - Use configurable URL in Python installation process - Add error handling and fallback to default URL if needed
1 parent d2b6ff4 commit 429f523

File tree

1 file changed

+78
-63
lines changed

1 file changed

+78
-63
lines changed

src/util/python_installer/python_install.ts

Lines changed: 78 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { exec, spawn } from 'child_process';
22
import * as path from 'path';
33
import * as os from 'os';
44
import { logger } from '../logger';
5+
import { DevChatConfig } from '../config';
56
const fs = require('fs');
67

78
// Check if the environment already exists
@@ -96,69 +97,83 @@ function canCreateSubdirectory(dirPath: string): boolean {
9697

9798

9899
export async function installPythonMicromamba(mambaCommandPath: string, envName: string, pythonVersion: string): Promise<string> {
99-
// Set the installation directory for conda
100+
// Set the installation directory for conda
100101
let userHome = process.platform === 'win32' ? fs.realpathSync(process.env.USERPROFILE || '') : process.env.HOME;
101-
if (os.platform() === 'win32' && /[^\x00-\xFF]/.test(userHome)) {
102-
if (fs.existsSync('C:/Program Files') && canCreateSubdirectory('C:/Program Files')) {
103-
userHome = 'C:/Program Files';
104-
} else if (fs.existsSync('D:/Program Files') && canCreateSubdirectory('D:/Program Files')) {
105-
userHome = 'D:/Program Files';
106-
} else if (fs.existsSync('E:/Program Files') && canCreateSubdirectory('E:/Program Files')) {
107-
userHome = 'E:/Program Files';
108-
}
109-
}
102+
if (os.platform() === 'win32' && /[^\x00-\xFF]/.test(userHome)) {
103+
if (fs.existsSync('C:/Program Files') && canCreateSubdirectory('C:/Program Files')) {
104+
userHome = 'C:/Program Files';
105+
} else if (fs.existsSync('D:/Program Files') && canCreateSubdirectory('D:/Program Files')) {
106+
userHome = 'D:/Program Files';
107+
} else if (fs.existsSync('E:/Program Files') && canCreateSubdirectory('E:/Program Files')) {
108+
userHome = 'E:/Program Files';
109+
}
110+
}
110111
const pathToMamba = `${userHome}/.chat/mamba`;
111112

112-
const envPath = path.resolve(pathToMamba, 'envs', envName);
113-
let pythonPath;
114-
let pythonPath2;
115-
if (os.platform() === 'win32') {
116-
pythonPath = path.join(envPath, 'Scripts', 'python.exe');
117-
pythonPath2 = path.join(envPath, 'python.exe');
118-
} else {
119-
pythonPath = path.join(envPath, 'bin', 'python');
120-
}
121-
122-
if (fs.existsSync(pythonPath)) {
123-
return pythonPath;
124-
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
125-
return pythonPath2;
126-
}
127-
128-
return new Promise<string>((resolve, reject) => {
129-
const cmd = mambaCommandPath;
130-
const args = ['create', '-n', envName, '-c', 'conda-forge', '-r', pathToMamba, `python=${pythonVersion}`, '--yes'];
131-
// output command and args in line
132-
// args to "create -n xx -c conda-forge ..."
133-
logger.channel()?.info(`cmd: ${cmd} ${args.join(' ')}`);
134-
const child = spawn(cmd, args);
135-
136-
child.stdout.on('data', (data) => {
137-
logger.channel()?.info(`${data}`);
138-
});
139-
140-
child.stderr.on('data', (data) => {
141-
console.error(`stderr: ${data}`);
142-
});
143-
144-
child.on('error', (error) => {
145-
logger.channel()?.error(`Error installing python ${pythonVersion} in env ${envName}`);
146-
logger.channel()?.show();
147-
reject('');
148-
});
149-
150-
child.on('close', (code) => {
151-
if (code !== 0) {
152-
reject(new Error(`Command exited with code ${code}`));
153-
} else {
154-
if (fs.existsSync(pythonPath)) {
155-
resolve(pythonPath);
156-
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
157-
resolve(pythonPath2);
158-
} else {
159-
reject(new Error(`No Python found`));
160-
}
161-
}
162-
});
163-
});
164-
}
113+
const envPath = path.resolve(pathToMamba, 'envs', envName);
114+
let pythonPath;
115+
let pythonPath2;
116+
if (os.platform() === 'win32') {
117+
pythonPath = path.join(envPath, 'Scripts', 'python.exe');
118+
pythonPath2 = path.join(envPath, 'python.exe');
119+
} else {
120+
pythonPath = path.join(envPath, 'bin', 'python');
121+
}
122+
123+
if (fs.existsSync(pythonPath)) {
124+
return pythonPath;
125+
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
126+
return pythonPath2;
127+
}
128+
129+
// Get conda-forge URL from config file
130+
const condaForgeUrl = getCondaForgeUrl();
131+
132+
return new Promise<string>((resolve, reject) => {
133+
const cmd = mambaCommandPath;
134+
const args = ['create', '-n', envName, '-c', condaForgeUrl, '-r', pathToMamba, `python=${pythonVersion}`, '--yes'];
135+
logger.channel()?.info(`cmd: ${cmd} ${args.join(' ')}`);
136+
const child = spawn(cmd, args);
137+
138+
child.stdout.on('data', (data) => {
139+
logger.channel()?.info(`${data}`);
140+
});
141+
142+
child.stderr.on('data', (data) => {
143+
console.error(`stderr: ${data}`);
144+
});
145+
146+
child.on('error', (error) => {
147+
logger.channel()?.error(`Error installing python ${pythonVersion} in env ${envName}`);
148+
logger.channel()?.show();
149+
reject('');
150+
});
151+
152+
child.on('close', (code) => {
153+
if (code !== 0) {
154+
reject(new Error(`Command exited with code ${code}`));
155+
} else {
156+
if (fs.existsSync(pythonPath)) {
157+
resolve(pythonPath);
158+
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
159+
resolve(pythonPath2);
160+
} else {
161+
reject(new Error(`No Python found`));
162+
}
163+
}
164+
});
165+
});
166+
}
167+
168+
export function getCondaForgeUrl(): string {
169+
const defaultUrl = "https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/";
170+
try {
171+
const config = DevChatConfig.getInstance();
172+
const url = config.get("conda-forge-url", defaultUrl);
173+
return url || defaultUrl; // 如果 url 是 undefined 或空字符串,返回默认 URL
174+
} catch (error) {
175+
logger.channel()?.error(`Error reading conda-forge URL from config: ${error}`);
176+
logger.channel()?.show();
177+
return defaultUrl;
178+
}
179+
}

0 commit comments

Comments
 (0)