cvm-cli
Version:
A unified CLI tool for managing PHP, Node.js, and Python versions with virtual environment and dependency management support.
157 lines (132 loc) • 3.58 kB
JavaScript
const fs = require('fs-extra');
const path = require('path');
const os = require('os');
const { spawn, exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);
const CVM_HOME = path.join(os.homedir(), '.cvm');
class CVMUtils {
static getCVMHome() {
return CVM_HOME;
}
static getConfigPath() {
return path.join(CVM_HOME, 'config', 'config.json');
}
static async loadConfig() {
try {
const configPath = this.getConfigPath();
if (await fs.pathExists(configPath)) {
return await fs.readJson(configPath);
}
return this.getDefaultConfig();
} catch (error) {
return this.getDefaultConfig();
}
}
static async saveConfig(config) {
const configPath = this.getConfigPath();
await fs.ensureDir(path.dirname(configPath));
await fs.writeJson(configPath, config, { spaces: 2 });
}
static getDefaultConfig() {
return {
currentVersions: {
php: null,
node: null,
python: null
},
environments: {},
activeEnvironment: null
};
}
static getLanguageDir(language) {
return path.join(CVM_HOME, language);
}
static getVersionDir(language, version) {
return path.join(this.getLanguageDir(language), version);
}
static getEnvironmentsDir() {
return path.join(CVM_HOME, 'environments');
}
static getEnvironmentDir(name) {
return path.join(this.getEnvironmentsDir(), name);
}
static async execCommand(command, options = {}) {
return new Promise((resolve, reject) => {
const child = spawn(command, [], {
shell: true,
stdio: options.silent ? 'pipe' : 'inherit',
...options
});
let stdout = '';
let stderr = '';
if (options.silent && child.stdout) {
child.stdout.on('data', (data) => {
stdout += data.toString();
});
}
if (options.silent && child.stderr) {
child.stderr.on('data', (data) => {
stderr += data.toString();
});
}
child.on('close', (code) => {
if (code === 0) {
resolve({ stdout, stderr, code });
} else {
reject(new Error(`Command failed with exit code ${code}: ${stderr}`));
}
});
child.on('error', (error) => {
reject(error);
});
});
}
static async isVersionInstalled(language, version) {
const versionDir = this.getVersionDir(language, version);
return await fs.pathExists(versionDir);
}
static async getInstalledVersions(language) {
const languageDir = this.getLanguageDir(language);
if (!await fs.pathExists(languageDir)) {
return [];
}
const items = await fs.readdir(languageDir);
const versions = [];
for (const item of items) {
const itemPath = path.join(languageDir, item);
const stat = await fs.stat(itemPath);
if (stat.isDirectory()) {
versions.push(item);
}
}
return versions.sort();
}
static getPlatform() {
const platform = os.platform();
switch (platform) {
case 'darwin':
return 'macos';
case 'win32':
return 'windows';
case 'linux':
return 'linux';
default:
return platform;
}
}
static getArch() {
const arch = os.arch();
switch (arch) {
case 'x64':
return 'x64';
case 'arm64':
return 'arm64';
case 'ia32':
return 'x86';
default:
return arch;
}
}
}
module.exports = CVMUtils;