@redpanda-data/docs-extensions-and-macros 4.13.1 → 4.13.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/bin/doc-tools-mcp.js +15 -3
  2. package/bin/doc-tools.js +767 -2088
  3. package/bin/mcp-tools/property-docs.js +18 -0
  4. package/bin/mcp-tools/rpcn-docs.js +28 -3
  5. package/cli-utils/antora-utils.js +53 -2
  6. package/cli-utils/dependencies.js +313 -0
  7. package/cli-utils/diff-utils.js +273 -0
  8. package/cli-utils/doc-tools-utils.js +54 -0
  9. package/extensions/algolia-indexer/generate-index.js +134 -102
  10. package/extensions/algolia-indexer/index.js +70 -38
  11. package/extensions/collect-bloblang-samples.js +2 -1
  12. package/extensions/generate-rp-connect-categories.js +126 -67
  13. package/extensions/generate-rp-connect-info.js +291 -137
  14. package/macros/rp-connect-components.js +34 -5
  15. package/package.json +4 -3
  16. package/tools/add-commercial-names.js +207 -0
  17. package/tools/generate-cli-docs.js +6 -2
  18. package/tools/get-console-version.js +5 -0
  19. package/tools/get-redpanda-version.js +5 -0
  20. package/tools/property-extractor/compare-properties.js +3 -3
  21. package/tools/property-extractor/generate-handlebars-docs.js +14 -14
  22. package/tools/property-extractor/generate-pr-summary.js +46 -0
  23. package/tools/property-extractor/pr-summary-formatter.js +375 -0
  24. package/tools/redpanda-connect/README.adoc +403 -38
  25. package/tools/redpanda-connect/connector-binary-analyzer.js +588 -0
  26. package/tools/redpanda-connect/generate-rpcn-connector-docs.js +97 -34
  27. package/tools/redpanda-connect/parse-csv-connectors.js +1 -1
  28. package/tools/redpanda-connect/pr-summary-formatter.js +601 -0
  29. package/tools/redpanda-connect/report-delta.js +69 -2
  30. package/tools/redpanda-connect/rpcn-connector-docs-handler.js +1180 -0
  31. package/tools/redpanda-connect/templates/connector.hbs +38 -0
  32. package/tools/redpanda-connect/templates/intro.hbs +0 -20
  33. package/tools/redpanda-connect/update-nav.js +205 -0
@@ -10,6 +10,8 @@ const { spawnSync } = require('child_process');
10
10
  const { findRepoRoot, getDocToolsCommand, MAX_EXEC_BUFFER_SIZE, DEFAULT_COMMAND_TIMEOUT } = require('./utils');
11
11
  const { getAntoraStructure } = require('./antora');
12
12
  const { createJob } = require('./job-queue');
13
+ const fs = require('fs');
14
+ const path = require('path');
13
15
 
