mdat-plugin-cli-help 2.0.1 → 2.0.2

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.
Files changed (2) hide show
  1. package/dist/index.js +27 -15
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineConfig, getContextMetadata } from "mdat";
2
2
  import { z } from "zod";
3
- import { execaCommand } from "execa";
3
+ import { execa } from "execa";
4
4
  import { createLogger, injectionHelper } from "lognow";
5
5
  import { CstParser, Lexer, createToken } from "chevrotain";
6
6
  import path from "node:path";
@@ -720,26 +720,32 @@ function helpStringToObject(helpString) {
720
720
  //#region src/utilities/get-help-markdown.ts
721
721
  /**
722
722
  * Get help output from a CLI command and return it as markdown
723
+ *
724
+ * @param cliCommand - The executable path (may contain spaces, e.g. on Windows)
725
+ * @param helpFlag - The flag to pass to get help output
726
+ * @param depth - Max recursion depth for subcommands
723
727
  */
724
728
  async function getHelpMarkdown(cliCommand, helpFlag = "--help", depth) {
725
- const rawHelpString = await getHelpString(`${cliCommand} ${helpFlag}`);
729
+ return getHelpMarkdownInternal(cliCommand, [], helpFlag, depth ?? Number.MAX_SAFE_INTEGER);
730
+ }
731
+ async function getHelpMarkdownInternal(executable, subcommands, helpFlag, depth) {
732
+ const rawHelpString = await getHelpString(executable, [...subcommands, helpFlag]);
726
733
  const programInfo = helpStringToObject(rawHelpString);
727
734
  if (programInfo === void 0) {
728
735
  log.warn(`Falling back to basic cli help text output.`);
729
736
  return renderHelpMarkdownBasic(rawHelpString);
730
737
  }
731
- return renderHelpMarkdownObject(cliCommand, helpFlag, depth ?? Number.MAX_SAFE_INTEGER, programInfo);
738
+ return renderHelpMarkdownObject(executable, subcommands, helpFlag, depth, programInfo);
732
739
  }
733
- async function renderHelpMarkdownObject(cliCommand, helpFlag, depth, programInfo) {
740
+ async function renderHelpMarkdownObject(executable, subcommands, helpFlag, depth, programInfo) {
734
741
  if (depth <= 0) {
735
742
  log.warn(`Max CLI command help depth reached, stopping recursion`);
736
743
  return "";
737
744
  }
738
745
  let markdown = helpObjectToMarkdown(programInfo, depth);
739
- const baseCommand = cliCommand.split(" ")[0];
740
746
  if (programInfo.commands) for (const command of programInfo.commands) {
741
747
  if (!command.parentCommandName || !command.commandName) continue;
742
- const subCommandHelp = await getHelpMarkdown(`${baseCommand} ${command.commandName}`, helpFlag, depth - 1);
748
+ const subCommandHelp = await getHelpMarkdownInternal(executable, [...subcommands, command.commandName], helpFlag, depth - 1);
743
749
  if (subCommandHelp === "") return markdown;
744
750
  markdown += `\n\n${subCommandHelp}`;
745
751
  }
@@ -753,19 +759,21 @@ function renderHelpMarkdownBasic(rawHelpString) {
753
759
  }
754
760
  /**
755
761
  * Run the CLI help command and return the output, throw if there's no output
762
+ *
763
+ * @returns The full help string from the resolved command
756
764
  * @throws {TypeError} If there's an error running the CLI help command
757
- * @returns the full help string from the resolved command
758
765
  */
759
- async function getHelpString(resolvedCommand) {
766
+ async function getHelpString(command, args) {
767
+ const displayCommand = `${command} ${args.join(" ")}`;
760
768
  let rawHelpString;
761
769
  try {
762
- const { stderr, stdout } = await execaCommand(resolvedCommand);
770
+ const { stderr, stdout } = await execa(command, args, { preferLocal: true });
763
771
  rawHelpString = stdout;
764
772
  if (rawHelpString === void 0 || rawHelpString === "") rawHelpString = stderr;
765
773
  } catch (error) {
766
- if (error instanceof Error) throw new TypeError(`Error running CLI help command: "${resolvedCommand}"\n${error.message}\n`);
774
+ if (error instanceof Error) throw new TypeError(`Error running CLI help command: "${displayCommand}"\n${error.message}\n`);
767
775
  }
768
- if (rawHelpString === void 0 || rawHelpString === "") throw new Error(`No result from running CLI help command: "${resolvedCommand}"\n`);
776
+ if (rawHelpString === void 0 || rawHelpString === "") throw new Error(`No result from running CLI help command: "${displayCommand}"\n`);
769
777
  return rawHelpString;
770
778
  }
771
779
  //#endregion
@@ -823,10 +831,14 @@ function looksLikePath(maybePath) {
823
831
  return parsed.root !== "" || parsed.dir !== "";
824
832
  }
825
833
  async function ensureExecutable(filePath) {
826
- let resolvedPath = path.isAbsolute(filePath) ? filePath : await which(filePath, { nothrow: true }) ?? void 0;
827
- resolvedPath ??= await getCommandPathFromPackage(filePath) ?? void 0;
828
- if (resolvedPath !== void 0 && await isExecutable(resolvedPath)) return resolvedPath;
829
- throw new Error(`The cli-help rule noticed that "${resolvedPath}" is not executable.`);
834
+ if (path.isAbsolute(filePath)) {
835
+ if (await isExecutable(filePath)) return filePath;
836
+ throw new Error(`The cli-help rule noticed that "${filePath}" is not executable.`);
837
+ }
838
+ if (await which(filePath, { nothrow: true }) !== null) return filePath;
839
+ const packagePath = await getCommandPathFromPackage(filePath);
840
+ if (packagePath !== void 0 && await isExecutable(packagePath)) return packagePath;
841
+ throw new Error(`The cli-help rule noticed that "${filePath}" is not executable.`);
830
842
  }
831
843
  async function getCommandPathFromPackage(commandName) {
832
844
  const { nodePackageJson } = await getContextMetadata();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mdat-plugin-cli-help",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Mdat plugin to generate tabular help documentation for CLI tools in Markdown files.",
5
5
  "keywords": [
6
6
  "markdown",
@@ -66,8 +66,8 @@
66
66
  }
67
67
  },
68
68
  "scripts": {
69
- "bench": "vitest bench --no-file-parallelism --compare test/benchmarks/baseline.json",
70
- "bench:baseline": "vitest bench --no-file-parallelism --outputJson test/benchmarks/baseline.json",
69
+ "bench": "vitest bench --run --no-file-parallelism --compare test/benchmarks/baseline.json",
70
+ "bench:baseline": "vitest bench --run --no-file-parallelism --outputJson test/benchmarks/baseline.json",
71
71
  "build": "tsdown --no-fixed-extension --tsconfig tsconfig.build.json",
72
72
  "clean": "git rm -f pnpm-lock.yaml ; git clean -fdX",
73
73
  "fix": "ksc fix",