feat: cmd.ts

This commit is contained in:
2026-01-23 01:26:19 +08:00
parent 5a8b4c0ac1
commit 1e8f414944
5 changed files with 162 additions and 27 deletions

View File

@@ -7,6 +7,8 @@ import {
readFileToString, readFileToString,
resolveFilename, resolveFilename,
} from "https://global.hatter.ink/script/get/@12/deno-commons-mod.ts"; } 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_CONFIG_FILE = "~/.config/python-config.json";
const PYTHON_VENV_DEFAULT_BASE_DIR = "~/.venv/"; const PYTHON_VENV_DEFAULT_BASE_DIR = "~/.venv/";
@@ -21,7 +23,7 @@ interface PythonConfig {
interface PythonVersion { interface PythonVersion {
version: string; version: string;
path: string; path: string; // Python path dir or Python binary file
comment?: string; comment?: string;
} }
@@ -34,12 +36,24 @@ interface PythonVenv {
async function loadPythonConfig(): Promise<PythonConfig> { async function loadPythonConfig(): Promise<PythonConfig> {
const pythonConfigFile = resolveFilename(PYTHON_CONFIG_FILE); const pythonConfigFile = resolveFilename(PYTHON_CONFIG_FILE);
const pythonConfigJson = await readFileToString(pythonConfigFile); const pythonConfigJson = await readFileToString(pythonConfigFile);
if (!pythonConfigJson === null) { if (!pythonConfigJson) {
throw `Could not read python config file: ${pythonConfigFile}`; throw `Could not read python config file: ${pythonConfigFile}`;
} }
return JSON.parse(pythonConfigJson) as PythonConfig; return JSON.parse(pythonConfigJson) as PythonConfig;
} }
async function findVirtualEnv(pythonVenvVersion: string): Promise<PythonVenv> {
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) { async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) {
const pythonConfig = await loadPythonConfig(); const pythonConfig = await loadPythonConfig();
const selectedPythonVersion = pythonVersion || const selectedPythonVersion = pythonVersion ||
@@ -72,13 +86,133 @@ async function newVirtualEnv(pythonVersion: string | null, pythonVenv: string) {
} }
// python3 -m venv myenv // 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]; 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<string> {
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<boolean> {
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() { async function main() {
// TODO ... const args = parseArgs(Deno.args);
} const [subcommand, ...remainingArgs] = args._;
await main();
// 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));

View File

@@ -18,12 +18,12 @@
}, },
"cal-bun.ts": { "cal-bun.ts": {
"script_name": "cal-bun.ts", "script_name": "cal-bun.ts",
"script_length": 434, "script_length": 427,
"script_sha256": "90fdb8f6f097dec94566a9595c30edf8996a66698b209104621760340d4462de", "script_sha256": "5af04975312b2fe0611ddd3d57f65b6c5a6db0e06cb839fd7c0a5d622a64fcd2",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/cal-bun.ts", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/cal-bun.ts",
"single_script_file": true, "single_script_file": true,
"publish_time": 1768145414509, "publish_time": 1768145414509,
"update_time": 1768145414509 "update_time": 1769102728192
}, },
"cal.ts": { "cal.ts": {
"script_name": "cal.ts", "script_name": "cal.ts",
@@ -159,11 +159,11 @@
}, },
"python.ts": { "python.ts": {
"script_name": "python.ts", "script_name": "python.ts",
"script_length": 2560, "script_length": 6352,
"script_sha256": "b65bea2cf9927b6b21bb87e9a597ebb2eaf2bd86929e90d149b60317f0cb3d02", "script_sha256": "ae1e3137d61ce79ab623ffeaeb6a8e58f378c873592c04339040d66baba5bd35",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/python-ts/main.ts", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/python-ts/main.ts",
"publish_time": 1768236234264, "publish_time": 1768236234264,
"update_time": 1769009291638 "update_time": 1769102728184
}, },
"random.ts": { "random.ts": {
"script_name": "random.ts", "script_name": "random.ts",
@@ -193,12 +193,12 @@
}, },
"ssh.ts": { "ssh.ts": {
"script_name": "ssh.ts", "script_name": "ssh.ts",
"script_length": 6801, "script_length": 6778,
"script_sha256": "d00394544ab94e55b2d3ac62ed0c3aa186f07ed24131ef8d492f215da3de1fb2", "script_sha256": "ddee643fa6f18ed55b0530015522166fe548a55baecd1762bd2d198cdd8a5243",
"script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/ssh.ts", "script_full_url": "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/single-scripts/ssh.ts",
"single_script_file": true, "single_script_file": true,
"publish_time": 1768111677531, "publish_time": 1768111677531,
"update_time": 1768111677531 "update_time": 1769102728188
}, },
"wget.ts": { "wget.ts": {
"script_name": "wget.ts", "script_name": "wget.ts",

View File

@@ -21,8 +21,8 @@
}, },
"python-ts": { "python-ts": {
"script_name": "python-ts", "script_name": "python-ts",
"script_length": 2560, "script_length": 6352,
"script_sha256": "b65bea2cf9927b6b21bb87e9a597ebb2eaf2bd86929e90d149b60317f0cb3d02" "script_sha256": "ae1e3137d61ce79ab623ffeaeb6a8e58f378c873592c04339040d66baba5bd35"
}, },
"sigstore-verify-ts": { "sigstore-verify-ts": {
"script_name": "sigstore-verify-ts", "script_name": "sigstore-verify-ts",

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env runts -- --runtime-bun #!/usr/bin/env runts -- --runtime-bun
const { spawn } = require("node:child_process"); import {spawn} from "node:child_process";
const _child = spawn("cal", ["-3"], { const _child = spawn("cal", ["-3"], {
shell: true, shell: true,
@@ -8,5 +8,5 @@ const _child = spawn("cal", ["-3"], {
stdio: ["inherit", "inherit", "inherit"], stdio: ["inherit", "inherit", "inherit"],
}); });
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260111T141122+08:00.MEYCIQDP7aV0GffQPybqxwbt // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260123T010042+08:00.MEUCIQD5tXRb9i5PnOf3c22J
// Kkwj3n9XxQRDc2DyBjfX5gNEXgIhAOb0+0t7EVEOCnces5zCHGtuyp/hRuPyhYjR/YgoykWp // /xe8L3Hquz2AwwKMq4oiCCL8MQIgGyextuCVasGLXrL3fw29p30QxCMlBKC7ZW9MoiffdEQ=

View File

@@ -2,10 +2,11 @@
// reference: https://git.hatter.ink/rust-scripts/scriptbase/src/branch/main/ssh-rs/src/main.rs // reference: https://git.hatter.ink/rust-scripts/scriptbase/src/branch/main/ssh-rs/src/main.rs
const { spawn } = require("node:child_process"); import {spawn} from "node:child_process";
const { parseArgs } = require("node:util"); import {parseArgs} from "node:util";
const fs = require("node:fs");
const os = require("node:os"); import fs from "node:fs";
import os from "node:os";
// reference: https://bun.com/docs/runtime/color // reference: https://bun.com/docs/runtime/color
const GREEN = Bun.color("green", "ansi"); const GREEN = Bun.color("green", "ansi");
@@ -210,5 +211,5 @@ async function main() {
} }
await main(); await main();
// @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260111T140745+08:00.MEUCIQCY2J0SNtcK1pMKCKE7 // @SCRIPT-SIGNATURE-V1: yk-r1.ES256.20260123T010039+08:00.MEYCIQCiVexBU7NyQo5LWv5F
// CFT9R+n9C38X7Y0AMf3krdiKBgIgYAmJTMonrmTnaeURZ3+7a/HQrT0ZLbc27UtPkZ7GloI= // /mzpbGJiduFHzzhEg/9FB5Y8ZQIhAN21S6dCoghgEJCS+MFZejEF2w7PUwSZMp2r92cUUGqO