From 1649f0c3b850fabcb37d2617f7bc5addf2d8ec0a Mon Sep 17 00:00:00 2001 From: Eric Schneider <37347760+eric-schneider@users.noreply.github.com> Date: Mon, 6 May 2024 01:29:31 -0700 Subject: [PATCH] Add unified docs assets --- .github/workflows/dispatch-gh-pages-build.yml | 50 ++++ .gitignore | 129 +-------- README.adoc | 270 ++++++++---------- build-locally.sh | 85 ------ docs-src/astra-cli-core/antora-astra-cli.yml | 11 - docs-src/astra-cli-core/antora.yml | 12 +- lib/remote-include-processor.js | 199 +++++++++++++ lib/svg-macro.js | 110 +++++++ lib/tailwind-processor.js | 12 + lib/unlisted-pages-extension.js | 41 +++ local-preview-playbook.yml | 73 +++++ package.json | 37 ++- playbooks/site-local-astra-cli.yaml | 126 -------- playbooks/site-publish-astra-cli.yaml | 135 --------- 14 files changed, 643 insertions(+), 647 deletions(-) create mode 100644 .github/workflows/dispatch-gh-pages-build.yml delete mode 100755 build-locally.sh delete mode 100644 docs-src/astra-cli-core/antora-astra-cli.yml mode change 120000 => 100644 docs-src/astra-cli-core/antora.yml create mode 100644 lib/remote-include-processor.js create mode 100644 lib/svg-macro.js create mode 100644 lib/tailwind-processor.js create mode 100644 lib/unlisted-pages-extension.js create mode 100644 local-preview-playbook.yml delete mode 100644 playbooks/site-local-astra-cli.yaml delete mode 100644 playbooks/site-publish-astra-cli.yaml diff --git a/.github/workflows/dispatch-gh-pages-build.yml b/.github/workflows/dispatch-gh-pages-build.yml new file mode 100644 index 0000000..17556a6 --- /dev/null +++ b/.github/workflows/dispatch-gh-pages-build.yml @@ -0,0 +1,50 @@ +name: Dispatch Deploy to GitHub Pages + +on: + push: + branches: + - 'main' + - 'stage' + # Add additional content source branches here + pull_request: + branches: + - '*' + +jobs: + dispatch-deploy: + runs-on: ubuntu-latest + + steps: + # Determine the build branch and draft branch for dispatch. + - name: Determine Dispatch Parameters + run: | + if [ "${{ github.event_name }}" == "pull_request" ]; then + # If this workflow is kicked off by a pull request, build + # a draft using the pull resource base branch and PR branch. + build_branch="${{ github.base_ref }}" + draft_branch="${{ github.event.pull_request.head.ref }}" + else + if [ "$(basename ${{ github.event.ref }})" == "stage" ]; then + # This was a merge to stage so kick off a build to update stage draft. + build_branch=stage + draft_branch=stage + else + # Otherwise this is a push to one of the source branches so + # dispatch a build for the main draft to pick up the changes. + build_branch=main + draft_branch=main + fi + fi + echo "build_branch=$build_branch" >> $GITHUB_OUTPUT + echo "draft_branch=$draft_branch" >> $GITHUB_OUTPUT + id: branches + + - name: Dispatch Deploy to GitHub Pages + uses: convictional/trigger-workflow-and-wait@v1.6.1 + with: + owner: riptano + repo: datastax-docs-site + github_token: ${{ secrets.DISPATCH_GITHUB_TOKEN }} + github_user: mlr + workflow_file_name: gh-pages-build.yml + client_payload: '{ "build_repository": "${{ github.event.repository.full_name }}", "build_branch": "${{ steps.branches.outputs.build_branch }}", "draft_branch": "${{ steps.branches.outputs.draft_branch }}", "pull_request_number": "${{ github.event.pull_request.number }}" }' diff --git a/.gitignore b/.gitignore index fb127a5..6bada63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,114 +1,15 @@ -build -.DS_store -*~ -package-lock.json -.vscode -.java-version - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# IDE -.idea/ +#OS +**/.DS_Store +**/.git-credentials + +#IDE +**/.vscode/ +**/.idea +**/*.iml +*.http +**/.java-version + +#build +**/package-lock.json +**/node_modules/ +/build/ \ No newline at end of file diff --git a/README.adoc b/README.adoc index a73efdd..17e824a 100644 --- a/README.adoc +++ b/README.adoc @@ -1,201 +1,159 @@ -= DataStax {product} Documentation -:toc: macro += {company} {product} Docs +// Variables: +:company: DataStax :product: Astra CLI -:product-repo-name: astra-cli-docs -:product-repo-name-long: datastax/astra-cli-docs -:product-repo-link: https://github.com/datastax/astra-cli-docs.git -:product-branch-name: main -:docset-name: astra-cli -:product-branch-link: main -:install-git-link: https://github.com/git-guides/install-git -:create-pr-link: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request -:nvm-link: https://github.com/nvm-sh/nvm -:homebrew-link: https://brew.sh/ -:asciidoctor-link: https://docs.asciidoctor.org/asciidoc/latest/ -:antora-link: https://docs.antora.org/antora/latest/ -:contributor-docs-link: https://docs.google.com/presentation/d/10RjxURHpJ8gwac0dCZ02pKo31nGhem29Z8-xERApyWU/edit?usp=sharing -:web-server-link: https://www.npmjs.com/package/serve - -This repo contains the documentation source files for the DataStax {product} documentation. - -The docs are written in {asciidoctor-link}[AsciiDoc] and use {antora-link}[Antora] to generate the HTML output. +:repo-name: astra-cli-docs +:github-org: datastax +// Settings: +:toc: macro +:!example-caption: +:experimental: +:hide-uri-scheme: +ifdef::env-github[] +:icons: font +:toclevels: 1 +:toc-title: Contents +:tip-caption: :bulb: +:note-caption: :information_source: +:important-caption: :heavy_exclamation_mark: +:caution-caption: :fire: +:warning-caption: :warning: +:badges: +endif::[] +// Project URLs: +:url-github-org: https://github.com/{github-org} +:url-project-repo: {url-github-org}/{repo-name} +:url-ui-repo: https://github.com/riptano/docs-ui +:url-playbook-repo: https://github.com/riptano/datastax-docs-site +:url-contribute: +:url-datastax: https://datastax.com +:url-datastax-docs: https://docs.datastax.com +:url-docs-preview: http://docs-preview.datastax.com +// External URLs: +:asciidoc-language: https://docs.asciidoctor.org/asciidoc/latest/ + +This repository contains the source files for the {company} {product} documentation. toc::[] -== Contributing to the docs - -Although this repo is maintained by the DataStax Docs team, contributions from the community are gratefully accepted, and encouraged. - -_Why should you contribute to the {product} docs?_:: -* It makes the Docs team's job easier. -* It makes your job easier. -* It helps DataStax and Cassandra users more quickly. +== Get started -_How do you contribute?_:: -The majority of DataStax documentation source files are written in AsciiDoc, a lightweight, human-readable markup language. -You can contribute to the documentation by adding content to, or editing, the AsciiDoc files in this repo. +The documentation is written in {asciidoc-language}[AsciiDoc]-formatted source files located in the `modules` directory. -For instructions, see <> below. +=== Make a simple update -[[writing-asciidoc]] -== Working with {product} docs +For simple updates like fixing typos or modifying existing prose, it's easiest to edit the source files directly on GitHub. -Before following the steps below, first make sure that you have {install-git-link}[git] installed on your computer. +NOTE: You'll need Write privileges on the repository to edit files directly on GitHub. -. Using a terminal, clone the {product-repo-link}[{product-repo-name}] repository (this repository) onto your computer. -+ -[source,shell,subs="attributes+"] ----- -git clone {product-repo-link} ----- -. `cd` into the cloned repo. -+ -[source,shell,subs="attributes+"] ----- -cd {product-repo-name} ----- -. If you have previously cloned the repo, switch to the `{product-branch-name}` branch and do a `git pull` to get the latest changes. -+ -[source,shell,subs="attributes+"] ----- -git checkout {product-branch-name} && git pull ----- -. Create a working branch. -+ -[source,shell,subs="attributes+"] ----- -git checkout -b ----- -+ -Replace `` with a descriptive name or a related JIRA ticket number. -. Locate the `.adoc` file that you wish to edit and open it in your preferred editor (`.adoc` files are stored in the `docs-src` directory). -Make sure to save your changes once you're done making edits. -+ -If adding a new page, make sure to add it to the appropriate location in the `docs-src` directory and then update the appropriate navigation file (`nav.adoc`) so that the new page will show up in the left-hand navigation of the docs website. -. Preview your changes by running a <>. -. Commit your changes. -+ -[source,shell,subs="attributes+"] ----- -git commit -m "" ----- -. Push your changes to GitHub. -+ -[source,shell,subs="attributes+"] ----- -git push -u origin ----- +. Find the file you want to edit in the `modules` directory. -=== Submitting your changes +. Click the *Edit* icon in the upper-right corner of the file view. -Once all of your changes are pushed to GitHub, you'll need to submit them for review by creating a {create-pr-link}[pull request]. +. Make your changes in the editor. -. Create your pull request against the {product-branch-link}[{product-branch-name}] branch. -. Assign someone from the docs team as a reviewer. - * https://github.com/jgillenwater[@jgillenwater] - * https://github.com/polandll[@polandll] +. Click *Commit changes...* -The docs team will review, ask questions, make requests, and merge your changes. -The docs team will then update the published documentation to reflect your changes. +. Enter a description for your commit and click *Propose changes*. -For more information on contributing to the docs, click {contributor-docs-link}[here]. +. On the *Open a pull request* screen, enter a title and description for your change, assign reviewers, then click *Create pull request*. -[[build-locally]] -== Generating and viewing the HTML output locally +. Once the pull request is open, an automatic draft preview build is triggered. +Once complete, the build system posts a comment on the pull request with a link to the draft site for you to preview your changes. -You can generate the HTML docs locally to view changes and check your work. -Note that these steps assume you've already cloned the {product-repo-link}[{product-repo-name}] repo and checked out the `{product-branch-name}` branch (see <> for more information). +=== Edit docs locally -Using a terminal, `cd` into the cloned repo directory and run the following command: +If you need to make substantial updates to the documentation, you'll want to clone the repository so you can work with the source files locally. -[source,shell,subs="attributes+"] +. Clone this repository ++ +[source,bash,subs="attributes"] ---- -./build-locally.sh {docset-name} +git clone {url-project-repo}.git ---- -.Dependencies +. https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic[Create a _classic_ personal access token] for your GitHub account. +When configuring the token, set the *Expiration* to at least 90 days and select everything under the *Repo* https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes[scope]. ++ [IMPORTANT] ==== -The `build-locally.sh` script requires {nvm-link}[`nvm`] to be installed on your system in order to install and update the rest of the required dependencies. -If you're running macOS and have {homebrew-link}[Homebrew] installed, the script will automatically install `nvm` for you. -If you're running on another platform (or don't use Homebrew), you'll need to manually install `nvm` before running the above command. +Copy your personal access token to a temporary location -- you'll need it later. ==== -If the docs built successfully, you'll see output similar to the following: +. https://docs.github.com/en/enterprise-cloud@latest/authentication/authenticating-with-saml-single-sign-on/authorizing-a-personal-access-token-for-use-with-saml-single-sign-on[Authorize your personal access token] so that it can access repositories in the Riptano and DataStax organizations in GitHub. -[source,console,subs="attributes+"] +. https://docs.antora.org/antora/latest/playbook/private-repository-auth/#populate-credentials-directly[Populate the credential store] with your personal access token. +For most people this means doing the following: ++ +.. Create the file `$HOME/.git-credentials` and open it in your editor. +.. Add the following line: ++ +[source,subs="verbatim,quotes"] ---- -Site generation complete! -Open file:///Users/your-user-name/{product-repo-name}/build/{docset-name} in a browser to view your site. - -Do you want to start a local web server for viewing the generated docs? (Y or N) +https://**TOKEN**:@github.com ---- ++ +Replace *`TOKEN`* with the personal access token you copied from GitHub. +.. Save and close the file. -The `build-locally.sh` script prints the local file path of the generated docs, and prompts you about starting a local {web-server-link}[web server] for viewing the docs. -Since the generated docs HTML files can be viewed directly in a web browser without the need for a web server, most users should answer *N* to the prompt. -(The web server is only required for viewing certain advanced functionality of the site build.) - -.To view the generated HTML files directly (most users) -. Copy the entire `file:` path from the terminal output, and open it in a web browser. -. In the file browser, click *docs*, then click on any of the `.html` files. -. From here, you can browse the documentation just like you would on docs.datastax.com. -. If you end up making further edits to the documentation, simply run the `build-locally.sh` script again to view your latest changes. +. If you don't already have Node.js installed, do the following: -.To view the docs using the local web server (advanced users) -. When prompted to start the local web server, type *Y* and press *Return*. +.. Install https://github.com/nvm-sh/nvm[nvm]. + -When the web server starts up, you'll see output similar to the following: +If you're on macOS, you can install nvm using https://brew.sh/[Homebrew]: + +[source,bash] ---- - ┌────────────────────────────────────────────────────┐ - │ │ - │ Serving! │ - │ │ - │ - Local: http://localhost:3000 │ - │ - On Your Network: http://192.168.86.141:3000 │ - │ │ - │ Copied local address to clipboard! │ - │ │ - └────────────────────────────────────────────────────┘ +brew install nvm ---- -. Copy the `Local:` address (in this case, `\http://localhost:3000`) and open it in a web browser. -. From the *Index of {product-repo-name}/* page, click *build/ > {docset-name}/ > docs/* -. From here, you can browse the documentation just like you would on docs.datastax.com. -. Once you're done viewing the documentation, go back to your terminal window and press *Ctrl+C* to shut down the web server. -. If you end up making further edits to the documentation, simply run the `build-locally.sh` script again to view your latest changes. -== Repo dependencies - -The `build-locally.sh` script should take care of installations required to build the docs. -However, if you get a message that you need to install NodeJS, run the following commands (macOS): - -[source,shell,subs="attributes+"] +.. Use nvm to install Node.js. ++ +[source,bash] ---- -brew install node +nvm install --lts +---- ++ +[source,bash] +---- +nvm use --lts +---- ++ +[source,bash] +---- +nvm alias default node ---- -[source,shell,subs="attributes+"] +. Install the project dependencies. ++ +[source,bash,subs="attributes"] +---- +cd {repo-name} +---- ++ +[source,bash] ---- npm install ---- -=== Dependencies in package.json - -There are some key dependencies for building the DataStax documentation. - -[source,json,subs="attributes+"] +. Build the site. ++ +[source,bash] ---- - "dependencies": { - "@antora/cli": "~3.0.1", - "@antora/site-generator-default": "~3.0.1", - "linkinator": "~3.0.3", - "async": "~3.2.4", - "mobx": "~6.0.4", - "react": "~16.8.4", - "react-dom": "~16.8.4", - "rxjs": "~7.0.1", - "styled-components": "~5.1.1" - } +npm run build:local ---- ++ +If the build was successful, you'll see the following output in your terminal: ++ +[source,console,subs="attributes"] +---- +Site generation complete! +Open file:///Users/USERNAME/repos/{repo-name}/build/site/index.html in a browser to view your site. +---- ++ +To view the site, paste the entire `\file:///` path into your browser's address bar and press kbd:[Return]. + +[#publish-docs] +== Publish docs -`@antora/cli` and `@antora/site-generator-default` are requirements to build with Antora. +To learn how to publish documentation to {url-datastax-docs}, see the {url-playbook-repo}#deploy-production[datastax-docs-site README]. diff --git a/build-locally.sh b/build-locally.sh deleted file mode 100755 index 35e4323..0000000 --- a/build-locally.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# get the product docset that is going to be run - -case $1 in - ( 'astra-cli' ) echo "product: $1";; - (*) echo "pick astra-cli" && exit;; -esac - -echo "checking prerequisites" - -# check if nvm is running and up-to-date - -. ~/.nvm/nvm.sh -. ~/.profile -. ~/.bashrc - -nvmversion=$(nvm --version) -echo "nvm version: ${nvmversion}" - -if [ $nvmversion != 0.39.0 ]; then - # update homebrew list of packages and either update or install nvm - echo "Updating/installing nvm - please be patient, this takes time" - brew update - brew install nvm -fi - -# check if node is running and the version - -nodeversion=$(node -v) -echo "node version: ${nodeversion}" - -if [ $nodeversion != 'v16.13.1' ]; then - # use nvm to install version 16 and change nvm to use it - nvm install 16 - nvm use 16 -fi - -# check if npm is running and the version - -npmversion=$(npm -v) -echo "npm version: ${npmversion}" - -if [ $npmversion != '8.5.5' ]; then - npm install -fi - -# check the antora version - -antoraversion=$(npm info antora version) -echo "antora version: ${antoraversion}" - -if [$antoraversion != 3.0.1 ]; then - npm install antora -fi - -# remove the antora symlinks that exist -# and set the antora symlinks to the correct product docset -# finally, run the corresponding product docset playbook - -case $1 in - - astra-cli) - echo "product is astra-cli" - echo "make antora.yml links" - cd docs-src/astra-cli-core - rm antora.yml; ln -s antora-astra-cli.yml antora.yml - # cd ../astra-cli-core - # rm antora.yml; ln -s antora-astra-cli.yml antora.yml - cd ../.. - echo "run the build" - npm run build:local:astra-cli - ;; - -esac - -echo -read -p "Do you want to start a local web server for viewing the generated docs? (Y or N)" server - -if [ $server = "Y" ] || [ $server = "y" ]; - then - npm i -g serve; serve - else - exit; -fi diff --git a/docs-src/astra-cli-core/antora-astra-cli.yml b/docs-src/astra-cli-core/antora-astra-cli.yml deleted file mode 100644 index 503bd7f..0000000 --- a/docs-src/astra-cli-core/antora-astra-cli.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: astra-cli -title: Astra CLI -version: '0.2' -start_page: index.adoc - -nav: -- modules/ROOT/nav.adoc - -asciidoc: - attributes: - astra_cli: 'Astra CLI' diff --git a/docs-src/astra-cli-core/antora.yml b/docs-src/astra-cli-core/antora.yml deleted file mode 120000 index eb12b4b..0000000 --- a/docs-src/astra-cli-core/antora.yml +++ /dev/null @@ -1 +0,0 @@ -antora-astra-cli.yml \ No newline at end of file diff --git a/docs-src/astra-cli-core/antora.yml b/docs-src/astra-cli-core/antora.yml new file mode 100644 index 0000000..503bd7f --- /dev/null +++ b/docs-src/astra-cli-core/antora.yml @@ -0,0 +1,11 @@ +name: astra-cli +title: Astra CLI +version: '0.2' +start_page: index.adoc + +nav: +- modules/ROOT/nav.adoc + +asciidoc: + attributes: + astra_cli: 'Astra CLI' diff --git a/lib/remote-include-processor.js b/lib/remote-include-processor.js new file mode 100644 index 0000000..731a0a0 --- /dev/null +++ b/lib/remote-include-processor.js @@ -0,0 +1,199 @@ +const CIRCUMFIX_COMMENT_SUFFIX_RX = / (?:\*[/)]|--%?>)$/ +const NEWLINE_RX = /\r\n?|\n/ +const TAG_DELIMITER_RX = /[,;]/ +const TAG_DIRECTIVE_RX = /\b(?:tag|(end))::(\S+)\[\]$/ +const LINES_DOTDOT_RX = /\.\./ + + +function getTags (attrs) { + if ( 'tag' in attrs ) { + const tag = attrs['tag'] + if (tag && tag !== '!') { + return tag.charAt() === '!' ? new Map().set(tag.substr(1), false) : new Map().set(tag, true) + } + } else if ( 'tags' in attrs ) { + const tags = attrs['tags'] + if (tags) { + let result = new Map() + let any = false + tags.split(TAG_DELIMITER_RX).forEach((tag) => { + if (tag && tag !== '!') { + any = true + tag.charAt() === '!' ? result.set(tag.substr(1), false) : result.set(tag, true) + } + }) + if (any) return result + } + } +} + + +function applyTagFiltering (contents, tags) { + let selecting, selectingDefault, wildcard + if (tags.has('**')) { + if (tags.has('*')) { + selectingDefault = selecting = tags.get('**') + wildcard = tags.get('*') + tags.delete('*') + } else { + selectingDefault = selecting = wildcard = tags.get('**') + } + tags.delete('**') + } else { + selectingDefault = selecting = !Array.from(tags.values()).includes(true) + if (tags.has('*')) { + wildcard = tags.get('*') + tags.delete('*') + } + } + + const lines = [] + const tagStack = [] + const usedTags = [] + let activeTag + let lineNum = 0 + let startLineNum + contents.split(NEWLINE_RX).forEach((line) => { + lineNum++ + let m + let l = line + if ( + (l.endsWith('[]') || + (~l.indexOf('[] ') && + (m = l.match(CIRCUMFIX_COMMENT_SUFFIX_RX)) && + (l = l.substr(0, m.index)).endsWith('[]'))) && + (m = l.match(TAG_DIRECTIVE_RX)) + ) { + const thisTag = m[2] + if (m[1]) { + if (thisTag === activeTag) { + tagStack.shift() + ;[activeTag, selecting] = tagStack.length ? tagStack[0] : [undefined, selectingDefault] + } else if (tags.has(thisTag)) { + const idx = tagStack.findIndex(([name]) => name === thisTag) + if (~idx) { + tagStack.splice(idx, 1) + //console.warn(`line ${lineNum}: mismatched end tag in include: expected ${activeTag}, found ${thisTag}`) + } + //} else { + // //console.warn(`line ${lineNum}: unexpected end tag in include: ${thisTag}`) + //} + } + } else if (tags.has(thisTag)) { + usedTags.push(thisTag) + tagStack.unshift([(activeTag = thisTag), (selecting = tags.get(thisTag))]) + } else if (wildcard !== undefined) { + selecting = activeTag && !selecting ? false : wildcard + tagStack.unshift([(activeTag = thisTag), selecting]) + } + } else if (selecting) { + if (!startLineNum) startLineNum = lineNum + lines.push(line) + } + }) + // Q: use _.difference(Object.keys(tags), usedTags)? + //const missingTags = Object.keys(tags).filter((e) => !usedTags.includes(e)) + //if (missingTags.length) { + // console.warn(`tag${missingTags.length > 1 ? 's' : ''} '${missingTags.join(',')}' not found in include`) + //} + return [lines, startLineNum || 1] +} + +function getLines (attrs) { + if ( 'lines' in attrs ) { + const lines = attrs['lines'] + if (lines) { + // console.warn(`have lines` + lines) + let result = [] // new Map() + let any = false + lines.split(TAG_DELIMITER_RX).forEach((line) => { + if (line && line !== '!') { + let tryMultipleLines = line.split(LINES_DOTDOT_RX) + if ( tryMultipleLines.length === 1 ) { + any = true + result.push([tryMultipleLines[0], tryMultipleLines[0]]) + } + else if ( tryMultipleLines.length === 2 ) { + any = true + result.push([tryMultipleLines[0], tryMultipleLines[1]]) + } + } + }) + if (any) return result + } + } +} + +function filterChars(content){ + let myRegexp = new RegExp(/[^${\}]+(?=})/g); + let matches = myRegexp.exec(content); + + if(matches == null) + return content; + + let ret = content; + // matches.forEach(x => { + // let a = new RegExp("\\${"+x+"}",'gm'); + // ret = ret.replace(a,'asd'); + // }) + + return ret; +} + +function applyLineFiltering (contents, linesToInclude) { + const lines = [] + let lineNum = 0 + let startLineNum + let registerCurrentLine = false + + const nLinesPair = linesToInclude.length + let currentLinePair = 0 + let startLine = linesToInclude[currentLinePair][0] + let endLine = linesToInclude[currentLinePair][1] + // console.warn(`applyLineFiltering ` + startLine + ' and ' + endLine ) + + contents.split(NEWLINE_RX).forEach((line) => { + lineNum++ + + if ( !registerCurrentLine ) { + if ( lineNum == startLine ) + registerCurrentLine = true + } + + if ( registerCurrentLine ) + { + if (!startLineNum) startLineNum = lineNum + lines.push(line) + + if ( lineNum == endLine ) { + registerCurrentLine = false + currentLinePair++ + if ( currentLinePair >= nLinesPair ) + return [lines, startLineNum] + else { + startLine = linesToInclude[currentLinePair][0] + endLine = linesToInclude[currentLinePair][1] + } + } + } + }) + return [lines, startLineNum || 1] +} + +module.exports = function () { + this.includeProcessor(function () { + this.$option('position', '>>') + this.handles((target) => target.startsWith('https://')) + this.process((doc, reader, target, attrs) => { + const contents = require('child_process').execFileSync('curl', ['--silent', '-L', target], { encoding: 'utf8' }) + let includeContents = filterChars(contents) + let startLineNum = 1 + const tags = getTags(attrs) + const lines = getLines(attrs) + if (tags) [includeContents, startLineNum] = applyTagFiltering(includeContents, tags) + else if (lines) [includeContents, startLineNum] = applyLineFiltering(includeContents, lines) + reader.pushInclude(includeContents, target, target, startLineNum, attrs) + // reader.pushInclude(contents, target, target, 1, attrs) + }) + }) +} diff --git a/lib/svg-macro.js b/lib/svg-macro.js new file mode 100644 index 0000000..e7f5928 --- /dev/null +++ b/lib/svg-macro.js @@ -0,0 +1,110 @@ +const logger = require("@antora/logger")("asciidoctor:svg-macro"); + +/** + * @example Inline Embedded SVG + * svg:ROOT:ui/icons/vector.svg[] + */ +function inlineSvgMacro({ contentCatalog, file }) { + return function () { + this.process((parent, target, attrs) => { + svgContent = getSvgContent(target, file, contentCatalog); + if (!svgContent) return; + return this.createInlinePass( + parent, + svgContent.replace(" { + svgContent = getSvgContent(target, file, contentCatalog); + if (!svgContent) return; + const svgHtmlAttrs = htmlAttrs({ ...attrs, role: undefined }); + const containerHtmlAttrs = attrs.role + ? `class="imageblock ${attrs.role}"` + : 'class="imageblock"'; + const html = + `
` + + svgContent.replace("
"; + return this.createBlock(parent, "pass", html); + }); + }; +} + +/** + * This macro relies on the material-icons font being loaded in UI bundle. + * + * @example Material Icon + * icon:material-icons:menu_open[] + * + * @example Embedded SVG + * icon:ROOT:ui/icons/vector.svg[] + */ +function inlineIconMacro({ contentCatalog, file }) { + return function () { + this.process((parent, target, attrs) => { + if (target.startsWith("material-icons")) { + iconTarget = target + .replace("material-icons:", "") + .trim() + .replace("-", "_"); + return this.createInlinePass( + parent, + `${iconTarget}` + ); + } else { + svgContent = getSvgContent(target, file, contentCatalog); + if (!svgContent) return; + return this.createInlinePass( + parent, + svgContent.replace(" { + context.once('sitePublished', () => { + const logger = context.getLogger('tailwind-processor-extension') + logger.info('Building Tailwind') + execSync('npm run tailwindcss', { stdio: 'inherit' }) + logger.info('Tailwind Build Successful') + }) +} diff --git a/lib/unlisted-pages-extension.js b/lib/unlisted-pages-extension.js new file mode 100644 index 0000000..ec1b337 --- /dev/null +++ b/lib/unlisted-pages-extension.js @@ -0,0 +1,41 @@ +module.exports.register = function ({ config }) { + const { addToNavigation, unlistedPagesHeading = 'Unlisted Pages' } = config + const logger = this.getLogger('unlisted-pages-extension') + this + .on('navigationBuilt', ({ contentCatalog }) => { + contentCatalog.getComponents().forEach(({ versions }) => { + versions.forEach(({ name: component, version, navigation: nav, url: defaultUrl }) => { + const navEntriesByUrl = getNavEntriesByUrl(nav) + const unlistedPages = contentCatalog + .findBy({ component, version, family: 'page' }) + .filter((page) => page.out) + .reduce((collector, page) => { + // Check if the 'unlisted-page' attribute is set to true + if (page.asciidoc.attributes['unlisted-page'] === 'true') { + return collector; // Skip this page + } + if ((page.pub.url in navEntriesByUrl) || page.pub.url === defaultUrl) return collector + logger.warn({ file: page.src, source: page.src.origin }, 'detected unlisted page') + return collector.concat(page) + }, []) + if (unlistedPages.length && addToNavigation) { + nav.push({ + content: unlistedPagesHeading, + items: unlistedPages.map((page) => { + return { content: page.asciidoc.navtitle, url: page.pub.url, urlType: 'internal' } + }), + root: true, + }) + } + }) + }) + }) +} + +function getNavEntriesByUrl (items = [], accum = {}) { + items.forEach((item) => { + if (item.urlType === 'internal') accum[item.url.split('#')[0]] = item + getNavEntriesByUrl(item.items, accum) + }) + return accum +} diff --git a/local-preview-playbook.yml b/local-preview-playbook.yml new file mode 100644 index 0000000..4a5db88 --- /dev/null +++ b/local-preview-playbook.yml @@ -0,0 +1,73 @@ +runtime: + log: + failure_level: warn +git: + # ensure_git_suffix: false # Enable if necessary -- some git services don’t recognize the URL if it contains the .git extension. + fetch_concurrency: 10 + +site: + title: DataStax Docs + start_page: astra-cli::index.adoc + robots: disallow + +content: + branches: main # Sources default to this branch if none are specified. + sources: + - url: . + start_path: docs-src/astra-cli-core + branches: HEAD + +antora: + extensions: + - '@antora/collector-extension' + - lib/tailwind-processor.js + - id: unlisted-pages + enabled: true + require: lib/unlisted-pages-extension.js + add_to_navigation: false + unlisted_pages_heading: Orphans + +asciidoc: + extensions: + - '@asciidoctor/tabs' + - lib/remote-include-processor.js + - lib/svg-macro.js + - asciidoctor-kroki + - asciidoctor-external-callout + attributes: + # BUILT-IN ATTRIBUTES + allow-uri-read: '' # this has no effect in antora, but does help development in Intellij + experimental: '' + idprefix: '' + idseparator: '-' + # kroki-fetch-diagram: true + # kroki-server-url: + max-include-depth: 10 + page-toclevels: 2@ + sectlinks: '' + tabs-sync-option: '' + example-caption: false + figure-caption: false + table-caption: false + xrefstyle: short + # CUSTOM ATTRIBUTES + company: 'DataStax' + astra_db: 'Astra DB' + astra_stream: 'Astra Streaming' + astra_ui: 'Astra Portal' + support_url: 'https://support.datastax.com' + glossary-url: 'https://docs.datastax.com/en/glossary/docs/index.html#' + +urls: + latest_version_segment_strategy: redirect:from + latest_version_segment: 'latest' + +ui: + bundle: + url: https://github.com/riptano/docs-ui/releases/latest/download/ui-bundle.zip + # url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable + snapshot: true + # supplemental_files: supplemental-ui + +output: + dir: 'build/site' \ No newline at end of file diff --git a/package.json b/package.json index a14bc75..da7d094 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,25 @@ { - "name": "astra-cli", - "scripts": { - "build:prod:astra-cli": "npm run build:publish:astra-cli", - "build:dev:astra-cli": "npm run build:local:astra-cli", - "build:publish:astra-cli": "antora --stacktrace --fetch --clean playbooks/site-publish-astra-cli.yaml", - "build:local:astra-cli": "antora --stacktrace --fetch --clean playbooks/site-local-astra-cli.yaml", - "build:linkinator:astra-cli": "npx linkinator https://docs.datastax.com/en/astra-cli/docs/ --recurse --skip ' https://localhost?'" - }, + "private": true, + "name": "astra-cli-docs", + "description": "The content source for DataStax Astra CLI documentation.", + "author": "DataStax Inc.", + "homepage": "https://docs.datastax.com", "repository": { "type": "git", - "url": "git+https://github.com/datastax/astra-cli-docs.git" + "url": "https://github.com/datastax/astra-cli-docs.git" + }, + "scripts": { + "build:local": "env FORCE_SHOW_EDIT_PAGE_LINK=true antora --clean --stacktrace local-preview-playbook.yml", + "tailwindcss": "tailwindcss build -c ./build/site/_/js/tailwind.config.js -i ./build/site/_/css/site.css -o ./build/site/_/css/site.css --minify" }, "dependencies": { - "@antora/cli": "~3.1", - "@antora/site-generator": "~3.1", - "@asciidoctor/tabs": "^1.0.0-beta.5", - "async": "~3.2.4", - "linkinator": "~3.0.3", - "mobx": "~6.0.4", - "react": "~16.8.4", - "react-dom": "~16.8.4", - "rxjs": "~7.0.1", - "styled-components": "~5.1.1" + "@antora/collector-extension": "^1.0.0-alpha.3", + "@asciidoctor/tabs": "^1.0.0-beta.6", + "antora": "~3.1", + "asciidoctor-external-callout": "~1.2.1", + "asciidoctor-kroki": "~0.18.1", + "csv-parser": "^3.0.0", + "npm-run-all": "^4.1.5", + "tailwindcss": "^3.3.5" } } diff --git a/playbooks/site-local-astra-cli.yaml b/playbooks/site-local-astra-cli.yaml deleted file mode 100644 index 6f34c11..0000000 --- a/playbooks/site-local-astra-cli.yaml +++ /dev/null @@ -1,126 +0,0 @@ -site: - title: Astra CLI - url: https://docs.datastax.com/en/astra-cli - start_page: docs::index.adoc - -output: - # The output.dir in the site-local playbook should take the form - # "./../build/". The reason for this is because DataStax docs are - # often stored on separate branches of the same repo. Using the docset name - # for the output directory ensures that different docset builds within the - # same repo don't overwrite each other - dir: ./../build/astra-cli - -content: - edit_url: false - sources: - - url: ./.. - branches: HEAD - start_path: docs-src/astra-cli-core - -ui: - bundle: - url: https://github.com/riptano/antora-ui-docs/releases/latest/download/ui-bundle.zip - snapshot: true - # Uncomment the "supplemental_files" line below ONLY IF you're trying to - # change the banner logo to something other than the default logo provided by - # the UI bundle. NOTE: The non-default logo must be named "logo.svg" and be - # located @ "playbooks/supplemental-ui/img/logo.svg". - #supplemental_files: ./supplemental-ui - output_dir: assets - -asciidoc: - attributes: - page-pagination: '' - sectanchors: '' - sectlinks: '' - idprefix: '' - idseparator: '-' - - company: 'DataStax' - product: 'Product' - product_name: 'Product' - evalproduct: 'DB Classic' - shortproduct: 'classic' - database: 'Astra DB' - astra_db: 'Astra DB' - astra_generic: 'Astra' - classic: 'classic' - classic_cap: 'Classic' - serverless: 'serverless' - serverless_cap: 'Serverless' - astra_ui: 'Astra Portal' - astra_cli: 'Astra CLI' - astra_stream: 'Astra Streaming' - advanced: 'no' - - stargate-docker-tag: v1.0.41 - stargate-docker-tag-3x: v1.0.41 - stargate-docker-tag-40: v1.0.41 - stargate-docker-tag-68: v1.0.40 - cass-tag-3x: '3.11' - cass-alt-tag-3x: '3_11' - cass-tag-40: '4.0' - cass-alt-tag-40: '4_0' - dse-server-tag-68: '6.8.9' - dse-tag-68: '6.8' - dse-alt-tag-68: '68' - - ASTRA_CLUSTER_ID: '8319febd-e7cf-4595-81e3-34f45d332d2a' - ASTRA_REGION: 'us-east1' - ASTRA_USERNAME: 'polandll' - ASTRA_PASSWORD: '12345abcd' - - auth_token: '$ASTRA_DB_APPLICATION_TOKEN' - base_auth_url: 'http://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com:8081' - base_auth_api_path: '/v1/auth' - cass_user: 'cassandra' # switch to auth_username - cass_passwd: 'cassandra' # switch to auth_password - - base_rest_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com' - base_doc_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com' - base_graphql_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com:8080' - - base_rest_schema: '/api/rest/v2/schemas/keyspaces' - base_doc_schema: '/api/rest/v2/schemas/namespaces' - base_gql_schema: '/api/graphql-schema' - - base_gql_admin: '/api/graphql-admin' - - base_rest_api: '/api/rest/v2/keyspaces' - base_doc_api: '/api/rest/v2/namespaces' - base_gql_api: '/api/graphql' - - rkeyspace: 'users_keyspace' - rkeyspace-dcs: 'users_keyspace-dcs' - rpartitionkey: 'firstname' - rclusteringkey: 'lastname' - rtable: 'users' - user1fn: 'Mookie' - user1ln: 'Betts' - user2fn: 'Janesha' - user2ln: 'Doesha' - - namespace: 'myworld' - collection: 'fitness' - user1: 'Janet' - user2: 'Joey' - user2a: 'Joseph' - user3: 'Martha' - - gkeyspace: 'library' - gtable1: 'book' - gtable2: 'reader' - - support_url: 'https://support.datastax.com' - astra_docs_base_url: 'https://docs.datastax.com/en/astra/docs' - - # The "glossary-url" attribute below is used by writers when linking to a - # term in the glossary. Referencing this attribute in an adoc file will - # automatically insert the root URL where the glossary pages are located. - # For example, the following syntax will generate a link to the glossary - # page for "agent": {glossary-url}agent[agent,window="_blank"] - glossary-url: 'https://docs.datastax.com/en/glossary/docs/index.html#' - - extensions: - - '@asciidoctor/tabs' diff --git a/playbooks/site-publish-astra-cli.yaml b/playbooks/site-publish-astra-cli.yaml deleted file mode 100644 index 92cecac..0000000 --- a/playbooks/site-publish-astra-cli.yaml +++ /dev/null @@ -1,135 +0,0 @@ -site: - title: Astra CLI - url: https://docs.datastax.com/en/astra-cli - start_page: docs::index.adoc - # The google_analytics and segment_io site keys must be in the release playbook - # of each docset. This ensures that the Google Tag Manager (GTM) and Segment - # scripts get loaded into the docsets that get published to docs.datastax.com. - keys: - google_analytics: 'GTM-5FSG7Q' - segment_io: 'd24gQtyKIUu5mLdkp11xjfiXLhRqx0HH' - -output: - # Bsys requires the output.dir in the site-publish playbook to be specifically - # set to "~/work//build/site". This is because bsys clones the - # content source repo into "/work", and then looks for the Antora-generated - # site in "build/site" within the repo directory when deploying/syncing. - dir: '~/work/astra-cli-docs/build/site' - -content: - edit_url: false - sources: - - url: '~/work/astra-cli-docs' - branches: HEAD - start_path: docs-src/astra-cli-core - -ui: - bundle: - url: https://github.com/riptano/antora-ui-docs/releases/latest/download/ui-bundle.zip - snapshot: true - # Uncomment the "supplemental_files" line below ONLY IF you're trying to - # change the banner logo to something other than the default logo provided by - # the UI bundle. NOTE: The non-default logo must be named "logo.svg" and be - # located @ "playbooks/supplemental-ui/img/logo.svg". - #supplemental_files: ~/work//playbooks/supplemental-ui - output_dir: assets - -asciidoc: - attributes: - page-pagination: '' - sectanchors: '' - sectlinks: '' - idprefix: '' - idseparator: '-' - - company: 'DataStax' - product: 'Product' - product_name: 'Product' - evalproduct: 'DB Classic' - database: 'Astra DB' - astra_db: 'Astra DB' - astra_generic: 'Astra' - classic: 'classic' - classic_cap: 'Classic' - serverless: 'serverless' - serverless_cap: 'Serverless' - astra_ui: "Astra Portal" - astra_cli: 'Astra CLI' - astra_stream: 'Astra Streaming' - advanced: 'no' - - stargate-docker-tag: v1.0.41 - stargate-docker-tag-3x: v1.0.41 - stargate-docker-tag-40: v1.0.41 - stargate-docker-tag-68: v1.0.40 - cass-tag-3x: '3.11' - cass-alt-tag-3x: '3_11' - cass-tag-40: '4.0' - cass-alt-tag-40: '4_0' - dse-server-tag-68: '6.8.9' - dse-tag-68: '6.8' - dse-alt-tag-68: '68' - - ASTRA_CLUSTER_ID: '8319febd-e7cf-4595-81e3-34f45d332d2a' - ASTRA_REGION: 'us-east1' - ASTRA_USERNAME: 'polandll' - ASTRA_PASSWORD: '12345abcd' - - auth_token: '$ASTRA_DB_APPLICATION_TOKEN' - base_auth_url: 'http://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com:8081' - base_auth_api_path: '/v1/auth' - cass_user: 'cassandra' # switch to auth_username - cass_passwd: 'cassandra' # switch to auth_password - - base_rest_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com' - base_doc_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com' - base_graphql_url: 'https://$ASTRA_CLUSTER_ID-$ASTRA_REGION.apps.astra.datastax.com:8080' - - base_rest_schema: '/api/rest/v2/schemas/keyspaces' - base_doc_schema: '/api/rest/v2/schemas/namespaces' - base_gql_schema: '/api/graphql-schema' - - base_gql_admin: '/api/graphql-admin' - - base_rest_api: '/api/rest/v2/keyspaces' - base_doc_api: '/api/rest/v2/namespaces' - base_gql_api: '/api/graphql' - - rkeyspace: 'users_keyspace' - rkeyspace-dcs: 'users_keyspace-dcs' - rpartitionkey: 'firstname' - rclusteringkey: 'lastname' - rtable: 'users' - user1fn: 'Mookie' - user1ln: 'Betts' - user2fn: 'Janesha' - user2ln: 'Doesha' - - namespace: 'myworld' - collection: 'fitness' - user1: 'Janet' - user2: 'Joey' - user2a: 'Joseph' - user3: 'Martha' - - gkeyspace: 'library' - gtable1: 'book' - gtable2: 'reader' - - support_url: 'https://support.datastax.com' - astra_docs_base_url: 'https://docs.datastax.com/en/astra/docs' - - # The "glossary-url" attribute below is used by writers when linking to a - # term in the glossary. Referencing this attribute in an adoc file will - # automatically insert the root URL where the glossary pages are located. - # For example, the following syntax will generate a link to the glossary - # page for "agent": {glossary-url}agent[agent,window="_blank"] - glossary-url: 'https://docs.datastax.com/en/glossary/docs/index.html#' - - # Bsys requires the URLs of the content source repos of the current docset - # to be listed as attributes in the site-publish playbook in the form - # ": 'ssh://github.com//.git'". - astra-cli-docs: 'ssh://github.com/datastax/astra-cli-docs.git' - - extensions: - - '@asciidoctor/tabs'