From 1e8f41494497cd6f38a20f76c64fe96d16670915 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Fri, 23 Jan 2026 01:26:19 +0800 Subject: [PATCH] feat: cmd.ts --- python-ts/main.ts | 148 ++++++++++++++++++++++++++++++++++++-- script-meta-v2.json | 18 ++--- script-meta.json | 4 +- single-scripts/cal-bun.ts | 6 +- single-scripts/ssh.ts | 13 ++-- 5 files changed, 162 insertions(+), 27 deletions(-) diff --git a/python-ts/main.ts b/python-ts/main.ts index 7ee0d55..a3a80f4 100644 --- a/python-ts/main.ts +++ b/python-ts/main.ts @@ -7,6 +7,8 @@ import { readFileToString, resolveFilename, } from "https://global.hatter.ink/script/get/@12/deno-commons-mod.ts"; +import { parseArgs } from "jsr:@std/cli/parse-args"; +import { spawn } from "node:child_process"; const PYTHON_CONFIG_FILE = "~/.config/python-config.json"; const PYTHON_VENV_DEFAULT_BASE_DIR = "~/.venv/"; @@ -21,7 +23,7 @@ interface PythonConfig { interface PythonVersion { version: string; - path: string; + path: string; // Python path dir or Python binary file comment?: string; } @@ -34,12 +36,24 @@ interface PythonVenv { async function loadPythonConfig(): Promise { const pythonConfigFile = resolveFilename(PYTHON_CONFIG_FILE); const pythonConfigJson = await readFileToString(pythonConfigFile); - if (!pythonConfigJson === null) { + if (!pythonConfigJson) { throw `Could not read python config file: ${pythonConfigFile}`; } return JSON.parse(pythonConfigJson) as PythonConfig; } +async function findVirtualEnv(pythonVenvVersion: string): Promise { + const pythonConfig = await loadPythonConfig(); + if (!pythonConfig.profiles) { + throw "No Python venvs configured"; + } + const pythonVenv = pythonConfig.profiles[pythonVenvVersion]; + if (!pythonVenv) { + throw `Python venv not found: ${pythonVenvVersion}`; + } + return pythonVenv; +} + async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) { const pythonConfig = await loadPythonConfig(); const selectedPythonVersion = pythonVersion || @@ -72,13 +86,133 @@ async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) { } // python3 -m venv myenv - const python3Cmd = joinPath(pythonVersionProfile.path, "bin", "python3"); + const python3Cmd = await getPythonFromPath(pythonVersionProfile.path); + log.success(`Found Python: ${python3Cmd}`); const pythonVenvArgs = ["-m", "vent", pythonVenvDir]; + + log.info( + `Create Python venv, python: ${python3Cmd}, args: ${pythonVenvArgs}`, + ); + spawn(python3Cmd, pythonVenvArgs, { + shell: true, + stdio: ["inherit", "inherit", "inherit"], + }); +} + +async function getPythonFromPath(path: string): Promise { + if (await isFile(path)) { + return path; + } + const python3Cmd = joinPath(pythonVersionProfile.path, "bin", "python3"); + if (await isFile(python3Cmd)) { + return python3Cmd; + } + throw new Error(`Python path not found, path: ${path}`); +} + +async function isFile(path: string): Promise { + const fileInfo = await Deno.stat(path); + return fileInfo?.isFile; +} + +function handleHelp(_args: string[]) { + console.log("Help message"); +} + +async function handlePython(args: string[]) { + const flags = parseArgs(Deno.args, { + boolean: ["help"], + string: ["version"], + alias: { + V: "version", + }, + }); + if (flags.help) { + console.log("Help massage for python"); + return; + } + if (!flags.version) { + const pythonConfig = await loadPythonConfig(); + if (!pythonConfig.versions) { + log.error("No Python versions configured"); + return; + } + + const versions = []; + let maxVersionLength = 0; + for (let version in pythonConfig.versions) { + versions.push(version); + if (version.length > maxVersionLength) { + maxVersionLength = version.length; + } + } + versions.sort(); + + console.log(`Found ${versions.length} Python version(s)`); + for (let version in pythonConfig.versions) { + const pythonVersion = pythonConfig.versions[version]; + const versionPadding = " ".repeat( + maxVersionLength - version.length, + ); + console.log( + `- Python ${version} ${versionPadding}: ${pythonVersion.path} [version: ${ + pythonVersion.version || "unknown" + }]`, + ); + } + + return; + } + const pythonVirtualEnv = await findVirtualEnv(flags.version); + + // TODO +} + +async function handleVenv(args: string[]) { + const flags = parseArgs(Deno.args, { + boolean: ["help"], + string: ["version"], + alias: { + V: "version", + }, + }); + if (flags.help) { + console.log("Help massage for venv"); + return; + } + if (!flags.version) { + log.warn("Version missing"); + return; + } + const pythonVirtualEnv = await findVirtualEnv(flags.version); + + // TODO } async function main() { - // TODO ... -} -await main(); + const args = parseArgs(Deno.args); + const [subcommand, ...remainingArgs] = args._; -// TODO ... + if (!subcommand) { + log.warn("Subcommand not found"); + return; + } + + switch (subcommand) { + case "help": + handleHelp(remainingArgs); + break; + case "py": + case "python": + await handlePython(remainingArgs); + break; + case "venv": + await handleVenv(remainingArgs); + break; + default: + log.error(`Unknown subcommand: ${subcommand}`); + break; + } +} + +main().catch((e) => log.error(e)); diff --git a/script-meta-v2.json b/script-meta-v2.json index 54fd639..d509339 100644 --- a/script-meta-v2.json +++ b/script-meta-v2.json @@ -18,12 +18,12 @@ }, "cal-bun.ts": { "script_name": "cal-bun.ts", - "script_length": 434, - "script_sha256": "90fdb8f6f097dec94566a9595c30edf8996a66698b209104621760340d4462de", + "script_length": 427, + "script_sha256": "5af04975312b2fe0611ddd3d57f65b6c5a6db0e06cb839fd7c0a5d622a64fcd2", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/cal-bun.ts", "single_script_file": true, "publish_time": 1768145414509, - "update_time": 1768145414509 + "update_time": 1769102728192 }, "cal.ts": { "script_name": "cal.ts", @@ -159,11 +159,11 @@ }, "python.ts": { "script_name": "python.ts", - "script_length": 2560, - "script_sha256": "b65bea2cf9927b6b21bb87e9a597ebb2eaf2bd86929e90d149b60317f0cb3d02", + "script_length": 6352, + "script_sha256": "ae1e3137d61ce79ab623ffeaeb6a8e58f378c873592c04339040d66baba5bd35", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/python-ts/main.ts", "publish_time": 1768236234264, - "update_time": 1769009291638 + "update_time": 1769102728184 }, "random.ts": { "script_name": "random.ts", @@ -193,12 +193,12 @@ }, "ssh.ts": { "script_name": "ssh.ts", - "script_length": 6801, - "script_sha256": "d00394544ab94e55b2d3ac62ed0c3aa186f07ed24131ef8d492f215da3de1fb2", + "script_length": 6778, + "script_sha256": "ddee643fa6f18ed55b0530015522166fe548a55baecd1762bd2d198cdd8a5243", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/ssh.ts", "single_script_file": true, "publish_time": 1768111677531, - "update_time": 1768111677531 + "update_time": 1769102728188 }, "wget.ts": { "script_name": "wget.ts", diff --git a/script-meta.json b/script-meta.json index 9533d2a..0a4994d 100644 --- a/script-meta.json +++ b/script-meta.json @@ -21,8 +21,8 @@ }, "python-ts": { "script_name": "python-ts", - "script_length": 2560, - "script_sha256": "b65bea2cf9927b6b21bb87e9a597ebb2eaf2bd86929e90d149b60317f0cb3d02" + "script_length": 6352, + "script_sha256": "ae1e3137d61ce79ab623ffeaeb6a8e58f378c873592c04339040d66baba5bd35" }, "sigstore-verify-ts": { "script_name": "sigstore-verify-ts", diff --git a/single-scripts/cal-bun.ts b/single-scripts/cal-bun.ts index 3517dc4..38ca1c5 100755 --- a/single-scripts/cal-bun.ts +++ b/single-scripts/cal-bun.ts @@ -1,6 +1,6 @@ #!/usr/bin/env runts -- --runtime-bun -const { spawn } = require("node:child_process"); +import {spawn} from "node:child_process"; const _child = spawn("cal", ["-3"], { shell: true, @@ -8,5 +8,5 @@ const _child = spawn("cal", ["-3"], { stdio: ["inherit", "inherit", "inherit"], }); -// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260111T141122+08:00.MEYCIQDP7aV0GffQPybqxwbt -// Kkwj3n9XxQRDc2DyBjfX5gNEXgIhAOb0+0t7EVEOCnces5zCHGtuyp/hRuPyhYjR/YgoykWp +// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260123T010042+08:00.MEUCIQD5tXRb9i5PnOf3c22J +// /xe8L3Hquz2AwwKMq4oiCCL8MQIgGyextuCVasGLXrL3fw29p30QxCMlBKC7ZW9MoiffdEQ= diff --git a/single-scripts/ssh.ts b/single-scripts/ssh.ts index a461645..d4043a6 100755 --- a/single-scripts/ssh.ts +++ b/single-scripts/ssh.ts @@ -2,10 +2,11 @@ // reference: https://git.hatter.ink/rust-scripts/scriptbase/src/branch/main/ssh-rs/src/main.rs -const { spawn } = require("node:child_process"); -const { parseArgs } = require("node:util"); -const fs = require("node:fs"); -const os = require("node:os"); +import {spawn} from "node:child_process"; +import {parseArgs} from "node:util"; + +import fs from "node:fs"; +import os from "node:os"; // reference: https://bun.com/docs/runtime/color const GREEN = Bun.color("green", "ansi"); @@ -210,5 +211,5 @@ async function main() { } await main(); -// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260111T140745+08:00.MEUCIQCY2J0SNtcK1pMKCKE7 -// CFT9R+n9C38X7Y0AMf3krdiKBgIgYAmJTMonrmTnaeURZ3+7a/HQrT0ZLbc27UtPkZ7GloI= +// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260123T010039+08:00.MEYCIQCiVexBU7NyQo5LWv5F +// /mzpbGJiduFHzzhEg/9FB5Y8ZQIhAN21S6dCoghgEJCS+MFZejEF2w7PUwSZMp2r92cUUGqO