diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 917261ed4..fbb1483ab 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,8 +1,9 @@ # This files defines code ownership. # General content -* @smahati * @renejeglinsky +node.js/ @smahati +java/ @smahati # Infra .github/ @chgeo @swaldmann diff --git a/.github/cli/grab-cli-texts.js b/.github/cli/grab-cli-texts.js new file mode 100755 index 000000000..6340e8df3 --- /dev/null +++ b/.github/cli/grab-cli-texts.js @@ -0,0 +1,52 @@ +#!/usr/bin/env node + +// CLI Help Extractor +// ============================ +// runs "npm exec --package= -c " to extract the command output and version +// of the latest tool version and writes it to stdout + +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 toOutput = (str) => [ + '', + `
`,
+    `> ${cmd}`,
+    '',
+    str
+        .replace(/\n.*home.*[|:].*/g, '') // remove absolute cds home path as it's system-specific
+        .replace(/\<(.*?)\>/g, '<$1>') //  -> <foo>
+        .replace(/^\x1b\[1m(.*?)\x1b\[(:?0|39|49)m\n/gm, '$1') // bold at beginning of line -> strong
+        .replace(/(\s*)\x1b\[4m(.*?)\x1b\[(:?0|39|49)m/g, '$1$2') // underline -> i
+        .replace(/(\s*)\x1b\[\d+m(.*?)\x1b\[(:?0|39|49)m/g, '$1$2') // other colors -> em
+    ,
+    `
` +].join('\n') + +try { + const version = (await exec(`npm view ${pkg} version`)).stdout.trim() + if (!/\d+\.\d+\.\d+/.test(version)) { + throw new Error(`unexpected version: ${version}`) + } + + const cmdString = `npm exec --package=${pkg}@${version} -c "${cmd}"` + // const cmdString = `${cmd}` // for local testing + console.error(`> ${cmdString}`) // use stderr for debugging output + 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 (!cmdOut || !cmdOut.includes('\n')) { + throw new Error(`no or invalid output from: ${cmdString}`) + } + // result is on stdout + console.log(toOutput(cmdOut.trim(), version.trim())) +} catch (e) { + console.error(`could not generate synopsis: ${e.message}`, e) +} diff --git a/.github/cli/grab-cli-texts.sh b/.github/cli/grab-cli-texts.sh new file mode 100755 index 000000000..6f76d18b9 --- /dev/null +++ b/.github/cli/grab-cli-texts.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +dir=`dirname -- "$0"` + +# create a temp project to run the commands in +proj=/tmp/your-project +rm -rf ${proj} +mkdir -p `dirname ${proj}` +pushd `dirname ${proj}` && cds init `basename ${proj}` && pushd `basename ${proj}` && npm i && popd && popd + +echo +echo "Grabbing CLI texts..." +${dir}/grab-cli-texts.js @cap-js/cds-typer "cds-typer --help" ${proj} > ${dir}/../../tools/assets/help/cds-typer.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds --help" ${proj} > ${dir}/../../tools/assets/help/cds-help.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds watch --help" ${proj} > ${dir}/../../tools/assets/help/cds-watch.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds version" ${proj} > ${dir}/../../tools/assets/help/cds-version.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds version --markdown" ${proj} > ${dir}/../../tools/assets/help/cds-version-md.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds env requires.db" ${proj} > ${dir}/../../tools/assets/help/cds-env-requires-db.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds env ls requires.db" ${proj} > ${dir}/../../tools/assets/help/cds-env-ls-requires-db.out.md +${dir}/grab-cli-texts.js @sap/cds-dk "cds -e .env.requires.db" ${proj} > ${dir}/../../tools/assets/help/cds-eval-env-requires-db.out.md diff --git a/.github/renovate.json b/.github/renovate.json index 6ca15c2a5..3168cb8b8 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -54,65 +54,5 @@ "depNameTemplate": "com.sap.cds:cds4j-api", "datasourceTemplate": "maven", "versioningTemplate": "maven" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*@sap/cds:\\s*\\s*(?\\d+\\.\\d+\\.\\d+)", - "\\|\\s*@sap/cds\\s*\\|\\s*(?\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "@sap/cds", - "datasourceTemplate": "npm" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*@sap/cds-compiler:\\s*\\s*(?\\d+\\.\\d+\\.\\d+)", - "\\|\\s*@sap/cds-compiler\\s*\\|\\s*(?\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "@sap/cds-compiler", - "datasourceTemplate": "npm" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*@sap/cds-dk:\\s*\\s*(?\\d+\\.\\d+\\.\\d+)", - "\\|\\s*@sap/cds-dk\\s*\\|\\s*(?\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "@sap/cds-dk", - "datasourceTemplate": "npm" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*@sap/cds-mtxs:\\s*\\s*(?\\d+\\.\\d+\\.\\d+)", - "\\|\\s*@sap/cds-mtxs\\s*\\|\\s*(?\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "@sap/cds-mtxs", - "datasourceTemplate": "npm" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*@sap/eslint-plugin-cds:\\s*\\s*(?\\d+\\.\\d+\\.\\d+)", - "\\|\\s*@sap/eslint-plugin-cds\\s*\\|\\s*(?\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "@sap/eslint-plugin-cds", - "datasourceTemplate": "npm" - }, - { - "customType": "regex", - "fileMatch": ["\\.md$"], - "matchStrings": [ - "\\s*Node.js:\\s*\\s*(?v\\d+\\.\\d+\\.\\d+)", - "\\|\\s*Node.js\\s*\\|\\s*(?v\\d+\\.\\d+\\.\\d+)\\s*\\|" - ], - "depNameTemplate": "nodejs", - "datasourceTemplate": "node" } ]} diff --git a/.github/typer/grab-typer-synopsis.js b/.github/typer/grab-typer-synopsis.js new file mode 100755 index 000000000..3ce64f4ec --- /dev/null +++ b/.github/typer/grab-typer-synopsis.js @@ -0,0 +1,46 @@ +#!/usr/bin/env node + +// cds-typer Synopsis Extractor +// ============================ +// runs "npx @cap-js/cds-typer --help" to extract the synopsis and version +// of the latest cds-typer version and writes it to a markdown file +// that is included in the cds-typer documentation page. + +import * as fs from 'node:fs' +import * as path from 'node:path' +import * as proc from 'node:child_process' +import * as util from 'node:util' + +const exec = util.promisify(proc.exec) +const tool = '@cap-js/cds-typer' +const includingFile = path.join('tools', 'cds-typer.md') +const synopsisFile = path.join('tools', 'cds-typer_help-output.md') + +const toMarkdown = (version, synopsis) => [ + '', + '```log', + `> ${tool}@${version} --help`, + '', + synopsis, + '```' +].join('\n') + +try { + const { stdout: version } = await exec(`npx ${tool} --version`) + const { stdout: synopsis } = await exec(`npx ${tool} --help`) + + // 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 (!synopsis || !/SYNOPSIS/.test(synopsis)) { + throw new Error(`unexpected synopsis: ${synopsis}`) + } + if (!fs.existsSync(includingFile)) { + throw new Error(`could not find file '${includingFile}', where to include the synopsis. Has the documentation for cds-typer moved?`) + } + fs.writeFileSync(synopsisFile, toMarkdown(version.trim(), synopsis)) +} catch (e) { + console.error(`could not run cds-typer to generate synopsis: ${e.message}`) +} diff --git a/.github/workflows/extract-docs.yml b/.github/workflows/extract-docs.yml new file mode 100644 index 000000000..6f71e7d47 --- /dev/null +++ b/.github/workflows/extract-docs.yml @@ -0,0 +1,47 @@ +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: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Extract CLI texts + run: | + npm i -g @sap/cds-dk + .github/cli/grab-cli-texts.sh + + - name: Check for changes + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + if git diff --exit-code; then + echo "No changes detected. Exiting." + exit 0 + fi + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: "update-cds-cli-texts" + commit-message: "Update CLI texts" + title: "chore: Update CLI texts" + body: "Updates the output of cds CLI texts to the latest version." diff --git a/.vitepress/config.ts b/.vitepress/config.ts index febdff501..7756df4ac 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -26,7 +26,7 @@ const redirectLinks: Record = {} const latestVersions = { java_services: '3.2.0', - java_cds4j: '3.2.0' + java_cds4j: '3.3.0' } const localSearchOptions = { @@ -105,7 +105,7 @@ const config:UserConfig = { ] as DefaultTheme.NavItem[], search: localSearchOptions, footer: { - message: 'Legal Disclosure | Terms of Use | Privacy', + message: `Legal Disclosure | Terms of Use | Privacy | Cookies`, copyright: `Copyright © 2019-${new Date().getFullYear()} SAP SE` }, editLink: { diff --git a/.vitepress/theme/components/ShortcutsList.vue b/.vitepress/theme/components/ShortcutsList.vue index 1be44fe89..aec4095c4 100644 --- a/.vitepress/theme/components/ShortcutsList.vue +++ b/.vitepress/theme/components/ShortcutsList.vue @@ -25,7 +25,7 @@