diff --git a/antora-playbook.yml b/antora-playbook.yml index fbe150e18d..76a6d64c8d 100644 --- a/antora-playbook.yml +++ b/antora-playbook.yml @@ -33,106 +33,146 @@ urls: latest_version_segment: current content: branches: master - # NOTE the git@ segment in the URL indicates which repositories are private - ## The above has a bug when upgrading to Antora 3.1. Original sources commented - ## out and replaced with a non git@ prefix. To revert if it causes issues + sources: - url: . branches: HEAD start_path: home + tags: ALL + + # Shared Devex - url: https://github.com/couchbaselabs/docs-devex branches: [release/7.2] + tags: [server] + - url: https://github.com/couchbaselabs/cb-swagger branches: [release/7.2, release/7.1, release/7.0, release/6.6, release/6.5, release/6.0] start_path: docs - # - url: https://git@github.com/couchbasecloud/couchbase-cloud + + # Cloud - url: https://github.com/couchbasecloud/couchbase-cloud branches: [main] start_path: docs/public - # - url: https://git@github.com/couchbase/couchbase-operator + private: true + tags: [cloud] + - url: https://github.com/couchbase/couchbase-operator branches: [2.4.x, 2.3.x, 2.2.x, 2.1.x, 2.0.x, 1.2.x, 1.1.x, 1.0.x] start_path: docs/user + private: true + tags: [operator] - url: https://github.com/couchbaselabs/observability branches: [0.2.x] start_path: docs + tags: [operator] - url: https://github.com/couchbaselabs/cbmultimanager branches: [0.2.x] start_path: docs + tags: [operator] + + # Connectors - url: https://github.com/couchbase/couchbase-elasticsearch-connector branches: [master, release/4.3, release/4.2, release/4.1, release/4.0] start_path: docs + tags: [connector] - url: https://github.com/couchbase/kafka-connect-couchbase branches: [master, release/4.0, release/3.4] start_path: docs + tags: [connector] - url: https://github.com/couchbase/couchbase-spark-connector branches: [master, release/3.2, release/3.1, release/3.0, release/2.4] start_path: docs + tags: [connector] - url: https://github.com/couchbase/couchbase-tableau-connector branches: [master] start_path: docs - # - url: https://git@github.com/couchbase/docs-connectors-talend + tags: [connector] - url: https://github.com/couchbase/docs-connectors-talend - # - url: https://git@github.com/couchbase/docs-analytics + private: true + tags: [connector] + + # Docs Server repos - url: https://github.com/couchbase/docs-analytics branches: [release/7.2, release/7.1, release/7.0, release/6.6, release/6.5, release/6.0] + private: true + tags: [analytics,server] - url: https://github.com/couchbase/couchbase-cli branches: [neo, 7.1.x-docs, cheshire-cat, mad-hatter, 6.5.x-docs, alice] start_path: docs - # - url: https://git@github.com/couchbase/backup + tags: [server] - url: https://github.com/couchbase/backup branches: [neo, 7.1.x-docs, cheshire-cat, mad-hatter, 6.5.x-docs, alice] start_path: docs + private: true + tags: [server] # NOTE docs-server is currently after other server repos so nav key wins - url: https://github.com/couchbase/docs-server branches: [release/7.2, release/7.1, release/7.0, release/6.6, release/6.5, release/6.0] + tags: [server] + + #SDK - url: https://github.com/couchbase/docs-sdk-common branches: [release/7.1.2, release/7.1, release/7.0, release/6.6, release/6.5, release/6.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-c branches: [release/3.3, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-txn-cxx branches: [release/1.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-dotnet branches: [release/3.4, release/3.3, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-go branches: [release/2.6, release/2.5, release/2.4, release/2.3, release/2.2, release/2.1, release/2.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-java branches: [release/3.4, release/3.3, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-kotlin branches: [release/1.1, release/1.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-nodejs branches: [release/4.2, release/4.1, release/4.0, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-php + tags: [sdk] branches: [release/4.1, release/4.0, release/3.2, release/3.1, release/3.0] - url: https://github.com/couchbase/docs-sdk-python branches: [release/4.1, release/4.0, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-ruby branches: [release/3.4, release/3.3, release/3.2, release/3.1, release/3.0] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-scala branches: [release/1.4, release/1.3, release/1.2, release/1.1] + tags: [sdk] - url: https://github.com/couchbase/docs-sdk-extensions branches: [main] + tags: [sdk] + # Mobile Docs Pages - url: https://github.com/couchbase/docs-mobile branches: [release/3.1, release/2.8] + tags: mobile - url: https://github.com/couchbaselabs/docs-couchbase-lite branches: [release/3.1, release/3.0, release/2.8, release/2.7, release/2.6, release/2.5, release/2.1, release/2.0] + tags: [mobile,client] - url: https://github.com/couchbaselabs/docs-sync-gateway branches: [release/3.1, release/3.0, release/2.8, release/2.7, release/2.6, release/2.5, release/2.1, release/2.0, release/1.5] + tags: [mobile,sync] + + # Miscellaneous - url: https://github.com/couchbase/docs-service-broker branches: [1.1.x, 1.0.x] - # - url: https://git@github.com/couchbase/docs-cloud-native - url: https://github.com/couchbase/docs-cloud-native branches: [cloud-native-2.2] -# - url: https://github.com/couchbaselabs/tutorials + private: true - url: https://github.com/couchbase/developer-content - url: https://github.com/couchbaselabs/tutorial-template - url: https://github.com/couchbaselabs/mobile-travel-sample branches: [master] start_path: content - # - url: https://github.com/couchbaselabs/hotel-finder-react-native - # - url: https://github.com/couchbaselabs/hotel-lister-cordova -# - url: https://github.com/couchbaselabs/tutorials-contrib - url: https://github.com/couchbaselabs/mobile-training-todo branches: tutorials start_path: content @@ -144,16 +184,13 @@ content: - url: https://github.com/couchbaselabs/userprofile-couchbase-mobile-xamarin branches: [standalone, query, sync] start_path: content - # - url: https://github.com/couchbaselabs/couchbase-lite-ios-api-playground - url: https://github.com/couchbaselabs/userprofile-couchbase-mobile-android branches: [standalone, query, sync] start_path: content - # - url: https://github.com/amarantha-k/OpenID_connect_tutorial - # branches: [tutorial] - # start_path: content - url: https://github.com/couchbaselabs/couchbase-lite-peer-to-peer-sync-examples branches: [master] start_path: content + asciidoc: attributes: site-navigation-data-path: _/js/site-navigation-data.js diff --git a/lib/inline-jira-macro.js b/lib/inline-jira-macro.js index 3660c98f30..f179d67598 100644 --- a/lib/inline-jira-macro.js +++ b/lib/inline-jira-macro.js @@ -43,7 +43,6 @@ function register (registry, context) { return accum }, { __DEFAULT__: 'https://issues.couchbase.com/browse' }) - console.log(mapping) const contextWithMapping = Object.assign({ mapping }, context) registry.inlineMacro('jira', initInlineJiraMacro(contextWithMapping)) } diff --git a/package-lock.json b/package-lock.json index 2238d8c2a4..234c6ff8b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,6 +6,7 @@ "": { "name": "docs-site", "dependencies": { + "@antora/collector-extension": "^1.0.0-alpha.3", "@antora/site-generator-ms": "git+https://gitlab.com/opendevise/oss/antora-site-generator-ms#as-extension", "antora": "~3.1", "asciidoctor-external-callout": "~1.2.0", @@ -13,6 +14,7 @@ "gulp": "~4.0", "gulp-connect": "~5.7", "js-yaml": "~4.1", + "lodash": "^4.17.21", "markdown-it": "^13.0.1", "yaml": "^2.2.2" } @@ -169,6 +171,21 @@ "real-require": "^0.2.0" } }, + "node_modules/@antora/collector-extension": { + "version": "1.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@antora/collector-extension/-/collector-extension-1.0.0-alpha.3.tgz", + "integrity": "sha512-0yUc+lMVKzXUfOyelGjVO4C2h8ltzYupyWsjymfBPH251Noj9pSlAuzbldjlp7h92dJakgsz+NsLTHIj6lArbQ==", + "dependencies": { + "@antora/expand-path-helper": "~2.0", + "cache-directory": "~2.0", + "glob-stream": "~7.0", + "isomorphic-git": "~1.21", + "js-yaml": "~4.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@antora/expand-path-helper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@antora/expand-path-helper/-/expand-path-helper-2.0.0.tgz", @@ -515,40 +532,11 @@ "node": ">=14" } }, - "node_modules/antora/node_modules/isomorphic-git": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.21.0.tgz", - "integrity": "sha512-ZqCAUM63CYepA3fB8H7NVyPSiOkgzIbQ7T+QPrm9xtYgQypN9JUJ5uLMjB5iTfomdJf3mdm6aSxjZwnT6ubvEA==", - "dependencies": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^4.0.1" - }, - "bin": { - "isogit": "cli.cjs" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/antora/node_modules/on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" }, - "node_modules/antora/node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "node_modules/antora/node_modules/pino": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/pino/-/pino-8.7.0.tgz", @@ -3046,6 +3034,35 @@ "node": ">=0.10.0" } }, + "node_modules/isomorphic-git": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.21.0.tgz", + "integrity": "sha512-ZqCAUM63CYepA3fB8H7NVyPSiOkgzIbQ7T+QPrm9xtYgQypN9JUJ5uLMjB5iTfomdJf3mdm6aSxjZwnT6ubvEA==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/isomorphic-git/node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -3234,6 +3251,11 @@ "node": ">=0.10.0" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -6005,6 +6027,18 @@ } } }, + "@antora/collector-extension": { + "version": "1.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/@antora/collector-extension/-/collector-extension-1.0.0-alpha.3.tgz", + "integrity": "sha512-0yUc+lMVKzXUfOyelGjVO4C2h8ltzYupyWsjymfBPH251Noj9pSlAuzbldjlp7h92dJakgsz+NsLTHIj6lArbQ==", + "requires": { + "@antora/expand-path-helper": "~2.0", + "cache-directory": "~2.0", + "glob-stream": "~7.0", + "isomorphic-git": "~1.21", + "js-yaml": "~4.1" + } + }, "@antora/expand-path-helper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@antora/expand-path-helper/-/expand-path-helper-2.0.0.tgz", @@ -6267,34 +6301,11 @@ "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.1.0.tgz", "integrity": "sha512-bgJcBmNTZaJO03xtXOTNfoFEf/3VwoZ/gJ2O4ekTCZu4LSFtfzQFrJ0kjq8ZSS0+IdghXqQIiDUnpp0eUR9IJg==" }, - "isomorphic-git": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.21.0.tgz", - "integrity": "sha512-ZqCAUM63CYepA3fB8H7NVyPSiOkgzIbQ7T+QPrm9xtYgQypN9JUJ5uLMjB5iTfomdJf3mdm6aSxjZwnT6ubvEA==", - "requires": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^4.0.1" - } - }, "on-exit-leak-free": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "pino": { "version": "8.7.0", "resolved": "https://registry.npmjs.org/pino/-/pino-8.7.0.tgz", @@ -8291,6 +8302,31 @@ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, + "isomorphic-git": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.21.0.tgz", + "integrity": "sha512-ZqCAUM63CYepA3fB8H7NVyPSiOkgzIbQ7T+QPrm9xtYgQypN9JUJ5uLMjB5iTfomdJf3mdm6aSxjZwnT6ubvEA==", + "requires": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "dependencies": { + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + } + } + }, "joycon": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", @@ -8446,6 +8482,11 @@ } } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", diff --git a/package.json b/package.json index 6e79ad253d..ae46cddf55 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,15 @@ "homepage": "https://docs.couchbase.com", "private": true, "dependencies": { - "antora": "~3.1", + "@antora/collector-extension": "^1.0.0-alpha.3", "@antora/site-generator-ms": "git+https://gitlab.com/opendevise/oss/antora-site-generator-ms#as-extension", + "antora": "~3.1", "asciidoctor-external-callout": "~1.2.0", "asciidoctor-kroki": "0.15.4", "gulp": "~4.0", "gulp-connect": "~5.7", "js-yaml": "~4.1", + "lodash": "^4.17.21", "markdown-it": "^13.0.1", "yaml": "^2.2.2" }, diff --git a/patch-staging.yml b/patch-staging.yml new file mode 100644 index 0000000000..542a7c1f8f --- /dev/null +++ b/patch-staging.yml @@ -0,0 +1,29 @@ +$from: antora-playbook.yml +$patch: + site: + title: Couchbase Docs Staging + url: https://docs-staging.couchbase.com + robots: disallow + keys: + google_analytics: null + content: + sources: + $seq: + - $prune: 1 + - $override: + docs-devex: + branches: + - release/7.2 + - capella + - elixir + couchbase-cloud: + start_path: ~ + start_paths: + - docs/public + - docs/serverless + observability: + branches: + - main + cbmultimanager: + branches: + - main diff --git a/patch.yml b/patch.yml new file mode 100644 index 0000000000..8a260df182 --- /dev/null +++ b/patch.yml @@ -0,0 +1,28 @@ +$from: antora-playbook.yml +$patch: + asciidoc: + attributes: + kroki-server-url: null + extensions: + $without: asciidoctor-external-callout + content: + sources: + $seq: + - $prune: 2 + - $local: + paths: .. + only: true + head: true + - $filter: + tags: mobile + - $only: + - docs-sync-gateway + - docs-couchbase-lite + - $override: + docs-sync-gateway: + branches: + $prepend: + - my-test-branch + ui: + bundle: + url: ../docs-ui/build/ui-bundle.zip diff --git a/playbook.mjs b/playbook.mjs new file mode 100755 index 0000000000..9673884aaf --- /dev/null +++ b/playbook.mjs @@ -0,0 +1,382 @@ +#!/usr/bin/env zx +'use strict' +import _ from "lodash" + +$.verbose = false + +/** Usage: + * ./playbook.mjs [--update] [--truncate] [--patch ] [--playbook ] [] [] + * + * e.g.: + * + * ./playbook.mjs --playbook antora-playbook.yml --patch patch.yml + * or + * ./playbook.mjs patch.yml --update # update the patchfile in place + * ./playbook.mjs patch.yml --truncate # truncat the patchfile to { $from: ..., $patch: ... } + * ./playbook.mjs patch.yml > new-playbook.yml + * + * playbook-file: a standard Antora playbook + * + * patch-file: a yml file with just the keys that you wish to *change*. + * see the `patch.yml` and `patch-staging.yml` files for examples. + * + * + ** Operators + * + * The following operators are provided: + * + * $from: identify the playbook to generate + * $patch: contains the tree to change + * $meta: replaced with metadata + * + ** $append: add an item to the end of a list + * $prepend: add an item to the beginning of list + * e.g: + + $patch: + asciidoc: + extensions: + $append: + - '@asciidoctor/tabs' + + ** $without: remove an item from a list + * e.g: + + $patch: + asciidoc: + extensions: + $without: asciidoctor-external-callout + + + ** $filter: restrict a list of objects, where the given fields match + * e.g: + * In this example, only those sources which have `tags: mobile` will be selected. + * You can provide multiple key/values that must all match. + * + $patch: + content: + sources: + $filter: + tags: mobile + + ** $prune: Keep only X branches + * This operator is specialised for content.sources + * e.g. + * Here we only keep the first 2 branches (for example ([release/7.2, release/7.1]`) + + $patch: + content: + sources: + $prune: 2 + + ** $local: resolve sources to the ones you have checked out locally + * e.g. + * We work through all of the sources like `https://github.com/couchbasecloud/couchbase-cloud` + * and look in each of the `paths` provided to see if there is a local directory matching. + * + * As many writers keep all their code in a single directory like ~/code, they might have: + + ~/ + code/ + couchbase-cloud + docs-site + + * Therefore the default of `paths` is .. the parent directory. + * We will then check if ../couchbase-cloud (e.g. ~/code/couchbase-cloud) + * exists, and update the record if so. + * If the `only` parameter is true, then we will remove all the remote sources. + * If `head` is supplied, then use the HEAD branch (e.g. the version you have checked out) + + $patch: + content: + sources: + $local: + paths: .. + only: true + head: + + ** $only: as an alternative to $filter, restrict the sources to specific repos + * e.g: + * (note how you can use the short name of the source) + + $patch: + content: + sources: + $only: + - docs-sync-gateway + - docs-couchbase-lite + + ** $override: update a specific source (using the short name) to apply any other operators. + * e.g.: + * Add `my-test-branch` as the *first* branch of `docs-sync-gateway` + * + $patch: + content: + sources: + $override: + docs-sync-gateway: + branches: + $prepend: + - my-test-branch + * + ** $seq: apply multiple operators in turn to the same node + * + $patch: + content: + sources: + $seq: + - $prune: 1 + - $local: + paths: + - .. + * + * See patch.yml and patch-staging.yml for full examples. + * + */ +const patchFile = argv.patch ?? argv._.shift() ?? 'patch.yml' +const patch = YAML.parse(fs.readFileSync(patchFile).toString()) +const $patch = patch.$patch + +if (! $patch) { + throw new Error("Patch file is missing $patch tree") +} + +/** Helper function to wrap a single item in an array if required */ +const toArray = (thing) => Array.isArray(thing) ? thing : [thing] + +/** Helper function to do permissive comparison. + * In particular: + * + * [1,2,3] == 2 (includes) + * [1,2,3] == [1,2] (includes all items) + * 1 == true (truthy value) + * ALL == ?? (always true. Used to make sure docs-site matches `tags: ALL` + * Everything else falls back to the === comparison operator + */ +function cmp (a, b) { + if (Array.isArray(a)) { + if (Array.isArray(b)) { + return b.every(bb => a.includes(bb)) + } + else { + return a.includes(b) + } + } + else if (typeof b === 'boolean') { + return a ? b : !b + } + else if (a === 'ALL') { + return true + } + else { + return a === b + } +} + +/** + * @param {Array.<>} node - any array node in playbook + * @param {Object} filters - object of key/values to filter for (using `cmp` function) + * All provided filters must match. + */ +function $filter (node, param) { + if (! Array.isArray(node)) { + throw new Error(`$filter run on something that isn't an array! ${JSON.stringify(param)}`) + } + return node.filter(item => + Object.entries(param) + .every(([k,v]) => cmp(item[k], v))) +} + +/** + * @param {Object[]} sources - expects to be called only on `content.sources` from playbook + * @param {Object} config + * @param {Array.} config.paths - array of local filesystem paths to check for the git repo + * @param {boolean} config.only - if true, filter out all non-local sources + * @param {boolean} config.head - if true, only use HEAD + * + */ + function $local (sources, {paths, only, head}) { + const repoPaths = toArray(paths ?? ['..']) + + const overrideHead = head ? {branches: ['HEAD']} : {} + + return sources.flatMap(item => { + const {url} = item + + // if url is already a local path, then wave it through + if (url.match(/^[.\/]/)) { + return [{...item, local: true}] + } + + // check all of the possible paths + const repo = path.basename(url, '.git') + for (const repoPath of repoPaths) { + const newPath = path.join(repoPath, repo) + try { + fs.accessSync(newPath, fs.constants.R_OK) + + return [{...item, url: newPath, local: true, ...overrideHead}] + } + catch(e) { + continue + // do nothing as file doesn't exist here + } + } + + // Otherwise we either filter out, or return the value unchanged + return only ? [] : [item] + } + ) +} + +/** + * @param {Object[]} sources - expects to be called only on `content.sources` from playbook + * @param {number} limit - the number of branches to keep. + */ +function $prune (sources, limit) { + return sources.map(source => + ('branches' in source) ? + {...source, branches: toArray(source.branches).slice(0, limit)} + : source) +} + +const repoShort = (url) => url === '.' ? 'docs-site' : path.basename(url, '.git') + +/** + * @param {Object[]} sources - expects to be called only on `content.sources` from playbook + * @param {Object} overrides - name/Object pairs to override + * @param {Object} overrides."some-repo" - the patch description to apply to the matching source with. + */ +function $override (sources, overrides) { + return sources.map(source => { + const short = repoShort(source.url) + if (short in overrides) { + return apply_patch(source, overrides[short]) + } + else { + return source + } + }) +} + +/** + * @param {Object[]} sources - expects to be called only on `content.sources` from playbook + * @param {Array.} only - just the names of repos to keep + */ +function $only (sources, only) { + return sources.filter(({url, tags}) => + tags === 'ALL' || only.some(source => source === repoShort(url))) +} + +function $seq (node, seq) { + return seq.reduce(apply_function, node) +} + + +// Catalog of functions +const functions = { + // explicit replace + $replace: (node, param) => _.cloneDeep(param), // avoid YAML aliasing + + // append or prepend the data to an ARRAY + $append: (node, param) => [...node, ...param], + $prepend: (node, param) => [...node, ...param], + // remove item from array + $without: (node, param) => node.filter(item => ! param.includes(item)), + + // filter a list by matching key + $filter, + + // Special functions on content.sources + $prune, + $local, + $override, + $only, + + // Sequence functions + $seq +} + + +const is_function = (obj) => { + if (is_object(obj)) { + const keys = Object.keys(obj) + return (keys.length === 1) && keys[0] in functions + } +} + +const is_object = (node) => (node && typeof node === 'object' && ! Array.isArray(node)) + +const apply_function = (node, patch) => { + const [fnName, param] = Object.entries(patch)[0] + const fn = functions[fnName] + return fn(node, param) +} + +/** + * Recursive function to apply the patch, by descending both the original + * playbook and the patch at the same time, applying operators as required. + */ +function apply_patch(node, patch) { + + // while `null` is a valid value for a node, or a patch replacement, + // `undefined` signals the absence of a value. + // Therefore we return the other side. + if (patch === undefined) return node + + // Apply functions + if (is_function(patch)) { + return apply_function(node, patch) + } + + // if both sides are objects, we iterate the superset of keys + if (is_object(node) && is_object(patch)) { + const keys = Object.keys({...node, ...patch}) + return Object.fromEntries(keys.map(k => [k, apply_patch(node[k], patch[k])])) + } + + // the only remaining option: return the patched value. + // we clone it, to avoid aliasing from the `$patch` section + return _.cloneDeep(patch) +} + + +var update = argv.update +const playbookFile = patch.$from ?? argv.playbook ?? argv._.shift() ?? 'antora-playbook.yml' +var playbook + +if (argv.truncate) { + update = true + playbook = { $from: playbookFile, $patch } +} +else { + const original = YAML.parse(fs.readFileSync(playbookFile).toString()) + + // Confirm which files we are composing + console.error(`Composing ${playbookFile} with ${patchFile}`) + + const patched = apply_patch(original, $patch) + + const $meta = { + date: Date() + } + + // playbook = { $from: playbookFile, $meta, $patch, ...patched } + playbook = patched +} + +const output = YAML.stringify(playbook) + +// if (update) { +// try { +// fs.copySync(patchFile, `${patchFile}~`) +// fs.writeFileSync(patchFile, output) +// } +// catch (err) { +// console.error(err) +// } +// } +// else { + console.log(output) +// } + diff --git a/rest-playbook.yml b/rest-playbook.yml new file mode 100644 index 0000000000..c41177d45f --- /dev/null +++ b/rest-playbook.yml @@ -0,0 +1,91 @@ +antora: + extensions: + - "@antora/site-generator-ms" + - ./lib/embargo.js + - "@antora/collector-extension" +site: + title: Couchbase Docs + url: https://docs.couchbase.com + start_page: home::index.adoc + robots: allow + keys: + google_analytics: GTM-MVPNN2 + nav_groups: > + [ + { "title": "Server", "startPage": "home::server.adoc", "components": ["server"] }, + { "title": "Mobile", "startPage": "home::mobile.adoc", "components": ["couchbase-lite", "sync-gateway"] }, + { "title": "Capella", "startPage": "cloud::index.adoc", "components": ["cloud"] }, + { "title": "Cloud-Native", "startPage": "cloud-native-database::index.adoc", "components": ["cloud-native-database"] }, + { "title": "Autonomous Operator", "components": ["operator"] }, + { "title": "CMOS", "components": ["cmos"] }, + { "title": "Service Broker", "components": ["service-broker"] }, + { "title": "SDKs", "startPage": "home::sdk.adoc", "components": ["*-sdk", "cxx-txns", "elasticsearch-connector", "kafka-connector", "spark-connector", "tableau-connector", "sdk-extensions"] }, + { "title": "Tutorials", "startPage": "tutorials::index.adoc", "components": ["tutorials"] } + ] +git: + ensure_git_suffix: false + fetch_concurrency: 10 +urls: + latest_version_segment_strategy: redirect:to + latest_version_segment: current +content: + branches: master + sources: + - url: . + branches: + - HEAD + start_path: home + tags: ALL + local: true + - url: ../couchbase-cloud + branches: + - HEAD + start_path: null + private: true + tags: + - cloud + local: true + start_paths: + - cmd/cp-open-api +asciidoc: + attributes: + site-navigation-data-path: _/js/site-navigation-data.js + enable-cmos: "" + max-include-depth: 10 + page-partial: false + experimental: "" + idprefix: "@" + idseparator: -@ + tabs: tabs + toc: null + page-toclevels: 1@ + xrefstyle: short + enterprise: https://www.couchbase.com/products/editions[ENTERPRISE EDITION] + community: https://www.couchbase.com/products/editions[COMMUNITY EDITION] + sqlpp: SQL++ + sqlpp_url: https://www.couchbase.com/products/n1ql + cbpp: Couchbase++ + kroki-server-url: null + kroki-fetch-diagram: false + url-issues: https://issues.couchbase.com/browse + url-issues-jscbc: https://issues.couchbase.com/browse + url-issues-av: https://couchbasecloud.atlassian.net/browse + page-jira-component-id: 17512 + extensions: + - ./lib/source-url-include-processor.js + - ./lib/json-config-ui-block-macro.js + - ./lib/inline-jira-macro.js + - ./lib/inline-man-macro.js + - ./lib/multirow-table-head-tree-processor.js + - ./lib/swagger-ui-block-macro.js + - ./lib/tabs-block.js + - ./lib/markdown-block.js + - ./lib/template-block.js + - asciidoctor-kroki + - asciidoctor-external-callout +ui: + bundle: + url: https://github.com/couchbase/docs-ui/releases/download/sandbox-11/ui-bundle.zip +output: + dir: ./public +