@jixo/cli 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,MAAM,GAAU,OAAM,MAAM,EAAiB,kBAuFzD,CAAC"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,MAAM,GAAU,OAAM,MAAM,EAAiB,kBAqHzD,CAAC"}
package/dist/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { cwdResolver } from "@gaubee/node";
2
+ import { match, P } from "ts-pattern";
2
3
  import yargs from "yargs";
3
4
  import { hideBin } from "yargs/helpers";
4
5
  import { doctor } from "./commands/doctor/index.js";
@@ -31,12 +32,43 @@ export const runCli = async (args = process.argv) => {
31
32
  alias: "D",
32
33
  type: "string",
33
34
  description: "The project directory with JIXO config",
35
+ })
36
+ .option("force", {
37
+ alias: "F",
38
+ type: "boolean",
39
+ description: "Tasks are forced to run, even at 100% progress. It is suitable for running after modifying the content of the task",
40
+ })
41
+ .option("once", {
42
+ alias: "O",
43
+ type: "boolean",
44
+ description: "The task is executed only once in the loop, equal to --step=1",
45
+ })
46
+ .option("step", {
47
+ alias: "S",
48
+ type: "number",
49
+ description: "The task is executed N times in the loop",
34
50
  });
35
51
  }, (argv) => {
36
52
  const filters = argv.filter.map((v) => v.toString().split(/[\s,]+/)).flat();
37
- const nameFilter = filters.filter((f) => !f.startsWith("./"));
38
- const dirFilter = filters.filter((f) => f.startsWith("./"));
39
- run(cwdResolver(argv.dir ?? ""), { nameFilter, dirFilter });
53
+ const nameFilter = [];
54
+ const dirFilter = [];
55
+ for (const f of filters) {
56
+ if (f.startsWith("./") || f.startsWith("../") || f.startsWith("~/")) {
57
+ dirFilter.push(f);
58
+ }
59
+ else {
60
+ nameFilter.push(f);
61
+ }
62
+ }
63
+ run(cwdResolver(argv.dir ?? ""), {
64
+ nameFilter,
65
+ dirFilter,
66
+ force: argv.force,
67
+ loopTimes: match(argv)
68
+ .with({ step: P.number.gt(0).select() }, (step) => step)
69
+ .with({ once: P.boolean.select() }, (once) => (once ? 1 : Infinity))
70
+ .otherwise(() => Infinity),
71
+ });
40
72
  })
