Merge pull request #593 from devchat-ai/config_conda_forge
feat: Add configurable conda-forge URL for Python installation
This commit is contained in:
commit
4e5283556c
@ -2,6 +2,7 @@ import { exec, spawn } from 'child_process';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import { logger } from '../logger';
|
import { logger } from '../logger';
|
||||||
|
import { DevChatConfig } from '../config';
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
// Check if the environment already exists
|
// Check if the environment already exists
|
||||||
@ -96,69 +97,83 @@ function canCreateSubdirectory(dirPath: string): boolean {
|
|||||||
|
|
||||||
|
|
||||||
export async function installPythonMicromamba(mambaCommandPath: string, envName: string, pythonVersion: string): Promise<string> {
|
export async function installPythonMicromamba(mambaCommandPath: string, envName: string, pythonVersion: string): Promise<string> {
|
||||||
// Set the installation directory for conda
|
// Set the installation directory for conda
|
||||||
let userHome = process.platform === 'win32' ? fs.realpathSync(process.env.USERPROFILE || '') : process.env.HOME;
|
let userHome = process.platform === 'win32' ? fs.realpathSync(process.env.USERPROFILE || '') : process.env.HOME;
|
||||||
if (os.platform() === 'win32' && /[^\x00-\xFF]/.test(userHome)) {
|
if (os.platform() === 'win32' && /[^\x00-\xFF]/.test(userHome)) {
|
||||||
if (fs.existsSync('C:/Program Files') && canCreateSubdirectory('C:/Program Files')) {
|
if (fs.existsSync('C:/Program Files') && canCreateSubdirectory('C:/Program Files')) {
|
||||||
userHome = 'C:/Program Files';
|
userHome = 'C:/Program Files';
|
||||||
} else if (fs.existsSync('D:/Program Files') && canCreateSubdirectory('D:/Program Files')) {
|
} else if (fs.existsSync('D:/Program Files') && canCreateSubdirectory('D:/Program Files')) {
|
||||||
userHome = 'D:/Program Files';
|
userHome = 'D:/Program Files';
|
||||||
} else if (fs.existsSync('E:/Program Files') && canCreateSubdirectory('E:/Program Files')) {
|
} else if (fs.existsSync('E:/Program Files') && canCreateSubdirectory('E:/Program Files')) {
|
||||||
userHome = 'E:/Program Files';
|
userHome = 'E:/Program Files';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const pathToMamba = `${userHome}/.chat/mamba`;
|
const pathToMamba = `${userHome}/.chat/mamba`;
|
||||||
|
|
||||||
const envPath = path.resolve(pathToMamba, 'envs', envName);
|
const envPath = path.resolve(pathToMamba, 'envs', envName);
|
||||||
let pythonPath;
|
let pythonPath;
|
||||||
let pythonPath2;
|
let pythonPath2;
|
||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
pythonPath = path.join(envPath, 'Scripts', 'python.exe');
|
pythonPath = path.join(envPath, 'Scripts', 'python.exe');
|
||||||
pythonPath2 = path.join(envPath, 'python.exe');
|
pythonPath2 = path.join(envPath, 'python.exe');
|
||||||
} else {
|
} else {
|
||||||
pythonPath = path.join(envPath, 'bin', 'python');
|
pythonPath = path.join(envPath, 'bin', 'python');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.existsSync(pythonPath)) {
|
if (fs.existsSync(pythonPath)) {
|
||||||
return pythonPath;
|
return pythonPath;
|
||||||
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
|
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
|
||||||
return pythonPath2;
|
return pythonPath2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise<string>((resolve, reject) => {
|
// Get conda-forge URL from config file
|
||||||
const cmd = mambaCommandPath;
|
const condaForgeUrl = getCondaForgeUrl();
|
||||||
const args = ['create', '-n', envName, '-c', 'conda-forge', '-r', pathToMamba, `python=${pythonVersion}`, '--yes'];
|
|
||||||
// output command and args in line
|
return new Promise<string>((resolve, reject) => {
|
||||||
// args to "create -n xx -c conda-forge ..."
|
const cmd = mambaCommandPath;
|
||||||
logger.channel()?.info(`cmd: ${cmd} ${args.join(' ')}`);
|
const args = ['create', '-n', envName, '-c', condaForgeUrl, '-r', pathToMamba, `python=${pythonVersion}`, '--yes'];
|
||||||
const child = spawn(cmd, args);
|
logger.channel()?.info(`cmd: ${cmd} ${args.join(' ')}`);
|
||||||
|
const child = spawn(cmd, args);
|
||||||
child.stdout.on('data', (data) => {
|
|
||||||
logger.channel()?.info(`${data}`);
|
child.stdout.on('data', (data) => {
|
||||||
});
|
logger.channel()?.info(`${data}`);
|
||||||
|
});
|
||||||
child.stderr.on('data', (data) => {
|
|
||||||
console.error(`stderr: ${data}`);
|
child.stderr.on('data', (data) => {
|
||||||
});
|
console.error(`stderr: ${data}`);
|
||||||
|
});
|
||||||
child.on('error', (error) => {
|
|
||||||
logger.channel()?.error(`Error installing python ${pythonVersion} in env ${envName}`);
|
child.on('error', (error) => {
|
||||||
logger.channel()?.show();
|
logger.channel()?.error(`Error installing python ${pythonVersion} in env ${envName}`);
|
||||||
reject('');
|
logger.channel()?.show();
|
||||||
});
|
reject('');
|
||||||
|
});
|
||||||
child.on('close', (code) => {
|
|
||||||
if (code !== 0) {
|
child.on('close', (code) => {
|
||||||
reject(new Error(`Command exited with code ${code}`));
|
if (code !== 0) {
|
||||||
} else {
|
reject(new Error(`Command exited with code ${code}`));
|
||||||
if (fs.existsSync(pythonPath)) {
|
} else {
|
||||||
resolve(pythonPath);
|
if (fs.existsSync(pythonPath)) {
|
||||||
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
|
resolve(pythonPath);
|
||||||
resolve(pythonPath2);
|
} else if (pythonPath2 && fs.existsSync(pythonPath2)) {
|
||||||
} else {
|
resolve(pythonPath2);
|
||||||
reject(new Error(`No Python found`));
|
} else {
|
||||||
}
|
reject(new Error(`No Python found`));
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCondaForgeUrl(): string {
|
||||||
|
const defaultUrl = "https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/";
|
||||||
|
try {
|
||||||
|
const config = DevChatConfig.getInstance();
|
||||||
|
const url = config.get("conda-forge-url", defaultUrl);
|
||||||
|
return url || defaultUrl; // 如果 url 是 undefined 或空字符串,返回默认 URL
|
||||||
|
} catch (error) {
|
||||||
|
logger.channel()?.error(`Error reading conda-forge URL from config: ${error}`);
|
||||||
|
logger.channel()?.show();
|
||||||
|
return defaultUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user