diff --git a/python-ts/main.ts b/python-ts/main.ts index b06d4e9..73de749 100644 --- a/python-ts/main.ts +++ b/python-ts/main.ts @@ -16,8 +16,8 @@ const PYTHON_CONFIG_FILE = "~/.config/python-config.json"; const PYTHON_VENV_DEFAULT_BASE_DIR = "~/.venv/"; interface PythonConfig { - default_version?: string; - default_profile?: string; + // default_version?: string; + // default_profile?: string; python_venv_base_path?: string; versions: Map; profiles?: Map; @@ -64,34 +64,37 @@ async function findVirtualEnv(pythonVenvVersion: string): Promise { return pythonVenv; } -async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) { +async function addVirtualEnv(pythonVersion: string | null, pythonVenv: string) { const pythonConfig = await loadPythonConfig(); - const selectedPythonVersion = pythonVersion || - pythonConfig.default_version || null; - if (!selectedPythonVersion) { + if (!pythonVersion) { throw `No Python version assigned.`; } - if (!selectedPythonVersion) { + if (!pythonVenv) { throw `No Python venv assigned.`; } const pythonVersionProfile = pythonConfig.versions[pythonVersion]; if (!pythonVersionProfile) { throw `Python version: ${pythonVersion} not found`; } - log.success(`Found Python version: ${pythonVersion}`); - const pythonVenvProfile = pythonConfig.profiles[pythonVenv]; + const realPythonVersion = pythonVersionProfile.version || pythonVersion; + log.success( + `Found Python version: ${realPythonVersion}`, + ); + const pythonVenvProfile = pythonConfig.profiles && + pythonConfig.profiles[pythonVenv]; if (pythonVenvProfile) { throw `Python venv already exists: ${pythonVenv}`; } const pythonVenvBaseDir = resolveFilename( pythonConfig.python_venv_base_path || PYTHON_VENV_DEFAULT_BASE_DIR, ); - if (!existsPath(pythonVenvBaseDir)) { + if (!await existsPath(pythonVenvBaseDir)) { log.info(`Make python venv base dir: ${pythonVenvBaseDir}`); Deno.mkdirSync(pythonVenvBaseDir); } - const pythonVenvDir = joinPath(pythonVenvBaseDir, pythonVenv); - if (existsPath(pythonVenvDir)) { + const pythonVenvLeafDir = `${pythonVenv}_python_${realPythonVersion}`; + const pythonVenvDir = joinPath(pythonVenvBaseDir, pythonVenvLeafDir); + if (await existsPath(pythonVenvDir)) { throw `Python venv: ${pythonVenvDir} already exists`; } @@ -100,10 +103,19 @@ async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) { log.success(`Found Python: ${python3Cmd}`); const pythonVenvArgs = ["-m", "venv", pythonVenvDir]; - log.info( - `Create Python venv, python: ${python3Cmd}, args: ${pythonVenvArgs}`, - ); + log.info("Create Python venv, python:", [python3Cmd, pythonVenvArgs]); await execCommandShell(python3Cmd, pythonVenvArgs); + + const newPythonVenvProfile: PythonVenv = { + version: realPythonVersion, + path: pythonVenvDir, + comment: `Python venv:${pythonVenv}, version: ${realPythonVersion}`, + }; + if (!pythonConfig.profiles) { + pythonConfig.profiles = {}; + } + pythonConfig.profiles[pythonVenv] = newPythonVenvProfile; + await savePythonConfig(pythonConfig); } async function isFile(path: string): Promise { @@ -118,7 +130,8 @@ function handleHelp(_args: string[]) { python.ts python - management python version [alias: py] python.ts add-python - add python version [alias: py] -python.ts venv - management python virtual environment`, +python.ts venv - management python virtual environment +python.ts add-venv - add python virtual environment`, ); // source <(cat ~/.venv-python-3.13.5/bin/activate) // source <(python.ts venv test1) @@ -246,35 +259,84 @@ async function handleAddPython(args: string[]) { } async function handleVenv(args: string[]) { - const flags = parseArgs(Deno.args, { + const flags = parseArgs(args, { boolean: ["help"], - string: ["version"], + string: ["name"], + alias: { + n: "name", + }, + }); + if (flags.help) { + console.log(`Help massage for venv + +python.ts venv [--name|-n filter-name]`); + return; + } + let pythonConfig = await loadPythonConfig(); + + if (!pythonConfig.profiles) { + console.warn("No Python virtual environments found"); + return; + } + + let totalProfilesCount = 0; + let filterProfilesCount = 0; + Object.entries(pythonConfig.profiles).forEach( + ([venv, pythonVenvProfile]) => { + totalProfilesCount++; + if (flags.name && venv.indexOf(flags.name) < 0) { + return; + } + filterProfilesCount++; + console.log("-", venv, pythonVenvProfile); + }, + ); + + if (totalProfilesCount !== filterProfilesCount) { + console.log( + `\nFilter profiles with '${flags.name}': ${filterProfilesCount} of ${totalProfilesCount}`, + ); + } + console.log( + "\nNOTE: use --name|-n filter virtual environments, use `source <(python.rs active[-venv] venv-name)`", + ); +} + +async function handleAddVenv(args: string[]) { + const flags = parseArgs(args, { + boolean: ["help"], + string: ["version", "venv"], alias: { V: "version", }, }); - if (flags.help) { - console.log("Help massage for venv"); + if (args.length === 0 || flags.help) { + console.log(`Help massage for add-venv + +python.ts add-venv --version 3.10 --venv test-env`); return; } if (!flags.version) { - log.warn("Version missing"); + log.error("Version missing"); return; } - const pythonVirtualEnv = await findVirtualEnv(flags.version); - - // TODO + if (!flags.venv) { + log.error("Venv is missing"); + return; + } + await addVirtualEnv(flags.version, flags.venv); } async function main() { - const args = parseArgs(Deno.args); - const [subcommand, ...remainingArgs] = args._; + const args = Deno.args; - if (!subcommand) { + if (args.length === 0) { log.warn("Subcommand not found, `python.ts help` for help message"); return; } + const subcommand = args[0]; + const remainingArgs = args.slice(1); switch (subcommand) { case "help": handleHelp(remainingArgs); @@ -290,6 +352,9 @@ async function main() { case "venv": await handleVenv(remainingArgs); break; + case "add-venv": + await handleAddVenv(remainingArgs); + break; default: log.error(`Unknown subcommand: ${subcommand}`); break;