14
16
  /**
15
17
  * Generate Redpanda property documentation
@@ -59,6 +61,7 @@ function generatePropertyDocs(args) {
59
61
  const docTools = getDocToolsCommand(repoRoot);
60
62
 
61
63
  // Build command arguments
64
+ // Note: --cloud-support is enabled by default in the CLI, so we don't need to add it explicitly
62
65
  const baseArgs = ['generate', 'property-docs'];
63
66
 
64
67
  if (args.tag) {
@@ -73,6 +76,21 @@ function generatePropertyDocs(args) {
73
76
  baseArgs.push('--generate-partials');
74
77
  }
75
78
 
79
+ // Default to using property-overrides.json from docs-data if it exists
80
+ let overridesPath = args.overrides;
81
+ if (!overridesPath) {
82
+ // Try to find docs-data/property-overrides.json in current directory
83
+ const defaultOverrides = path.join(process.cwd(), 'docs-data', 'property-overrides.json');
84
+ if (fs.existsSync(defaultOverrides)) {
85
+ overridesPath = defaultOverrides;
86
+ }
87
+ }
88
+
89
+ if (overridesPath) {
90
+ baseArgs.push('--overrides');
91
+ baseArgs.push(overridesPath);
92
+ }
93
+
76
94
  // If background mode, create job and return immediately
77
95
  if (args.background) {
78
96
  const cmdArgs = [docTools.program, ...docTools.getArgs(baseArgs)];
@@ -12,6 +12,8 @@ const { execSync, spawnSync } = require('child_process');
12
12
  const { findRepoRoot, MAX_EXEC_BUFFER_SIZE, DEFAULT_COMMAND_TIMEOUT } = require('./utils');
13
13
  const { getAntoraStructure } = require('./antora');
14
14
  const cache = require('./cache');
15
+ const fs = require('fs');
16
+ const path = require('path');
15
17
 
16
18
  /**
17
19
  * Generate Redpanda Connect connector documentation
@@ -33,12 +35,16 @@ function generateRpConnectDocs(args = {}) {
33
35
  try {
34
36
  // Build command arguments array (no shell interpolation)
35
37
  const cmdArgs = ['doc-tools', 'generate', 'rpcn-connector-docs'];
36
-
38
+
37
39
  // Add flags only when present, each as separate array entries
38
40
  if (args.fetch_connectors) cmdArgs.push('--fetch-connectors');
39
41
  if (args.draft_missing) cmdArgs.push('--draft-missing');
40
42
  if (args.update_whats_new) cmdArgs.push('--update-whats-new');
41
43
  if (args.include_bloblang) cmdArgs.push('--include-bloblang');
44
+ if (args.skip_cloud_detection) cmdArgs.push('--skip-cloud-detection');
45
+ if (args.skip_binary_analysis) cmdArgs.push('--skip-binary-analysis');
46
+ if (args.skip_cloud_analysis) cmdArgs.push('--skip-cloud-analysis');
47
+ if (args.skip_cgo_analysis) cmdArgs.push('--skip-cgo-analysis');
42
48
  if (args.data_dir) {
43
49
  cmdArgs.push('--data-dir');
44
50
  cmdArgs.push(args.data_dir);
@@ -51,9 +57,28 @@ function generateRpConnectDocs(args = {}) {
51
57
  cmdArgs.push('--csv');
52
58
  cmdArgs.push(args.csv);
53
59
  }
54
- if (args.overrides) {
60
+
61
+ // Default to using overrides.json from docs-data if it exists
62
+ let overridesPath = args.overrides;
63
+ if (!overridesPath) {
64
+ // Try to find docs-data/overrides.json in current directory
65
+ const defaultOverrides = path.join(process.cwd(), 'docs-data', 'overrides.json');
66
+ if (fs.existsSync(defaultOverrides)) {
67
+ overridesPath = defaultOverrides;
68
+ }
69
+ }
70
+
71
+ if (overridesPath) {
55
72
  cmdArgs.push('--overrides');
56
- cmdArgs.push(args.overrides);
73
+ cmdArgs.push(overridesPath);
74
+ }
75
+ if (args.cloud_version) {
76
+ cmdArgs.push('--cloud-version');
77
+ cmdArgs.push(args.cloud_version);
78
+ }
79
+ if (args.cgo_version) {
80
+ cmdArgs.push('--cgo-version');
81
+ cmdArgs.push(args.cgo_version);
57
82
  }
58
83
 
59
84
  const result = spawnSync('npx', cmdArgs, {
@@ -71,8 +71,8 @@ function getAntoraValue(keyPath) {
71
71
 
72
72
  /**
73
73
  * Safely sets a nested value in the Antora configuration, given a "dot path".
74
- * If the file or path does not exist, it will create intermediate objects as needed.
75
- * After setting the value, writes the updated YAML back to `antora.yml`.
74
+ * Uses surgical text replacement to preserve formatting, comments, and other content.
75
+ * Only works for asciidoc.attributes.* paths for now.
76
76
  *
77
77
  * @param {string} keyPath
78
78
  * A dot-separated path to set (e.g. "asciidoc.attributes.latest-connect-version").
@@ -96,6 +96,57 @@ function setAntoraValue(keyPath, newValue) {
96
96
  return false;
97
97
  }
98
98
 
99
+ // For asciidoc.attributes.* paths, use surgical text replacement
100
+ if (keyPath.startsWith('asciidoc.attributes.')) {
101
+ const attributeName = keyPath.replace('asciidoc.attributes.', '');
102
+
103
+ try {
104
+ let fileContents = fs.readFileSync(antoraPath, 'utf8');
105
+
106
+ // Pattern to match the attribute line (handles various YAML formats)
107
+ // Matches: " attribute-name: value" or " attribute-name: 'value'" or " attribute-name: \"value\""
108
+ const pattern = new RegExp(`^(\\s+${attributeName}:\\s*)(.*)$`, 'm');
109
+
110
+ // Format the new value (quote strings with special chars, leave numbers/booleans as-is)
111
+ let formattedValue = newValue;
112
+ if (typeof newValue === 'string') {
113
+ // Quote if it contains special characters or spaces
114
+ if (newValue.match(/[:\s#\[\]{},'"]|^[&*!|>@`]/) || newValue.startsWith('v')) {
115
+ formattedValue = `'${newValue}'`;
116
+ }
117
+ }
118
+
119
+ if (pattern.test(fileContents)) {
120
+ // Attribute exists - replace its value
121
+ fileContents = fileContents.replace(pattern, `$1${formattedValue}`);
122
+ } else {
123
+ // Attribute doesn't exist - add it in the attributes section
124
+ // Find the attributes: section and add it there
125
+ const attributesPattern = /^(\s+)attributes:\s*$/m;
126
+ const match = fileContents.match(attributesPattern);
127
+ if (match) {
128
+ const indent = match[1] + ' '; // Two more spaces for attribute items
129
+ const newLine = `${indent}${attributeName}: ${formattedValue}\n`;
130
+ // Insert after the "attributes:" line
131
+ const insertPos = match.index + match[0].length;
132
+ fileContents = fileContents.slice(0, insertPos) + '\n' + newLine + fileContents.slice(insertPos + 1);
133
+ } else {
134
+ console.error(`Could not find "attributes:" section in ${path.basename(antoraPath)}`);
135
+ return false;
136
+ }
137
+ }
138
+
139
+ fs.writeFileSync(antoraPath, fileContents, 'utf8');
140
+ return true;
141
+ } catch (err) {
142
+ console.error(`Error updating ${path.basename(antoraPath)}: ${err.message}`);
143
+ return false;
144
+ }
145
+ }
146
+
147
+ // For non-attribute paths, fall back to full YAML rewrite (legacy behavior)
148
+ console.warn(`Warning: ${keyPath} uses full YAML rewrite which may affect formatting`);
149
+
99
150
  let config;
100
151
  try {
101
152
  const fileContents = fs.readFileSync(antoraPath, 'utf8');
@@ -0,0 +1,313 @@
1
+ 'use strict'
2
+
3
+ const { execSync } = require('child_process')
4
+ const { fail } = require('./doc-tools-utils')
5
+
6
+ /**
7
+ * Ensures that a specified command-line tool is installed and operational.
8
+ *
9
+ * Attempts to execute the tool with a version flag to verify its presence. If the tool
10
+ * is missing or fails to run, the process exits with an error message and optional
11
+ * installation hint.
12
+ *
13
+ * @param {string} cmd - The name of the tool to check (for example, 'docker', 'helm-docs').
14
+ * @param {object} [opts] - Optional settings.
15
+ * @param {string} [opts.versionFlag='--version'] - The flag used to test the tool's execution.
16
+ * @param {string} [opts.help] - An optional hint or installation instruction shown on failure.
17
+ */
18
+ function requireTool (cmd, { versionFlag = '--version', help = '' } = {}) {
19
+ try {
20
+ execSync(`${cmd} ${versionFlag}`, { stdio: 'ignore' })
21
+ } catch {
22
+ const hint = help ? `\n→ ${help}` : ''
23
+ fail(`'${cmd}' is required but not found.${hint}`)
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Ensures that a command-line tool is installed by checking if it responds to a specified flag.
29
+ *
30
+ * @param {string} cmd - The name of the command-line tool to check.
31
+ * @param {string} [help] - Optional help text to display if the tool is not found.
32
+ * @param {string} [versionFlag='--version'] - The flag to use when checking if the tool is installed.
33
+ */
34
+ function requireCmd (cmd, help, versionFlag = '--version') {
35
+ requireTool(cmd, { versionFlag, help })
36
+ }
37
+
38
+ /**
39
+ * Ensures that Python with a minimum required version is installed and available in the system PATH.
40
+ *
41
+ * Checks for either `python3` or `python` executables and verifies that the version is at least
42
+ * the specified minimum (default: 3.10). Exits the process with an error message if the
43
+ * requirement is not met.
44
+ *
45
+ * @param {number} [minMajor=3] - Minimum required major version of Python.
46
+ * @param {number} [minMinor=10] - Minimum required minor version of Python.
47
+ */
48
+ function requirePython (minMajor = 3, minMinor = 10) {
49
+ const candidates = ['python3', 'python', 'python3.12', 'python3.11', 'python3.10']
50
+ for (const p of candidates) {
51
+ try {
52
+ const out = execSync(`${p} --version`, { encoding: 'utf8' }).trim()
53
+ const [maj, min] = out.split(' ')[1].split('.').map(Number)
54
+ if (maj > minMajor || (maj === minMajor && min >= minMinor)) {
55
+ return
56
+ }
57
+ } catch {
58
+ /* ignore & try next */
59
+ }
60
+ }
61
+ fail(
62
+ `Python ${minMajor}.${minMinor}+ not found or too old.
63
+
64
+ **Quick Install (Recommended):**
65
+ Run the automated installer to set up all dependencies:
66
+ npm run install-test-dependencies
67
+
68
+ Or install manually from your package manager or https://python.org`
69
+ )
70
+ }
71
+
72
+ /**
73
+ * Ensures that the Docker CLI is installed and the Docker daemon is running.
74
+ */
75
+ function requireDockerDaemon () {
76
+ requireTool('docker', { help: 'https://docs.docker.com/get-docker/' })
77
+ try {
78
+ execSync('docker info', { stdio: 'ignore' })
79
+ } catch {
80
+ fail(`Docker daemon does not appear to be running.
81
+
82
+ **Quick Install (Recommended):**
83
+ Run the automated installer to set up all dependencies:
84
+ npm run install-test-dependencies
85
+
86
+ Or install and start Docker manually: https://docs.docker.com/get-docker/`)
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Ensures that required dependencies for generating CRD documentation are installed.
92
+ */
93
+ function verifyCrdDependencies () {
94
+ requireCmd('git', 'Install Git: https://git-scm.com/downloads')
95
+ requireCmd(
96
+ 'crd-ref-docs',
97
+ `
98
+ The 'crd-ref-docs' command is required but was not found.
99
+
100
+ **Quick Install (Recommended):**
101
+ Run the automated installer to set up all dependencies:
102
+ npm run install-test-dependencies
103
+
104
+ Or install manually (for macOS):
105
+
106
+ 1. Determine your architecture:
107
+ Run: \`uname -m\`
108
+
109
+ 2. Download and install:
110
+
111
+ - For Apple Silicon (M1/M2/M3):
112
+ curl -fLO https://github.com/elastic/crd-ref-docs/releases/download/v0.1.0/crd-ref-docs_0.1.0_Darwin_arm64.tar.gz
113
+ tar -xzf crd-ref-docs_0.1.0_Darwin_arm64.tar.gz
114
+ chmod +x crd-ref-docs
115
+ sudo mv crd-ref-docs /usr/local/bin/
116
+
117
+ - For Intel (x86_64):
118
+ curl -fLO https://github.com/elastic/crd-ref-docs/releases/download/v0.1.0/crd-ref-docs_0.1.0_Darwin_x86_64.tar.gz
119
+ tar -xzf crd-ref-docs_0.1.0_Darwin_x86_64.tar.gz
120
+ chmod +x crd-ref-docs
121
+ sudo mv crd-ref-docs /usr/local/bin/
122
+
123
+ For more details, visit: https://github.com/elastic/crd-ref-docs
124
+ `.trim()
125
+ )
126
+ requireCmd(
127
+ 'go',
128
+ `
129
+ The 'go' command (Golang) is required but was not found.
130
+
131
+ **Quick Install (Recommended):**
132
+ Run the automated installer to set up all dependencies:
133
+ npm run install-test-dependencies
134
+
135
+ Or install manually on macOS:
136
+
137
+ Option 1: Install via Homebrew (recommended):
138
+ brew install go
139
+
140
+ Option 2: Download directly from the official site:
141
+ 1. Visit: https://go.dev/dl/
142
+ 2. Download the appropriate installer for macOS.
143
+ 3. Run the installer and follow the instructions.
144
+
145
+ After installation, verify it works:
146
+ go version
147
+
148
+ For more details, see: https://go.dev/doc/install
149
+ `.trim(),
150
+ 'version'
151
+ )
152
+ }
153
+
154
+ /**
155
+ * Ensures that all required tools for Helm documentation generation are installed.
156
+ */
157
+ function verifyHelmDependencies () {
158
+ requireCmd(
159
+ 'helm-docs',
160
+ `
161
+ The 'helm-docs' command is required but was not found.
162
+
163
+ **Quick Install (Recommended):**
164
+ Run the automated installer to set up all dependencies:
165
+ npm run install-test-dependencies
166
+
167
+ Or install manually (for macOS):
168
+
169
+ 1. Determine your architecture:
170
+ Run: \`uname -m\`
171
+
172
+ 2. Download and install:
173
+
174
+ - For Apple Silicon (M1/M2/M3):
175
+ curl -fLO https://github.com/norwoodj/helm-docs/releases/download/v1.11.0/helm-docs_1.11.0_Darwin_arm64.tar.gz
176
+ tar -xzf helm-docs_1.11.0_Darwin_arm64.tar.gz
177
+ chmod +x helm-docs
178
+ sudo mv helm-docs /usr/local/bin/
179
+
180
+ - For Intel (x86_64):
181
+ curl -fLO https://github.com/norwoodj/helm-docs/releases/download/v1.11.0/helm-docs_1.11.0_Darwin_x86_64.tar.gz
182
+ tar -xzf helm-docs_1.11.0_Darwin_x86_64.tar.gz
183
+ chmod +x helm-docs
184
+ sudo mv helm-docs /usr/local/bin/
185
+
186
+ Alternatively, if you use Homebrew:
187
+ brew install norwoodj/tap/helm-docs
188
+
189
+ For more details, visit: https://github.com/norwoodj/helm-docs
190
+ `.trim()
191
+ )
192
+ requireCmd('pandoc', 'brew install pandoc or https://pandoc.org')
193
+ requireCmd('git', 'Install Git: https://git-scm.com/downloads')
194
+ }
195
+
196
+ /**
197
+ * Ensures all dependencies required for generating property documentation are installed.
198
+ */
199
+ function verifyPropertyDependencies () {
200
+ requireCmd('make', 'Your OS package manager')
201
+ requirePython()
202
+
203
+ // Check for Node.js (required for Handlebars templates)
204
+ requireCmd('node', 'https://nodejs.org/en/download/ or use your package manager (for example, brew install node)')
205
+ requireCmd('npm', 'Usually installed with Node.js')
206
+
207
+ // Check for C++ compiler
208
+ let cppCompiler = null
209
+ try {
210
+ execSync('gcc --version', { stdio: 'ignore' })
211
+ cppCompiler = 'gcc'
212
+ } catch {
213
+ try {
214
+ execSync('clang --version', { stdio: 'ignore' })
215
+ cppCompiler = 'clang'
216
+ } catch {
217
+ fail(`A C++ compiler (gcc or clang) is required for tree-sitter compilation.
218
+
219
+ **Quick Install (Recommended):**
220
+ Run the automated installer to set up all dependencies:
221
+ npm run install-test-dependencies
222
+
223
+ Or install manually:
224
+
225
+ On macOS, install Xcode Command Line Tools:
226
+ xcode-select --install
227
+
228
+ On Linux (Ubuntu/Debian):
229
+ sudo apt update && sudo apt install build-essential
230
+
231
+ On Linux (CentOS/RHEL/Fedora):
232
+ sudo yum groupinstall "Development Tools"
233
+ # or on newer versions:
234
+ sudo dnf groupinstall "Development Tools"
235
+
236
+ After installation, verify with:
237
+ gcc --version
238
+ # or
239
+ clang --version`)
240
+ }
241
+ }
242
+
243
+ // Check for C++ standard library headers (critical for tree-sitter compilation)
244
+ const fs = require('fs')
245
+ const path = require('path')
246
+ const os = require('os')
247
+
248
+ let tempDir = null
249
+ let compileCmd = cppCompiler === 'gcc' ? 'gcc' : 'clang++'
250
+ try {
251
+ const testProgram = '#include <functional>\nint main() { return 0; }'
252
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cpp-test-'))
253
+ const tempFile = path.join(tempDir, 'test.cpp')
254
+ fs.writeFileSync(tempFile, testProgram)
255
+
256
+ execSync(`${compileCmd} -x c++ -fsyntax-only "${tempFile}"`, { stdio: 'ignore' })
257
+ fs.rmSync(tempDir, { recursive: true, force: true })
258
+ } catch {
259
+ if (tempDir) {
260
+ try {
261
+ fs.rmSync(tempDir, { recursive: true, force: true })
262
+ } catch {
263
+ // Ignore cleanup errors
264
+ }
265
+ }
266
+ fail(`C++ standard library headers are missing or incomplete.
267
+
268
+ **Quick Install (Recommended):**
269
+ Run the automated installer to set up all dependencies:
270
+ npm run install-test-dependencies
271
+
272
+ Or fix manually:
273
+
274
+ 1. **Test if the issue exists**:
275
+ echo '#include <functional>' | ${compileCmd} -x c++ -fsyntax-only -
276
+
277
+ 2. **If the test fails, try these fixes in order**:
278
+ **Fix 1**: Reset developer path
279
+ sudo xcode-select --reset
280
+
281
+ **Fix 2**: Force reinstall Command Line Tools
282
+ sudo rm -rf /Library/Developer/CommandLineTools
283
+ xcode-select --install
284
+
285
+ Complete the GUI installation dialog that appears.
286
+
287
+ 3. **Verify the fix**:
288
+ echo '#include <functional>' | ${compileCmd} -x c++ -fsyntax-only -
289
+ If successful, you should see no output and the command should exit with code 0.
290
+ `)
291
+ }
292
+ }
293
+
294
+ /**
295
+ * Ensures all required dependencies for generating Redpanda metrics documentation are installed.
296
+ */
297
+ function verifyMetricsDependencies () {
298
+ requirePython()
299
+ requireCmd('curl')
300
+ requireCmd('tar')
301
+ requireDockerDaemon()
302
+ }
303
+
304
+ module.exports = {
305
+ requireTool,
306
+ requireCmd,
307
+ requirePython,
308
+ requireDockerDaemon,
309
+ verifyCrdDependencies,
310
+ verifyHelmDependencies,
311
+ verifyPropertyDependencies,
312
+ verifyMetricsDependencies
313
+ }