diff --git a/boost.js b/boost.js deleted file mode 100644 index 81a86f2..0000000 --- a/boost.js +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) - - Distributed under the Boost Software License, Version 1.0. (See accompanying - file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - Official repository: https://github.com/boostorg/antora -*/ - -'use strict' - -const fs = require('node:fs'); -const path = require('node:path'); - - -/* - This extension allows every asciidoc attribute - specified in the playbook or the command line - to become a variable in the playbook using the - syntax ${var}. -*/ -class Ext { - static register() { - new Ext(this) - } - - constructor(ctx) { - ;(this.ctx = ctx) - .on('contextStarted', this.contextStarted.bind(this)) - } - - doReplace1(elem, pat, sub) { - if (Array.isArray(elem)) { - for(var i = 0; i < elem.length; i++) - if (typeof elem[i] != "string") - this.doReplace1(elem[i], pat, sub) - else - elem[i] = elem[i].replaceAll(pat, sub) - } else if (typeof elem == 'object') { - for (let key in elem) - if (typeof elem[key] != "string") - this.doReplace1(elem[key], pat, sub) - else - elem[key] = elem[key].replaceAll(pat, sub) - } - } - - doReplace(playbook) { - for (const [key, value] of Object.entries(playbook.asciidoc.attributes)) { - var pat = "${" + key + "}" - this.doReplace1(playbook.site, pat, value) - this.doReplace1(playbook.urls, pat, value) - this.doReplace1(playbook.content, pat, value) - this.doReplace1(playbook.output, pat, value) - this.doReplace1(playbook.ui, pat, value) - } - } - - contextStarted({playbook}) { - let branch = playbook.asciidoc.attributes['page-boost-branch']; - - if(! branch ) - throw new Error("Missing required attribute: asciidoc.attributes.page-boost-branch"); - - if( branch === "master" || branch === "develop") { - playbook.content.tags = "" - playbook.content.branches = branch - } else { - playbook.content.tags = "boost-" + branch - playbook.content.branches = null // disable branches - playbook.urls.latestVersionSegment = "" // disable tag in URL - } - - const cwd = process.cwd(); - const sources = playbook.content.sources; - for (let i = 0; i < sources.length; i++) { - const source = sources[i]; - const antoraYmlPath = path.join(cwd, source.startPath, 'antora.yml'); - if (fs.existsSync(antoraYmlPath)) { - source.url = '.'; - } - } - - this.doReplace(playbook); - } -} - -module.exports = Ext diff --git a/build.sh b/build.sh index f07ef64..cb711c8 100755 --- a/build.sh +++ b/build.sh @@ -2,12 +2,6 @@ if command -v git >/dev/null && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then branch=$(git rev-parse --abbrev-ref HEAD) -else - branch="develop" -fi - -if [ "$branch" != "master" ] && [ "$branch" != "develop" ]; then - branch="develop" fi ./sitedoc.sh "$branch" diff --git a/extensions/boost.js b/extensions/boost.js new file mode 100644 index 0000000..20322e0 --- /dev/null +++ b/extensions/boost.js @@ -0,0 +1,142 @@ +/* + Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) + Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com) + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + Official repository: https://github.com/boostorg/antora +*/ + +'use strict' + +const fs = require('node:fs'); +const path = require('node:path'); +const process = require("process"); +const {execSync} = require('child_process'); + +/* + This extension allows every asciidoc attribute + specified in the playbook or the command line + to become a variable in the playbook using the + syntax ${var}. +*/ +class BoostPlaybookPatterns { + static register() { + new BoostPlaybookPatterns(this) + } + + constructor(ctx) { + ;(this.ctx = ctx) + .on('contextStarted', this.contextStarted.bind(this)) + } + + /** + * Recursively replaces all occurrences of a pattern with a substitution string + * in an object or array of strings. + * + * @param {Array|Object} obj - The object or array to modify. + * @param {string|RegExp} pattern - The pattern to search for. + * @param {string} replacement - The replacement string. + * @returns {void} + */ + replaceAll(obj, pattern, replacement) { + if (Array.isArray(obj)) { + obj.forEach((val, i) => { + if (typeof val === "string") obj[i] = val.replaceAll(pattern, replacement); + else if (typeof val === "object") this.replaceAll(val, pattern, replacement); + }); + } else if (typeof obj === "object" && obj !== null) { + Object.entries(obj).forEach(([key, val]) => { + if (typeof val === "string") obj[key] = val.replaceAll(pattern, replacement); + else if (typeof val === "object") this.replaceAll(val, pattern, replacement); + }); + } + } + + /** + * Sets page attributes on the playbook's `asciidoc` object based on the current Git branch and commit. + * Also sets the `branches` and `tags` properties of the playbook's `content` object, and optionally + * modifies the playbook's `urls` object. + * + * @param {object} playbook - The playbook object to modify. + */ + setPageAttributes(playbook) { + let branch = playbook.asciidoc.attributes['page-boost-branch']; + if (!branch) + try { + branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim(); + } catch (error) { + branch = 'develop' + } + playbook.asciidoc.attributes['page-boost-branch'] = branch + playbook.content.branches = branch + + let commit_id = playbook.asciidoc.attributes['page-commit-id']; + if (!commit_id) + try { + commit_id = execSync('git rev-parse HEAD').toString().trim().substring(0, 7); + playbook.asciidoc.attributes['page-commit-id'] = commit_id + } catch (error) { + playbook.asciidoc.attributes['page-commit-id'] = undefined + } + + if (branch in ["master", "develop"]) { + playbook.content.tags = "" + } else { + playbook.content.tags = "boost-" + branch + playbook.urls.latestVersionSegment = "" // disable tag in URL + } + } + + /** + * Sets the `url` property of each source in the playbook's content object + * to `'.'` if an `antora.yml` file exists in the source's directory. + * + * @param {object} playbook - The playbook object to modify. + */ + setContentSourceURLs(playbook) { + const cwd = process.cwd(); + const sources = playbook.content.sources; + for (let i = 0; i < sources.length; i++) { + const source = sources[i]; + const antoraYmlPath = path.join(cwd, source.startPath, 'antora.yml'); + if (fs.existsSync(antoraYmlPath)) { + source.url = '.'; + } + } + } + + /** + * Recursively replaces all occurrences of attribute placeholders in a playbook + * with their corresponding attribute values. + * + * @param {Object} playbook - The playbook to modify. + * @returns {void} + */ + replacePatterns(playbook) { + for (const [key, value] of Object.entries(playbook.asciidoc.attributes)) { + const placeholder = "${" + key + "}"; + this.replaceAll(playbook.site, placeholder, value); + this.replaceAll(playbook.urls, placeholder, value); + this.replaceAll(playbook.content, placeholder, value); + this.replaceAll(playbook.output, placeholder, value); + this.replaceAll(playbook.ui, placeholder, value); + } + } + + /** + * Called when Antora starts processing a playbook. Sets page attributes, content source URLs, + * and performs replacements in the playbook's content. + * + * @param {object} context - An object containing the playbook and other contextual information. + * @param {object} context.playbook - The playbook object being processed. + */ + contextStarted({playbook}) { + this.setPageAttributes(playbook) + this.setContentSourceURLs(playbook); + this.replacePatterns(playbook); + } +} + +module.exports = BoostPlaybookPatterns diff --git a/libdoc.sh b/libdoc.sh index c055822..5a9ab8e 100755 --- a/libdoc.sh +++ b/libdoc.sh @@ -62,6 +62,10 @@ else commit_id="" fi +if [ ! -d "node_modules" ] || [ "$(find package.json -prune -printf '%T@\n' | cut -d . -f 1)" -gt "$(find node_modules -prune -printf '%T@\n' | cut -d . -f 1)" ]; then + npm install +fi + # Run antora command while test $# -gt 0; do if [ "$1" = "develop" ] || [ "$1" = "master" ]; then diff --git a/libs.playbook.yml b/libs.playbook.yml index 67ecb05..cb50a6f 100644 --- a/libs.playbook.yml +++ b/libs.playbook.yml @@ -39,19 +39,19 @@ site: antora: extensions: - - require: ./boost.js + - require: ./extensions/boost.js - require: '@antora/lunr-extension' content: sources: - - url: https://github.com/vinniefalco/mp11 - start_path: antora - - url: https://github.com/vinniefalco/predef - start_path: antora - - url: https://github.com/vinniefalco/qvm - start_path: antora - - url: https://github.com/vinniefalco/unordered - start_path: antora + - url: https://github.com/vinniefalco/mp11 + start_path: antora + - url: https://github.com/vinniefalco/predef + start_path: antora + - url: https://github.com/vinniefalco/qvm + start_path: antora + - url: https://github.com/vinniefalco/unordered + start_path: antora ui: bundle: diff --git a/package-lock.json b/package-lock.json index 87006b3..46f252d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,8 @@ "packages": { "": { "dependencies": { - "@antora/lunr-extension": "^1.0.0-alpha.8" + "@antora/lunr-extension": "^1.0.0-alpha.8", + "process": "^0.11.10" }, "devDependencies": { "@antora/cli": "3.1.2", @@ -1827,7 +1828,6 @@ "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, "engines": { "node": ">= 0.6.0" } diff --git a/package.json b/package.json index c5c301a..a524e2e 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "@antora/site-generator": "3.1.2" }, "dependencies": { - "@antora/lunr-extension": "^1.0.0-alpha.8" + "@antora/lunr-extension": "^1.0.0-alpha.8", + "process": "^0.11.10" } } diff --git a/site.playbook.yml b/site.playbook.yml index 114e40d..a44620c 100644 --- a/site.playbook.yml +++ b/site.playbook.yml @@ -17,11 +17,6 @@ # old-version: DIGIT+ '_' DIGIT+ '_' DIGIT+ # -asciidoc: - attributes: - page-boost-branch: develop - page-commit-id: '' - site: url: https://antora.cppalliance.org title: Boost Site Docs @@ -29,7 +24,7 @@ site: antora: extensions: - - require: ./boost.js + - require: ./extensions/boost.js - require: '@antora/lunr-extension' content: diff --git a/sitedoc.sh b/sitedoc.sh index a1e6774..6ee2db5 100755 --- a/sitedoc.sh +++ b/sitedoc.sh @@ -57,12 +57,10 @@ else commit_id="" fi -if [ "$1" != "develop" ] && [ "$1" != "master" ]; then - echo "invalid argument: '$1'" - exit 1 +if [ ! -d "node_modules" ] || [ "$(find package.json -prune -printf '%T@\n' | cut -d . -f 1)" -gt "$(find node_modules -prune -printf '%T@\n' | cut -d . -f 1)" ]; then + npm install fi -$ANTORA_CMD --fetch \ - --attribute page-boost-branch="$1" \ - --attribute page-commit-id="$commit_id" \ - site.playbook.yml +echo $ANTORA_CMD --fetch --attribute page-boost-branch="$1" --attribute page-commit-id="$commit_id" site.playbook.yml +$ANTORA_CMD --fetch --attribute page-boost-branch="$1" --attribute page-commit-id="$commit_id" site.playbook.yml +