Skip to content

Commit

Permalink
Generic CLI output grabbing
Browse files Browse the repository at this point in the history
  • Loading branch information
chgeo committed Oct 1, 2024
1 parent 4130cf9 commit 2bc145a
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 137 deletions.
52 changes: 52 additions & 0 deletions .github/cli/grab-cli-texts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env node

// CLI Help Extractor
// ============================
// runs "npm exec <tool> --help" to extract the synopsis and version
// of the latest tool version and writes it to a markdown file
// that is included in a documentation page.

import * as proc from 'node:child_process'
import * as util from 'node:util'

const exec = util.promisify(proc.exec)
const pkg = process.argv[2]
if (!pkg) throw new Error('Missing package')
const cmd = process.argv[3] || pkg.split('/').pop()
const cwd = process.argv[4] || process.cwd()
const unstyled = process.argv.some(a => a === '--unstyled')

const toMarkdown = (version, str) => [
'<!-- this file is automatically generated and updated by a github action -->',
`${unstyled ? '```log' : '<pre class="log">'}`,
`> ${pkg}@${version} ${cmd}`,
'',
str
.replace(/\n.*home.*[|:].*/g, '') // remove absolute cds home path as it's system-specific
.replace(/\<(.*?)\>/g, '&lt;$1&gt;') // <foo> -> &lt;foo&gt;
.replace(/^\x1b\[1m(.*?)\x1b\[0m\n/gm, '<strong>$1</strong>') // bold at beginning of line -> strong
.replace(/(\s*)\x1b\[4m(.*?)\x1b\[0m/g, '$1<i>$2</i>') // underline -> i
.replace(/(\s*)\x1b\[\d+m(.*?)\x1b\[0m/g, '$1<em>$2</em>') // other colors -> em
, `${unstyled ? '```' : '</pre>'}`
].join('\n')

try {
const cmdString = `npm exec --package=${pkg} -c "${cmd}"`
const { stdout: version } = await exec(`npm view ${pkg} version`)
const { stdout: cmdOut } = await exec(cmdString, {cwd, env: { FORCE_COLOR: 'true', ...process.env }})

// some very basic plausibility checks to make sure we don't
// end up with garbage or npx errors in the markdown
if (!/\d+\.\d+\.\d+/.test(version)) {
throw new Error(`unexpected version: ${version}`)
}
if (!cmdOut) {
throw new Error(`no output from: ${cmdString}`)
}
if (cmd.includes('help') && !/SYNOPSIS|USAGE/.test(cmdOut)) {
throw new Error(`unexpected synopsis: ${cmdOut}`)
}
console.log(toMarkdown(version.trim(), cmdOut.trim()))
} catch (e) {
console.error(`could not generate synopsis: ${e.message}`, e)
}
31 changes: 22 additions & 9 deletions .github/workflows/extract-docs.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
name: PR Latest cds-typer Output
name: Update CLI Texts

on:
workflow_dispatch:
schedule:
# Runs every Wednesday at 02:45 AM (UTC)
- cron: '45 2 * * 3'

permissions:
contents: write
pull-requests: write

jobs:
run_script_and_create_pr:
runs-on: ubuntu-latest
Expand All @@ -19,8 +23,15 @@ jobs:
with:
node-version: '20'

- name: Extract cds-typer --help text
run: node .github/typer/grab-typer-synopsis.js
- name: Extract CLI texts
run: |
npm i -g @sap/cds-dk
pushd /tmp && rm -rf your-project && cds init your-project && pushd your-project && npm i && popd && popd
.github/cli/grab-cli-texts.js @cap-js/cds-typer "cds-typer --help" /tmp/your-project > tools/assets/help/cds-typer.out.md
.github/cli/grab-cli-texts.js @sap/cds-dk "cds --help" /tmp/your-project > tools/assets/help/cds-help.out.md
.github/cli/grab-cli-texts.js @sap/cds-dk "cds watch --help" /tmp/your-project > tools/assets/help/cds-watch.out.md
.github/cli/grab-cli-texts.js @sap/cds-dk "cds version" /tmp/your-project > tools/assets/help/cds-version.out.md
.github/cli/grab-cli-texts.js @sap/cds-dk "cds version --markdown" /tmp/your-project > tools/assets/help/cds-version-md.out.md
- name: Check for changes
run: |
Expand All @@ -34,19 +45,21 @@ jobs:
- name: Commit changes
run: |
git commit -m "Update cds-typer synopsis"
git commit -m "Update CLI texts"
- name: Push changes
id: push_changes
run: |
BRANCH_NAME="update-cds-typer-synopsis-$(date +'%Y%m%d%H%M%S')"
BRANCH_NAME="update-cds-cli-texts-$(date +'%Y%m%d%H%M%S')"
git checkout -b "$BRANCH_NAME"
git push origin "$BRANCH_NAME"
echo "::set-output name=BRANCH_NAME::$BRANCH_NAME"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
uses: peter-evans/create-pull-request@v7
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ steps.push_changes.outputs.BRANCH_NAME }}
title: "chore: Update synopsis for cds-typer"
body: "Updates the output of `cds-typer --help` to the latest version."
title: "chore: Update CLI texts"
body: "Updates the output of cds CLI texts to the latest version."
base: main
39 changes: 39 additions & 0 deletions tools/assets/help/cds-help.out.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!-- this file is automatically generated and updated by a github action -->
<pre class="log">
> @sap/[email protected] cds --help --help

<strong>USAGE</strong>
<em>cds</em> &lt;command&gt; [&lt;args&gt;]
<em>cds</em> &lt;src&gt; = <em>cds compile</em> &lt;src&gt;
<em>cds</em> = <em>cds help</em>

<strong>COMMANDS</strong>
<em>i</em> | <em>init</em> jump-start cds-based projects
<em>a</em> | <em>add</em> add a feature to an existing project
<em> </em> | <em>gen</em> generate models/data using a descriptive prompt [beta]
<em>y</em> | <em>bind</em> bind application to remote services
<em>m</em> | <em>import</em> add models from external sources
<em>c</em> | <em>compile</em> compile cds models to different outputs
<em>p</em> | <em>parse</em> parses given cds models
<em>s</em> | <em>serve</em> run your services in local server
<em>w</em> | <em>watch</em> run and restart on file changes
<em> </em> | <em>mock</em> call <i>cds serve</i> with mocked service
<em>r</em> | <em>repl</em> read-eval-event loop
<em>e</em> | <em>env</em> inspect effective configuration
<em>b</em> | <em>build</em> prepare for deployment
<em>d</em> | <em>deploy</em> deploy to databases or cloud
<em> </em> | <em>subscribe</em> subscribe a tenant to a multitenant SaaS app
<em> </em> | <em>unsubscribe</em> unsubscribe a tenant from a multitenant SaaS app
<em>l</em> | <em>login</em> login to extensible multitenant SaaS app
<em> </em> | <em>logout</em> logout from extensible multitenant SaaS app
<em> </em> | <em>pull</em> pull base model of extensible SaaS app
<em> </em> | <em>push</em> push extension to extensible SaaS app
<em>t</em> | <em>lint</em> run linter for env or model checks
<em>v</em> | <em>version</em> get detailed version information
<em> </em> | <em>completion</em> add/remove cli completion for cds commands
<em>?</em> | <em>help</em> get detailed usage information

Learn more about each command using:
<em>cds help</em> &lt;command&gt; or
<em>cds</em> &lt;command&gt; <em>--help</em>
</pre>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!-- this file is automatically generated and updated by a github action -->
```log
> @cap-js/[email protected] --help
<pre class="log">
> @cap-js/[email protected] cds-typer --help

SYNOPSIS

Expand All @@ -16,52 +16,45 @@ OPTIONS

This text.

--inlineDeclarations
--inline_declarations: <flat | structured>
--IEEE754Compatible: &lt;true | false&gt;
(default: false)

If set to true, floating point properties are generated
as IEEE754 compatible '(number | string)' instead of 'number'.

--inlineDeclarations: &lt;flat | structured&gt;
(default: structured)

Whether to resolve inline type declarations
flat: (x_a, x_b, ...)
or structured: (x: {a, b}).

--IEEE754Compatible
--ieee754compatible: <true | false>
(default: false)
If set to true, floating point properties are generated
as IEEE754 compatible '(number | string)' instead of 'number'.
--jsConfigPath
--js_config_path: <string>
--jsConfigPath: &lt;string&gt;

Path to where the jsconfig.json should be written.
If specified, cds-typer will create a jsconfig.json file and
set it up to restrict property usage in types entities to
existing properties only.

--logLevel
--log_level SILENT | ERROR | WARN | INFO | DEBUG | TRACE | SILLY | VERBOSE
--logLevel SILENT | ERROR | WARN | INFO | DEBUG | TRACE | SILLY | VERBOSE
(default: ERROR)

Minimum log level that is printed.
The default is only used if no explicit value is passed
and there is no configuration passed via cds.env either.

--outputDirectory
--output_directory: <string>
--outputDirectory: &lt;string&gt;
(default: ./)

Root directory to write the generated files to.

--propertiesOptional
--properties_optional: <true | false>
--propertiesOptional: &lt;true | false&gt;
(default: true)

If set to true, properties in entities are
always generated as optional (a?: T).

--useEntitiesProxy
--use_entities_proxy: <true | false>
--useEntitiesProxy: &lt;true | false&gt;
(default: false)

If set to true the 'cds.entities' exports in the generated 'index.js'
Expand All @@ -74,5 +67,4 @@ OPTIONS
--version

Prints the version of this tool.
```
</pre>
17 changes: 17 additions & 0 deletions tools/assets/help/cds-version-md.out.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!-- this file is automatically generated and updated by a github action -->
<pre class="log">
> @sap/[email protected] cds version --markdown

| your-project | &lt;Add your repository here&gt; |
| ---------------------- | ---------------------------------------------------------------------------------------- |
| @cap-js/asyncapi | 1.0.2 |
| @cap-js/openapi | 1.0.5 |
| @sap/cds | 8.3.0 |
| @sap/cds-compiler | 5.3.0 |
| @sap/cds-dk (global) | 8.4.0 |
| @sap/cds-fiori | 1.2.7 |
| @sap/cds-foss | 5.0.1 |
| @sap/cds-mtxs | 2.1.1 |
| @sap/eslint-plugin-cds | 3.0.6 |
| Node.js | v22.8.0 |
</pre>
16 changes: 16 additions & 0 deletions tools/assets/help/cds-version.out.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- this file is automatically generated and updated by a github action -->
<pre class="log">
> @sap/[email protected] cds version

<em>@cap-js/asyncapi</em>: 1.0.2
<em>@cap-js/openapi</em>: 1.0.5
<em>@sap/cds</em>: 8.3.0
<em>@sap/cds-compiler</em>: 5.3.0
<em>@sap/cds-dk (global)</em>: 8.4.0
<em>@sap/cds-fiori</em>: 1.2.7
<em>@sap/cds-foss</em>: 5.0.1
<em>@sap/cds-mtxs</em>: 2.1.1
<em>@sap/eslint-plugin-cds</em>: 3.0.6
<em>Node.js</em>: v22.8.0
<em>your-project</em>: 1.0.0
</pre>
44 changes: 44 additions & 0 deletions tools/assets/help/cds-watch.out.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- this file is automatically generated and updated by a github action -->
<pre class="log">
> @sap/[email protected] cds watch --help

<strong>SYNOPSIS</strong>
<em>cds watch</em> [&lt;project&gt;]

Tells cds to watch for relevant things to come or change in the specified
project or the current work directory. Compiles and (re-)runs the server
on every change detected.

Actually, cds watch is just a convenient shortcut for:
<em>cds serve all --with-mocks --in-memory?</em>

<strong>OPTIONS</strong>
<em>--port</em> &lt;number&gt;

Specify the port on which the launched server listens.
If you specify '0', the server picks a random free port.
Alternatively, specify the port using env variable <i>PORT</i>.

<em>--ext</em> &lt;extensions&gt;

Specify file extensions to watch for in a comma-separated list.
<em>Example:</em> cds w --ext cds,json,js.

<em>--livereload</em> &lt;port | false&gt;

Specify the port for the livereload server. Defaults to '35729'.
Disable it with value <i>false</i>.

<em>--open</em> &lt;url&gt;

Open the given URL (suffix) in the browser after starting.
If none is given, the default application URL will be opened.

<em>--profile</em> &lt;profile,...&gt;

Specify from which profile(s) the binding information is taken.
<em>Example:</em> cds w --profile hybrid,production

<strong>SEE ALSO</strong>
<em>cds serve --help</em> for the different start options.
</pre>
Loading

0 comments on commit 2bc145a

Please sign in to comment.