Skip to content

Commit

Permalink
docs: Dynamically pretty-formatting CLI reference
Browse files Browse the repository at this point in the history
  • Loading branch information
steilerDev committed Sep 1, 2023
1 parent a4455dd commit 2e5a7e6
Show file tree
Hide file tree
Showing 18 changed files with 488 additions and 236 deletions.
13 changes: 4 additions & 9 deletions .github/actions/build/docs-setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,8 @@ runs:
uses: actions/setup-node@v3
with:
node-version-file: ${{ inputs.app-path }}/node-version
- id: download-app-artifact
uses: actions/download-artifact@v3
with:
name: ${{ inputs.app-artifact-name }}
path: ${{ inputs.app-path }}
- id: install-app-artifact
cache: npm
cache-dependency-path: ${{ inputs.app-path }}
- id: setup-npm
shell: bash
run: |
tree -a ${{ inputs.app-path }}
npm install -g ./${{ inputs.app-path }}/npm-pack.tgz
run: (cd ${{ inputs.app-path }}; npm ci)
6 changes: 1 addition & 5 deletions .github/actions/build/docs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@ runs:
run: |
echo "site-dir=$(grep -oP "site_dir: '\K.+'" ${{ inputs.docs-path }}/mkdocs.yml | head -c-2)" >> $GITHUB_OUTPUT
echo "docs-dir=$(grep -oP "docs_dir: '\K.+'" ${{ inputs.docs-path }}/mkdocs.yml | head -c-2)" >> $GITHUB_OUTPUT
- id: get-npm-metadata
uses: ./.github/actions/helper/npm-metadata
with:
package: ${{ inputs.app-path }}/package.json
- id: setup-fs
shell: bash
run: cp README.md LICENSE ${{ inputs.docs-path }}/${{ steps.get-docs-config.outputs.docs-dir }}/
- id: build-cli-reference
shell: bash
run: ${{ github.action_path }}/build_cli.sh "${{ inputs.docs-path }}/${{ steps.get-docs-config.outputs.docs-dir }}" "${{ steps.get-npm-metadata.outputs.command }}"
run: (cd ${{ inputs.app-path }}; npm run doc:cli -- "${{ inputs.docs-path }}/${{ steps.get-docs-config.outputs.docs-dir }}")
- id: build-mkdocs
shell: bash
run: (cd ${{ inputs.docs-path }}; mkdocs build)
Expand Down
38 changes: 0 additions & 38 deletions .github/actions/build/docs/build_cli.sh

This file was deleted.