41
73
  .command("prompts", "Manage prompts", (yargs) => {
42
74
  return (yargs
@@ -68,7 +100,7 @@ export const runCli = async (args = process.argv) => {
68
100
  const argv = await cli.parse();
69
101
  if (argv._.length === 0) {
70
102
  cli.showHelp();
71
- console.log("".repeat(Math.max(4, process.stdout.columns)));
103
+ console.log(" " + "─".repeat(Math.max(4, process.stdout.columns - 2)));
72
104
  await doctor();
73
105
  }
74
106
  };
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import {cwdResolver} from \"@gaubee/node\";\nimport yargs from \"yargs\";\nimport {hideBin} from \"yargs/helpers\";\nimport {doctor} from \"./commands/doctor/index.js\";\nimport {init} from \"./commands/init.js\";\nimport {listPrompts} from \"./commands/prompts/list.js\";\nimport {upgradePrompts} from \"./commands/prompts/upgrade.js\";\nimport {run} from \"./commands/tasks/run.js\";\n\nexport const runCli = async (args: string[] = process.argv) => {\n const cli = await yargs(hideBin(args))\n .scriptName(\"jixo\")\n .command(\n \"doctor\",\n \"Check the requirements for run jixo\",\n (yargs) => yargs,\n () => {\n doctor();\n },\n )\n .command(\n \"init [dir]\",\n \"Create a new JIXO project\",\n (yargs) => {\n return yargs.positional(\"dir\", {\n describe: \"The directory to create the JIXO config\",\n default: \"./\",\n });\n },\n (argv) => {\n init(cwdResolver(argv.dir));\n },\n )\n .command(\n \"run [filter...]\",\n \"Run JIXO tasks\",\n (yargs) => {\n return yargs\n .positional(\"filter\", {\n describe: 'Fliter tasks by name or directory(starts with \"./\")',\n array: true,\n default: [],\n })\n .option(\"dir\", {\n alias: \"D\",\n type: \"string\",\n description: \"The project directory with JIXO config\",\n });\n },\n (argv) => {\n const filters = argv.filter.map((v) => v.toString().split(/[\\s,]+/)).flat();\n const nameFilter = filters.filter((f) => !f.startsWith(\"./\"));\n const dirFilter = filters.filter((f) => f.startsWith(\"./\"));\n run(cwdResolver(argv.dir ?? \"\"), {nameFilter, dirFilter});\n },\n )\n .command(\n \"prompts\",\n \"Manage prompts\",\n (yargs) => {\n return (\n yargs\n //\n .option(\"dir\", {\n alias: \"D\",\n type: \"string\",\n description: \"The project directory with JIXO config\",\n })\n .option(\"mirrorUrl\", {\n alias: \"M\",\n type: \"string\",\n description: \"The Url for download prompts\",\n })\n .option(\"upgrade\", {\n alias: \"U\",\n type: \"boolean\",\n description: \"Upgrade builtin prompts\",\n })\n );\n },\n async (argv) => {\n if (argv.upgrade) {\n upgradePrompts(argv.dir ? cwdResolver(argv.dir) : cwdResolver(), {mirrorUrl: argv.mirrorUrl});\n } else {\n listPrompts();\n }\n },\n )\n .strict();\n const argv = await cli.parse();\n\n if (argv._.length === 0) {\n cli.showHelp();\n console.log(\"⎯\".repeat(Math.max(4, process.stdout.columns)));\n await doctor();\n }\n};\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["import {cwdResolver} from \"@gaubee/node\";\nimport {match, P} from \"ts-pattern\";\nimport yargs from \"yargs\";\nimport {hideBin} from \"yargs/helpers\";\nimport {doctor} from \"./commands/doctor/index.js\";\nimport {init} from \"./commands/init.js\";\nimport {listPrompts} from \"./commands/prompts/list.js\";\nimport {upgradePrompts} from \"./commands/prompts/upgrade.js\";\nimport {run} from \"./commands/tasks/run.js\";\n\nexport const runCli = async (args: string[] = process.argv) => {\n const cli = await yargs(hideBin(args))\n .scriptName(\"jixo\")\n .command(\n \"doctor\",\n \"Check the requirements for run jixo\",\n (yargs) => yargs,\n () => {\n doctor();\n },\n )\n .command(\n \"init [dir]\",\n \"Create a new JIXO project\",\n (yargs) => {\n return yargs.positional(\"dir\", {\n describe: \"The directory to create the JIXO config\",\n default: \"./\",\n });\n },\n (argv) => {\n init(cwdResolver(argv.dir));\n },\n )\n .command(\n \"run [filter...]\",\n \"Run JIXO tasks\",\n (yargs) => {\n return yargs\n .positional(\"filter\", {\n describe: 'Fliter tasks by name or directory(starts with \"./\")',\n array: true,\n default: [],\n })\n .option(\"dir\", {\n alias: \"D\",\n type: \"string\",\n description: \"The project directory with JIXO config\",\n })\n .option(\"force\", {\n alias: \"F\",\n type: \"boolean\",\n description: \"Tasks are forced to run, even at 100% progress. It is suitable for running after modifying the content of the task\",\n })\n .option(\"once\", {\n alias: \"O\",\n type: \"boolean\",\n description: \"The task is executed only once in the loop, equal to --step=1\",\n })\n .option(\"step\", {\n alias: \"S\",\n type: \"number\",\n description: \"The task is executed N times in the loop\",\n });\n },\n (argv) => {\n const filters = argv.filter.map((v) => v.toString().split(/[\\s,]+/)).flat();\n const nameFilter: string[] = [];\n const dirFilter: string[] = [];\n for (const f of filters) {\n if (f.startsWith(\"./\") || f.startsWith(\"../\") || f.startsWith(\"~/\")) {\n dirFilter.push(f);\n } else {\n nameFilter.push(f);\n }\n }\n run(cwdResolver(argv.dir ?? \"\"), {\n nameFilter,\n dirFilter,\n force: argv.force,\n loopTimes: match(argv)\n .with({step: P.number.gt(0).select()}, (step) => step)\n .with({once: P.boolean.select()}, (once) => (once ? 1 : Infinity))\n .otherwise(() => Infinity),\n });\n },\n )\n .command(\n \"prompts\",\n \"Manage prompts\",\n (yargs) => {\n return (\n yargs\n //\n .option(\"dir\", {\n alias: \"D\",\n type: \"string\",\n description: \"The project directory with JIXO config\",\n })\n .option(\"mirrorUrl\", {\n alias: \"M\",\n type: \"string\",\n description: \"The Url for download prompts\",\n })\n .option(\"upgrade\", {\n alias: \"U\",\n type: \"boolean\",\n description: \"Upgrade builtin prompts\",\n })\n );\n },\n async (argv) => {\n if (argv.upgrade) {\n upgradePrompts(argv.dir ? cwdResolver(argv.dir) : cwdResolver(), {mirrorUrl: argv.mirrorUrl});\n } else {\n listPrompts();\n }\n },\n )\n .strict();\n const argv = await cli.parse();\n\n if (argv._.length === 0) {\n cli.showHelp();\n console.log(\" \" + \"─\".repeat(Math.max(4, process.stdout.columns - 2)));\n await doctor();\n }\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  // doctor.ts
2
2
  import { blue, cyan, green, red, spinner, yellow } from "@gaubee/nodekit";
3
- import { execSync } from "child_process";
3
+ import { execSync } from "node:child_process";
4
4
  import semver from "semver";
5
5
  import { iter_map_not_null } from "@gaubee/util";
6
6
  const CHECK_MARK = green("✔");
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/commands/doctor/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["// doctor.ts\nimport {blue, cyan, green, red, spinner, yellow} from \"@gaubee/nodekit\";\nimport {execSync} from \"child_process\";\nimport semver from \"semver\";\n\nimport {iter_map_not_null} from \"@gaubee/util\";\nimport type {DoctorConfig} from \"./types.js\"; // Assuming types.ts\n\nconst CHECK_MARK = green(\"✔\");\nconst CROSS_MARK = red(\"✖\");\nconst WARN_MARK = yellow(\"⚠\");\n\nexport interface ToolCheckResult {\n id: string;\n displayName: string;\n exists: boolean;\n version?: string; // Actual version found\n requiredVersion?: string; // From config\n meetsVersionRequirement: boolean; // True if version >= minVersion or if minVersion not set & exists\n isOptional: boolean;\n message: string;\n installationHint?: string;\n}\n\nexport interface DoctorReport {\n overallSuccess: boolean;\n results: ToolCheckResult[];\n}\n\nasync function executeCommand(command: string): Promise<{stdout: string; stderr: string; error?: Error}> {\n return new Promise((resolve) => {\n try {\n const stdout = execSync(command, {encoding: \"utf8\", stdio: \"pipe\"});\n resolve({stdout, stderr: \"\"});\n } catch (e: any) {\n resolve({stdout: \"\", stderr: e.stderr || \"\", error: e});\n }\n });\n}\n\nexport async function runDoctor(config: DoctorConfig, enableLog: boolean = true): Promise<DoctorReport> {\n const LOG_TITLE = \"Running Environment Doctor 🏥\\n\\n\";\n const logger = spinner(LOG_TITLE);\n if (enableLog) {\n logger.start();\n }\n\n const results: ToolCheckResult[] = [];\n let overallSuccess = true;\n let overallWarn = false;\n\n const tool_logs: string[] = [];\n\n for (const [index, tool] of config.entries()) {\n const TOOL_LOG_TITLE = `${blue(`[${tool.id}]`)} ${cyan(tool.displayName)}`;\n const SUCCESS_MARK = () => CHECK_MARK;\n const FAIL_MARK = () => {\n overallWarn = true;\n return tool.optional ? WARN_MARK : CROSS_MARK;\n };\n const setToolLog = (update: (cur: string) => string | (string | undefined | null)[]) => {\n const log = update(tool_logs[index] ?? \"\");\n tool_logs[index] = (Array.isArray(log) ? iter_map_not_null(log, (v) => (v ? v : null)) : [log]).map((line) => \" \" + line).join(\"\\n\");\n logger.text = LOG_TITLE + tool_logs.join(\"\\n\");\n };\n setToolLog(() => `Checking ${TOOL_LOG_TITLE}... `);\n let tool_log: (string | undefined | null)[] = [];\n\n const result: ToolCheckResult = {\n id: tool.id,\n displayName: tool.displayName,\n exists: false,\n meetsVersionRequirement: false, // Assume failure until proven otherwise\n isOptional: !!tool.optional,\n message: \"\",\n requiredVersion: tool.minVersion,\n installationHint: tool.installationHint,\n };\n\n const execResult = await executeCommand(tool.versionCommand);\n\n if (execResult.error || execResult.stderr.includes(\"command not found\") || execResult.stderr.includes(\"not recognized\")) {\n result.exists = false;\n result.message = `'${tool.id}' command not found or failed to execute.`;\n tool_log = [\n //\n `${FAIL_MARK()} ${TOOL_LOG_TITLE}`,\n ` ${red(result.message)}`,\n tool.installationHint && ` ${yellow(\"Hint:\")} ${tool.installationHint}`,\n ];\n } else {\n result.exists = true;\n const output = execResult.stdout.trim();\n const match = output.match(tool.versionParseRegex);\n\n if (match && match[1]) {\n result.version = semver.clean(match[1]) || undefined; // Clean the version string\n if (result.version) {\n if (tool.minVersion) {\n if (semver.gte(result.version, tool.minVersion)) {\n result.meetsVersionRequirement = true;\n result.message = `Version ${result.version} satisfies >=${tool.minVersion}.`;\n tool_log.push(`${SUCCESS_MARK()} ${TOOL_LOG_TITLE} (v${result.version})`);\n } else {\n result.meetsVersionRequirement = false;\n result.message = `Version ${result.version} is older than required >=${tool.minVersion}.`;\n tool_log.push(`${FAIL_MARK()} ${TOOL_LOG_TITLE} (v${result.version} - required: >=${tool.minVersion})`);\n tool_log.push(` ${red(result.message)}`);\n if (tool.installationHint) {\n tool_log.push(` ${yellow(\"Hint:\")} ${tool.installationHint}`);\n }\n }\n } else {\n // No minimum version specified, just existence is enough\n result.meetsVersionRequirement = true;\n result.message = `Found version ${result.version}. No minimum version specified.`;\n tool_log.push(`${SUCCESS_MARK()} ${TOOL_LOG_TITLE} (v${result.version} - existence check only)`);\n }\n } else {\n // Regex matched but couldn't clean version (should be rare with semver.clean)\n result.meetsVersionRequirement = false;\n result.message = `Could not parse a valid version string from output: \"${output}\". Regex: ${tool.versionParseRegex}`;\n tool_log.push(`${FAIL_MARK()} ${TOOL_LOG_TITLE}`);\n tool_log.push(` ${red(result.message)}`);\n }\n } else {\n result.meetsVersionRequirement = false;\n result.message = `Could not parse version from output: \"${output}\". Regex: ${tool.versionParseRegex}`;\n tool_log.push(`${FAIL_MARK}`);\n tool_log.push(` ${red(result.message)}`);\n }\n }\n\n setToolLog(() => tool_log);\n\n results.push(result);\n if (!result.meetsVersionRequirement && !result.isOptional) {\n overallSuccess = false;\n }\n }\n\n const LOG_SUMMERY = `${overallSuccess ? (overallWarn ? \"⚠️ \" : \"✅\") : \"💊\"} JIXO Environment Doctor 🏥\\n\\n`;\n logger.stopAndPersist({\n text: LOG_SUMMERY + tool_logs.join(\"\\n\") + \"\\n\",\n });\n\n return {\n overallSuccess,\n results,\n };\n}\n"]}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/commands/doctor/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["// doctor.ts\nimport {blue, cyan, green, red, spinner, yellow} from \"@gaubee/nodekit\";\nimport {execSync} from \"node:child_process\";\nimport semver from \"semver\";\n\nimport {iter_map_not_null} from \"@gaubee/util\";\nimport type {DoctorConfig} from \"./types.js\"; // Assuming types.ts\n\nconst CHECK_MARK = green(\"✔\");\nconst CROSS_MARK = red(\"✖\");\nconst WARN_MARK = yellow(\"⚠\");\n\nexport interface ToolCheckResult {\n id: string;\n displayName: string;\n exists: boolean;\n version?: string; // Actual version found\n requiredVersion?: string; // From config\n meetsVersionRequirement: boolean; // True if version >= minVersion or if minVersion not set & exists\n isOptional: boolean;\n message: string;\n installationHint?: string;\n}\n\nexport interface DoctorReport {\n overallSuccess: boolean;\n results: ToolCheckResult[];\n}\n\nasync function executeCommand(command: string): Promise<{stdout: string; stderr: string; error?: Error}> {\n return new Promise((resolve) => {\n try {\n const stdout = execSync(command, {encoding: \"utf8\", stdio: \"pipe\"});\n resolve({stdout, stderr: \"\"});\n } catch (e: any) {\n resolve({stdout: \"\", stderr: e.stderr || \"\", error: e});\n }\n });\n}\n\nexport async function runDoctor(config: DoctorConfig, enableLog: boolean = true): Promise<DoctorReport> {\n const LOG_TITLE = \"Running Environment Doctor 🏥\\n\\n\";\n const logger = spinner(LOG_TITLE);\n if (enableLog) {\n logger.start();\n }\n\n const results: ToolCheckResult[] = [];\n let overallSuccess = true;\n let overallWarn = false;\n\n const tool_logs: string[] = [];\n\n for (const [index, tool] of config.entries()) {\n const TOOL_LOG_TITLE = `${blue(`[${tool.id}]`)} ${cyan(tool.displayName)}`;\n const SUCCESS_MARK = () => CHECK_MARK;\n const FAIL_MARK = () => {\n overallWarn = true;\n return tool.optional ? WARN_MARK : CROSS_MARK;\n };\n const setToolLog = (update: (cur: string) => string | (string | undefined | null)[]) => {\n const log = update(tool_logs[index] ?? \"\");\n tool_logs[index] = (Array.isArray(log) ? iter_map_not_null(log, (v) => (v ? v : null)) : [log]).map((line) => \" \" + line).join(\"\\n\");\n logger.text = LOG_TITLE + tool_logs.join(\"\\n\");\n };\n setToolLog(() => `Checking ${TOOL_LOG_TITLE}... `);\n let tool_log: (string | undefined | null)[] = [];\n\n const result: ToolCheckResult = {\n id: tool.id,\n displayName: tool.displayName,\n exists: false,\n meetsVersionRequirement: false, // Assume failure until proven otherwise\n isOptional: !!tool.optional,\n message: \"\",\n requiredVersion: tool.minVersion,\n installationHint: tool.installationHint,\n };\n\n const execResult = await executeCommand(tool.versionCommand);\n\n if (execResult.error || execResult.stderr.includes(\"command not found\") || execResult.stderr.includes(\"not recognized\")) {\n result.exists = false;\n result.message = `'${tool.id}' command not found or failed to execute.`;\n tool_log = [\n //\n `${FAIL_MARK()} ${TOOL_LOG_TITLE}`,\n ` ${red(result.message)}`,\n tool.installationHint && ` ${yellow(\"Hint:\")} ${tool.installationHint}`,\n ];\n } else {\n result.exists = true;\n const output = execResult.stdout.trim();\n const match = output.match(tool.versionParseRegex);\n\n if (match && match[1]) {\n result.version = semver.clean(match[1]) || undefined; // Clean the version string\n if (result.version) {\n if (tool.minVersion) {\n if (semver.gte(result.version, tool.minVersion)) {\n result.meetsVersionRequirement = true;\n result.message = `Version ${result.version} satisfies >=${tool.minVersion}.`;\n tool_log.push(`${SUCCESS_MARK()} ${TOOL_LOG_TITLE} (v${result.version})`);\n } else {\n result.meetsVersionRequirement = false;\n result.message = `Version ${result.version} is older than required >=${tool.minVersion}.`;\n tool_log.push(`${FAIL_MARK()} ${TOOL_LOG_TITLE} (v${result.version} - required: >=${tool.minVersion})`);\n tool_log.push(` ${red(result.message)}`);\n if (tool.installationHint) {\n tool_log.push(` ${yellow(\"Hint:\")} ${tool.installationHint}`);\n }\n }\n } else {\n // No minimum version specified, just existence is enough\n result.meetsVersionRequirement = true;\n result.message = `Found version ${result.version}. No minimum version specified.`;\n tool_log.push(`${SUCCESS_MARK()} ${TOOL_LOG_TITLE} (v${result.version} - existence check only)`);\n }\n } else {\n // Regex matched but couldn't clean version (should be rare with semver.clean)\n result.meetsVersionRequirement = false;\n result.message = `Could not parse a valid version string from output: \"${output}\". Regex: ${tool.versionParseRegex}`;\n tool_log.push(`${FAIL_MARK()} ${TOOL_LOG_TITLE}`);\n tool_log.push(` ${red(result.message)}`);\n }\n } else {\n result.meetsVersionRequirement = false;\n result.message = `Could not parse version from output: \"${output}\". Regex: ${tool.versionParseRegex}`;\n tool_log.push(`${FAIL_MARK}`);\n tool_log.push(` ${red(result.message)}`);\n }\n }\n\n setToolLog(() => tool_log);\n\n results.push(result);\n if (!result.meetsVersionRequirement && !result.isOptional) {\n overallSuccess = false;\n }\n }\n\n const LOG_SUMMERY = `${overallSuccess ? (overallWarn ? \"⚠️ \" : \"✅\") : \"💊\"} JIXO Environment Doctor 🏥\\n\\n`;\n logger.stopAndPersist({\n text: LOG_SUMMERY + tool_logs.join(\"\\n\") + \"\\n\",\n });\n\n return {\n overallSuccess,\n results,\n };\n}\n"]}