diff --git a/bin/doc-tools.js b/bin/doc-tools.js old mode 100755 new mode 100644 index e01c16e..fd0b1b6 --- a/bin/doc-tools.js +++ b/bin/doc-tools.js @@ -10,6 +10,14 @@ const fetchFromGithub = require('../tools/fetch-from-github.js'); const { urlToXref } = require('../cli-utils/convert-doc-links.js'); +/** + * Searches upward from a starting directory to locate the repository root. + * + * Traverses parent directories from the specified start path, returning the first directory containing either a `.git` folder or a `package.json` file. Exits the process with an error if no such directory is found. + * + * @param {string} [start] - The directory to begin the search from. Defaults to the current working directory. + * @returns {string} The absolute path to the repository root directory. + */ function findRepoRoot(start = process.cwd()) { let dir = start; while (dir !== path.parse(dir).root) { @@ -26,19 +34,25 @@ function findRepoRoot(start = process.cwd()) { // -------------------------------------------------------------------- // Dependency check functions -// -------------------------------------------------------------------- +/** + * Prints an error message to stderr and exits the process with a non-zero status. + * + * @param {string} msg - The error message to display before exiting. + */ function fail(msg) { console.error(`❌ ${msg}`); process.exit(1); } /** - * Ensure a tool is installed (and optionally that it responds to a version flag). + * Ensures that a specified command-line tool is installed and operational. + * + * Attempts to execute the tool with a version flag to verify its presence. If the tool is missing or fails to run, the process exits with an error message and optional installation hint. * - * @param {string} cmd The binary name (such as 'docker', 'helm-docs') - * @param {object} [opts] - * @param {string} [opts.versionFlag='--version'] What to append to check it runs - * @param {string} [opts.help] A one-liner hint (URL or install command) + * @param {string} cmd - The name of the tool to check (e.g., 'docker', 'helm-docs'). + * @param {object} [opts] - Optional settings. + * @param {string} [opts.versionFlag='--version'] - The flag used to test the tool's execution. + * @param {string} [opts.help] - An optional hint or installation instruction shown on failure. */ function requireTool(cmd, { versionFlag = '--version', help = '' } = {}) { try { @@ -49,14 +63,28 @@ function requireTool(cmd, { versionFlag = '--version', help = '' } = {}) { } } -// Simple existence only (no version flag) +/** + * Ensures that a command-line tool is installed by checking if it responds to the `--help` flag. + * + * @param {string} cmd - The name of the command-line tool to check. + * @param {string} [help] - Optional help text to display if the tool is not found. + * + * @throws {Error} If the specified command is not found or does not respond to `--help`. + */ function requireCmd(cmd, help) { requireTool(cmd, { versionFlag: '--help', help }); } // -------------------------------------------------------------------- // Special validators -// -------------------------------------------------------------------- +/** + * Ensures that Python with a minimum required version is installed and available in the system PATH. + * + * Checks for either `python3` or `python` executables and verifies that the version is at least the specified minimum (default: 3.10). Exits the process with an error message if the requirement is not met. + * + * @param {number} [minMajor=3] - Minimum required major version of Python. + * @param {number} [minMinor=10] - Minimum required minor version of Python. + */ function requirePython(minMajor = 3, minMinor = 10) { const candidates = ['python3', 'python']; @@ -77,6 +105,11 @@ function requirePython(minMajor = 3, minMinor = 10) { `\n→ install with your package manager, or https://python.org`); } +/** + * Ensures that the Docker CLI is installed and the Docker daemon is running. + * + * @throws {Error} If Docker is not installed or the Docker daemon is not running. + */ function requireDockerDaemon() { requireTool('docker', { help: 'https://docs.docker.com/get-docker/' }); try { @@ -88,19 +121,33 @@ function requireDockerDaemon() { // -------------------------------------------------------------------- // Grouped checks -// -------------------------------------------------------------------- +/** + * Ensures that required dependencies for generating CRD documentation are installed. + * + * Verifies the presence of the {@link git} and {@link crd-ref-docs} command-line tools, exiting the process with an error message if either is missing. + */ function verifyCrdDependencies() { requireCmd('git', 'install Git: https://git-scm.com/downloads'); requireCmd('crd-ref-docs', 'https://github.com/elastic/crd-ref-docs'); } +/** + * Ensures that all required tools for Helm documentation generation are installed. + * + * Checks for the presence of `helm-docs`, `pandoc`, and `git`, exiting the process with an error if any are missing. + */ function verifyHelmDependencies() { requireCmd('helm-docs', 'https://github.com/norwoodj/helm-docs'); requireCmd('pandoc', 'brew install pandoc or https://pandoc.org'); requireCmd('git', 'install Git: https://git-scm.com/downloads'); } +/** + * Ensures all dependencies required for generating property documentation are installed. + * + * Checks for the presence of `make`, Python 3.10 or newer, and at least one C++ compiler (`gcc` or `clang`). Exits the process with an error message if any dependency is missing. + */ function verifyPropertyDependencies() { requireCmd('make', 'your OS package manager'); requirePython(); @@ -112,6 +159,13 @@ function verifyPropertyDependencies() { } } +/** + * Ensures all required dependencies for generating Redpanda metrics documentation are installed. + * + * Verifies that Python 3.10+, `curl`, and `tar` are available, and that the Docker daemon is running. + * + * @throws {Error} If any required dependency is missing or the Docker daemon is not running. + */ function verifyMetricsDependencies() { requirePython(); requireCmd('curl'); diff --git a/cli-utils/convert-doc-links.js b/cli-utils/convert-doc-links.js index 609c3a1..7c297aa 100644 --- a/cli-utils/convert-doc-links.js +++ b/cli-utils/convert-doc-links.js @@ -1,15 +1,14 @@ const { URL } = require('url'); /** - * Convert a docs.redpanda.com URL (optionally suffixed with “[label]”) into - * an Antora xref resource ID, preserving that label in brackets. + * Converts a docs.redpanda.com URL, optionally suffixed with a label in brackets, into an Antora xref resource ID string. * - * Example: - * urlToXref('https://docs.redpanda.com/v25.1/reference/configuration/[Config]') - * // → 'xref:reference:configuration.adoc[Config]' + * If the input includes a label in square brackets (e.g., `[Label]`), the label is preserved and appended to the resulting xref. * - * @param {string} input - * @returns {string} + * @param {string} input - A docs.redpanda.com URL, optionally followed by a label in square brackets. + * @returns {string} The corresponding Antora xref resource ID, with the label preserved if present. + * + * @throws {Error} If the input is not a valid URL or does not belong to docs.redpanda.com. */ function urlToXref(input) { // Peel off an optional “[label]” diff --git a/cli-utils/self-managed-docs-branch.js b/cli-utils/self-managed-docs-branch.js index 629ceb9..51a14a4 100644 --- a/cli-utils/self-managed-docs-branch.js +++ b/cli-utils/self-managed-docs-branch.js @@ -3,8 +3,11 @@ const yaml = require('js-yaml'); const { spawnSync } = require('child_process'); /** - * Fetches the latest documented Self-Managed version from the remote docs repo's antora.yml - * @returns {Promise} example: "25.1" + * Retrieves the current Self-Managed documentation version from the remote antora.yml file. + * + * @returns {Promise} Resolves with the version string (e.g., "25.1"). + * + * @throws {Error} If the antora.yml file cannot be fetched, parsed, or if the version field is missing. */ function fetchRemoteAntoraVersion() { const url = 'https://raw.githubusercontent.com/redpanda-data/docs/main/antora.yml' @@ -32,10 +35,14 @@ function fetchRemoteAntoraVersion() { } /** - * Given an operator tag (such as "operator/v25.1.2" or "v25.1.2") and - * the remote Antora version (such as "25.1"), decide which docs branch to use. + * Determines the appropriate documentation branch for a given operator tag based on the remote Antora version. + * + * Normalizes the input tag, extracts the major.minor version, and applies version-specific logic to select the correct branch. Verifies that the chosen branch exists in the remote repository. + * + * @param {string} operatorTag - The operator tag to evaluate (e.g., "operator/v25.1.2" or "v25.1.2"). + * @returns {Promise} The name of the documentation branch to use. * - * Throws if the chosen branch does not exist on origin. + * @throws {Error} If the tag cannot be parsed or if the determined branch does not exist in the remote repository. */ async function determineDocsBranch(operatorTag) { // Strip any "operator/" prefix