2 changes: 1 addition & 1 deletion .github/actions/build/wiki/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ runs:
steps:
- id: build-typedoc
shell: bash
run: (cd ${{ inputs.app-path }}; npm run build:typedoc)
run: (cd ${{ inputs.app-path }}; npm run doc:typedoc)
- id: package-artifact
shell: bash
run: |
Expand Down
3 changes: 3 additions & 0 deletions .vscode/icloud-photos-sync.cspell
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ CPLASSET
CPLMASTER
croner
datasource
dawidd6
dedup
deFEyox97ecdknADe0xP4YzIDDKf
devmasx
Expand All @@ -30,6 +31,7 @@ Driessen
dsid
dslang
emhlbnl
endfor
fcxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
foldered
fontawesome
Expand All @@ -48,6 +50,7 @@ KNYDBI
leonardi
Lfyc
lhotari
liquidjs
loglevel
LPMQ
majorfeat
Expand Down
2 changes: 1 addition & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"tasks": [
{
"type": "npm",
"script": "build",
"script": "build:dev",
"path": "app/",
"group": "build",
"problemMatcher": [],
Expand Down
65 changes: 65 additions & 0 deletions app/build/cli-reference.liquid
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# CLI Reference

## Description

{{ description }}.

## Synopsis

```
{{ synopsis }}
```

Use `{{ commandName }} {{ helpCommandName }} [command]` for information on a specific command. The following commands are available:
{% for command in globalCommands %}
* [{{ command.name }}](#{{ command.name }})
{% endfor %}

## Options
{% for option in globalOptions %}
### {{ option.pretty }}

{% if option.required -%}
`{{- ' REQUIRED' -}}`
{%- else -%}
`{{- ' OPTIONAL' -}}`
{%- endif -%}
{{- ' | ' -}}
`{{- option.type }}`

{{ option.description }}

{% if option.long %}
* *Long Option*: `{{ option.long }}`
{%- endif -%}
{% if option.short %}
* *Short Option*: `{{ option.short }}`
{%- endif -%}
{% if option.environment %}
* *Environment Variable*: `{{ option.environment }}`
{%- endif -%}
{% if option.defaultValue %}
* *Default*: `{{ option.defaultValue }}`
{%- endif -%}
{% endfor %}

## Commands

{% for command in globalCommands %}
### {{ command.name }}

{{ command.description}}

Usage:
```
{{ command.usage}}
```

{% if command.arguments.length > 0 %}
Arguments:
{% for argument in command.arguments %}
* `{{ argument.name}}` ({% if argument.required -%} `REQUIRED` {%- else -%} `OPTIONAL` {%- endif %}): {{ argument.description }}
{%- endfor %}
{% endif %}

{% endfor %}
101 changes: 101 additions & 0 deletions app/build/cli-reference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// This script generates the CLI reference documentation from the CLI options - if doc root path is provided, it will write the output to the provided path, otherwise it will print to stdout

import {Argument, Help} from 'commander';
import {argParser} from '../src/app/factory.js';
import {Liquid} from 'liquidjs';
import fs from 'fs/promises';
import path from 'path';

const outputPath = process.argv.pop() + `/user-guides/cli.md`;

/**
* The program from the app factory
*/
const program = argParser(() => {});
/**
* Commander js helper to format
*/
const helper = new Help();

type GlobalCommand = {
name: string,
usage: string,
description: string,
arguments?: {
name: string,
description: string,
required: boolean
}[]
}

type GlobalOption = {
pretty: string,
required: boolean,
type: string,
description: string,
long?: string,
short?: string,
environment?: string,
defaultValue?: string,
}

const templateInput = {
description: program.description(),
commandName: program.name(),
helpCommandName: (program as any)._helpCommandName,
synopsis: helper.commandUsage(program),
globalCommands: [] as GlobalCommand[],
globalOptions: [] as GlobalOption[],
};

for (const option of program.options) {
templateInput.globalOptions.push(
{
pretty: option.long!.slice(2),
long: option.long!,
short: option.short!,
environment: (option as any).envVar,
required: option.mandatory,
defaultValue: option.defaultValueDescription ?? option.defaultValue?.toString(),
type: (option.flags.match(/<(.*)>/) ?? [``, `boolean`])[1],
description: option.description,
},
);
}

for (const command of program.commands) {
templateInput.globalCommands.push(
{
name: command.name(),
usage: templateInput.commandName + ` [options] ` + command.name() + ((command as any)._args.length > 0 ? ` [arguments]` : ``),
description: command.description(),
arguments: [],
},
);

for (const argument of (command as any)._args as Argument[]) {
templateInput.globalCommands[templateInput.globalCommands.length - 1].arguments!.push(
{
name: argument.name(),
description: argument.description,
required: argument.required,
},
);
}
}

templateInput.globalOptions.sort((a, b) => a.pretty.localeCompare(b.pretty));
templateInput.globalCommands.sort((a, b) => a.name.localeCompare(b.name));

const engine = new Liquid();
const template = await engine.parseFile(`./build/cli-reference.liquid`);
const output = await engine.render(template, templateInput);

try {
await fs.stat(path.dirname(outputPath));
await fs.writeFile(outputPath, output, {encoding: `utf-8`});
} catch (err) {
console.error(`Unable to write to file: ${err.message}`);
console.log();
console.log(output);
}
3 changes: 1 addition & 2 deletions app/knip.config.jsonc
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{
"entry": ["test/**/*.test.ts", "src/main.ts"],
"entry": ["test/**/*.test.ts", "src/main.ts", "build/cli-reference.ts", "build/schema.ts"],
"project": ["**/*.ts"],
"ignoreDependencies": [
"@typescript-eslint/eslint-plugin", // Loaded by eslint.config.json
"@typescript-eslint/parser", // Needed by @typescript-eslint/eslint-plugin
"eslint-config-xo", // Loaded by eslint.config.json
"eslint-plugin-tsdoc", // Loaded by eslint.config.json
"ts-json-schema-generator", // Loaded by 'build-schema' script
"typedoc-plugin-markdown", // Loaded by 'typedoc' script
"typedoc-github-wiki-theme" // Loaded by 'typedoc' script
],
Expand Down

0 comments on commit 2e5a7e6

Please sign in to comment.