@redpanda-data/docs-extensions-and-macros 4.13.1 → 4.13.3
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.
- package/bin/doc-tools-mcp.js +16 -4
- package/bin/doc-tools.js +768 -2089
- package/bin/mcp-tools/generated-docs-review.js +2 -2
- package/bin/mcp-tools/mcp-validation.js +1 -1
- package/bin/mcp-tools/openapi.js +2 -2
- package/bin/mcp-tools/property-docs.js +18 -0
- package/bin/mcp-tools/rpcn-docs.js +28 -3
- package/cli-utils/antora-utils.js +53 -2
- package/cli-utils/dependencies.js +313 -0
- package/cli-utils/diff-utils.js +273 -0
- package/cli-utils/doc-tools-utils.js +54 -0
- package/extensions/algolia-indexer/generate-index.js +134 -102
- package/extensions/algolia-indexer/index.js +70 -38
- package/extensions/collect-bloblang-samples.js +2 -1
- package/extensions/generate-rp-connect-categories.js +125 -67
- package/extensions/generate-rp-connect-info.js +291 -137
- package/macros/rp-connect-components.js +34 -5
- package/package.json +4 -3
- package/tools/add-commercial-names.js +207 -0
- package/tools/bundle-openapi.js +1 -1
- package/tools/generate-cli-docs.js +6 -2
- package/tools/get-console-version.js +5 -0
- package/tools/get-redpanda-version.js +5 -0
- package/tools/property-extractor/compare-properties.js +3 -3
- package/tools/property-extractor/generate-handlebars-docs.js +14 -14
- package/tools/property-extractor/generate-pr-summary.js +46 -0
- package/tools/property-extractor/pr-summary-formatter.js +375 -0
- package/tools/redpanda-connect/README.adoc +403 -38
- package/tools/redpanda-connect/connector-binary-analyzer.js +588 -0
- package/tools/redpanda-connect/generate-rpcn-connector-docs.js +97 -34
- package/tools/redpanda-connect/parse-csv-connectors.js +1 -1
- package/tools/redpanda-connect/pr-summary-formatter.js +663 -0
- package/tools/redpanda-connect/report-delta.js +70 -2
- package/tools/redpanda-connect/rpcn-connector-docs-handler.js +1279 -0
- package/tools/redpanda-connect/templates/connector.hbs +38 -0
- package/tools/redpanda-connect/templates/intro.hbs +0 -20
- package/tools/redpanda-connect/update-nav.js +216 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const glob = require('glob');
|
|
6
|
+
|
|
7
|
+
// Commercial name mappings based on connector patterns
|
|
8
|
+
const commercialNameMappings = {
|
|
9
|
+
// AWS services
|
|
10
|
+
'aws_s3': 'Amazon S3, AWS S3, S3, Simple Storage Service',
|
|
11
|
+
'aws_kinesis': 'Amazon Kinesis, AWS Kinesis, Kinesis',
|
|
12
|
+
'aws_sqs': 'Amazon SQS, AWS SQS, SQS, Simple Queue Service',
|
|
13
|
+
'aws_sns': 'Amazon SNS, AWS SNS, SNS, Simple Notification Service',
|
|
14
|
+
'aws_dynamodb': 'Amazon DynamoDB, AWS DynamoDB, DynamoDB',
|
|
15
|
+
'aws_kinesis_firehose': 'Amazon Kinesis Firehose, AWS Kinesis Firehose, Kinesis Firehose',
|
|
16
|
+
'aws_lambda': 'Amazon Lambda, AWS Lambda, Lambda',
|
|
17
|
+
'aws_cloudwatch': 'Amazon CloudWatch, AWS CloudWatch, CloudWatch',
|
|
18
|
+
|
|
19
|
+
// Message queues
|
|
20
|
+
'amqp_0_9': 'RabbitMQ, AMQP',
|
|
21
|
+
'amqp_1': 'RabbitMQ, AMQP, Apache Qpid',
|
|
22
|
+
'kafka': 'Apache Kafka, Kafka',
|
|
23
|
+
'kafka_franz': 'Apache Kafka, Kafka',
|
|
24
|
+
'nats': 'NATS, NATS.io',
|
|
25
|
+
'nats_jetstream': 'NATS JetStream, NATS',
|
|
26
|
+
'nats_stream': 'NATS Streaming, NATS',
|
|
27
|
+
'pulsar': 'Apache Pulsar, Pulsar',
|
|
28
|
+
'redis_pubsub': 'Redis Pub/Sub, Redis',
|
|
29
|
+
'redis_streams': 'Redis Streams, Redis',
|
|
30
|
+
'redis_list': 'Redis Lists, Redis',
|
|
31
|
+
|
|
32
|
+
// Databases - general patterns
|
|
33
|
+
'mongodb': 'MongoDB, Mongo',
|
|
34
|
+
'cassandra': 'Apache Cassandra, Cassandra',
|
|
35
|
+
'elasticsearch': 'Elasticsearch, Elastic',
|
|
36
|
+
'influxdb': 'InfluxDB, Influx',
|
|
37
|
+
'redis_hash': 'Redis, Redis Hash',
|
|
38
|
+
|
|
39
|
+
// HTTP/API
|
|
40
|
+
'http_client': 'HTTP, REST API, REST',
|
|
41
|
+
'http_server': 'HTTP, REST API, REST, Gateway',
|
|
42
|
+
'webhook': 'Webhook, HTTP',
|
|
43
|
+
|
|
44
|
+
// File formats
|
|
45
|
+
'unarchive': 'ZIP, TAR, GZIP, Archive, JSON, CSV',
|
|
46
|
+
'archive': 'ZIP, TAR, GZIP, Archive',
|
|
47
|
+
'lines': 'Text Files, Plain Text, Log Files',
|
|
48
|
+
'csv': 'CSV, Comma-Separated Values',
|
|
49
|
+
|
|
50
|
+
// Cloud providers (generic patterns will catch aws_*, gcp_*, azure_*)
|
|
51
|
+
'gcp_pubsub': 'Google Cloud Pub/Sub, GCP Pub/Sub, Google Pub/Sub',
|
|
52
|
+
'gcp_bigquery': 'Google BigQuery, GCP BigQuery, BigQuery',
|
|
53
|
+
'gcp_cloud_storage': 'Google Cloud Storage, GCS, GCP Cloud Storage',
|
|
54
|
+
'azure_blob_storage': 'Azure Blob Storage, Microsoft Azure Storage',
|
|
55
|
+
'azure_queue_storage': 'Azure Queue Storage, Microsoft Azure Queue',
|
|
56
|
+
'azure_table_storage': 'Azure Table Storage, Microsoft Azure Table',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// Pattern-based commercial names (for connectors not in explicit mapping)
|
|
60
|
+
function getCommercialNamesFromPattern(connectorName) {
|
|
61
|
+
const names = [];
|
|
62
|
+
|
|
63
|
+
// AWS pattern
|
|
64
|
+
if (connectorName.startsWith('aws_')) {
|
|
65
|
+
names.push('Amazon');
|
|
66
|
+
names.push('AWS');
|
|
67
|
+
const serviceName = connectorName.replace('aws_', '').replace(/_/g, ' ');
|
|
68
|
+
names.push(serviceName.split(' ').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// GCP pattern
|
|
72
|
+
if (connectorName.startsWith('gcp_')) {
|
|
73
|
+
names.push('Google Cloud');
|
|
74
|
+
names.push('GCP');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Azure pattern
|
|
78
|
+
if (connectorName.startsWith('azure_')) {
|
|
79
|
+
names.push('Microsoft Azure');
|
|
80
|
+
names.push('Azure');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// SQL databases
|
|
84
|
+
if (connectorName.startsWith('sql_')) {
|
|
85
|
+
names.push('SQL');
|
|
86
|
+
names.push('PostgreSQL');
|
|
87
|
+
names.push('MySQL');
|
|
88
|
+
names.push('Microsoft SQL Server');
|
|
89
|
+
names.push('ClickHouse');
|
|
90
|
+
names.push('Trino');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return names;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getCommercialNames(connectorName) {
|
|
97
|
+
// Check explicit mapping first
|
|
98
|
+
if (commercialNameMappings[connectorName]) {
|
|
99
|
+
return commercialNameMappings[connectorName];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Try pattern matching
|
|
103
|
+
const patternNames = getCommercialNamesFromPattern(connectorName);
|
|
104
|
+
if (patternNames.length > 0) {
|
|
105
|
+
return patternNames.join(', ');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function addCommercialNamesToFile(filePath) {
|
|
112
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
113
|
+
let lines = content.split('\n');
|
|
114
|
+
|
|
115
|
+
// Extract connector name from file path
|
|
116
|
+
const connectorName = path.basename(filePath, '.adoc');
|
|
117
|
+
|
|
118
|
+
// Remove existing page-commercial-names if present (we'll re-add in correct location)
|
|
119
|
+
lines = lines.filter(line => !line.includes(':page-commercial-names:'));
|
|
120
|
+
|
|
121
|
+
// Get commercial names
|
|
122
|
+
const commercialNames = getCommercialNames(connectorName);
|
|
123
|
+
if (!commercialNames) {
|
|
124
|
+
return { status: 'skip', reason: 'no commercial names found' };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Find the position to insert (after single-source tag if present, otherwise after title)
|
|
128
|
+
let insertIndex = -1;
|
|
129
|
+
let titleIndex = -1;
|
|
130
|
+
|
|
131
|
+
// First find the title
|
|
132
|
+
for (let i = 0; i < lines.length; i++) {
|
|
133
|
+
if (lines[i].startsWith('= ')) {
|
|
134
|
+
titleIndex = i;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (titleIndex === -1) {
|
|
140
|
+
return { status: 'error', reason: 'could not find title' };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Look for single-source tag after the title (with or without space after //)
|
|
144
|
+
let foundSingleSource = false;
|
|
145
|
+
for (let i = titleIndex + 1; i < Math.min(titleIndex + 10, lines.length); i++) {
|
|
146
|
+
if (lines[i].includes('tag::single-source[]')) {
|
|
147
|
+
insertIndex = i + 1;
|
|
148
|
+
foundSingleSource = true;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// If no single-source tag, insert after title
|
|
154
|
+
if (!foundSingleSource) {
|
|
155
|
+
insertIndex = titleIndex + 1;
|
|
156
|
+
// Skip any existing page attributes
|
|
157
|
+
while (insertIndex < lines.length && lines[insertIndex].startsWith(':')) {
|
|
158
|
+
insertIndex++;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (insertIndex === -1) {
|
|
163
|
+
return { status: 'error', reason: 'could not find title' };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Insert the attribute
|
|
167
|
+
lines.splice(insertIndex, 0, `:page-commercial-names: ${commercialNames}`);
|
|
168
|
+
|
|
169
|
+
// Write back
|
|
170
|
+
fs.writeFileSync(filePath, lines.join('\n'), 'utf8');
|
|
171
|
+
|
|
172
|
+
return { status: 'added', commercialNames };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Main execution
|
|
176
|
+
const basePath = process.argv[2] || '/Users/jakecahill/Documents/rp-connect-docs';
|
|
177
|
+
const pattern = `${basePath}/modules/components/pages/{inputs,outputs,processors}/*.adoc`;
|
|
178
|
+
|
|
179
|
+
console.log(`Finding connector files in: ${pattern}`);
|
|
180
|
+
const files = glob.sync(pattern).filter(f => !f.endsWith('about.adoc'));
|
|
181
|
+
|
|
182
|
+
console.log(`Found ${files.length} connector files\n`);
|
|
183
|
+
|
|
184
|
+
let added = 0;
|
|
185
|
+
let skipped = 0;
|
|
186
|
+
let errors = 0;
|
|
187
|
+
|
|
188
|
+
files.forEach(file => {
|
|
189
|
+
const connectorName = path.basename(file, '.adoc');
|
|
190
|
+
const result = addCommercialNamesToFile(file);
|
|
191
|
+
|
|
192
|
+
if (result.status === 'added') {
|
|
193
|
+
console.log(`✅ ${connectorName}: ${result.commercialNames}`);
|
|
194
|
+
added++;
|
|
195
|
+
} else if (result.status === 'skip') {
|
|
196
|
+
skipped++;
|
|
197
|
+
} else if (result.status === 'error') {
|
|
198
|
+
console.error(`❌ ${connectorName}: ${result.reason}`);
|
|
199
|
+
errors++;
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
console.log(`\n📊 Summary:`);
|
|
204
|
+
console.log(` ✅ Added: ${added}`);
|
|
205
|
+
console.log(` ⏭️ Skipped: ${skipped}`);
|
|
206
|
+
console.log(` ❌ Errors: ${errors}`);
|
|
207
|
+
console.log(` 📝 Total: ${files.length}`);
|
package/tools/bundle-openapi.js
CHANGED
|
@@ -551,7 +551,7 @@ function postProcessBundle(filePath, options, quiet = false) {
|
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
/**
|
|
554
|
-
* Bundle OpenAPI fragments for the specified API
|
|
554
|
+
* Bundle OpenAPI fragments for the specified API surfaces from a repository tag and write the resulting bundled YAML files to disk.
|
|
555
555
|
*
|
|
556
556
|
* @param {Object} options - Configuration options.
|
|
557
557
|
* @param {string} options.tag - Git tag to checkout (for example, 'v25.1.1').
|
|
@@ -274,7 +274,10 @@ IMPORTANT: This documentation is auto-generated. Do not edit manually. Run \`npm
|
|
|
274
274
|
'get-console-version',
|
|
275
275
|
'link-readme',
|
|
276
276
|
'fetch',
|
|
277
|
-
'setup-mcp'
|
|
277
|
+
'setup-mcp',
|
|
278
|
+
'validate-mcp',
|
|
279
|
+
'preview-prompt',
|
|
280
|
+
'mcp-version'
|
|
278
281
|
];
|
|
279
282
|
|
|
280
283
|
topLevelCommands.forEach(cmd => {
|
|
@@ -300,7 +303,8 @@ IMPORTANT: This documentation is auto-generated. Do not edit manually. Run \`npm
|
|
|
300
303
|
'helm-spec',
|
|
301
304
|
'cloud-regions',
|
|
302
305
|
'crd-spec',
|
|
303
|
-
'bundle-openapi'
|
|
306
|
+
'bundle-openapi',
|
|
307
|
+
'update-connect-version'
|
|
304
308
|
];
|
|
305
309
|
|
|
306
310
|
generateSubcommands.forEach(subcmd => {
|
|
@@ -50,6 +50,11 @@ module.exports = async function getConsoleVersion({ beta = false, fromAntora = f
|
|
|
50
50
|
? (data.latestBetaRelease || data.latestStableRelease)
|
|
51
51
|
: data.latestStableRelease;
|
|
52
52
|
|
|
53
|
+
if (!version) {
|
|
54
|
+
console.error('Could not determine Console version');
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
console.log(`CONSOLE_VERSION=${version}`);
|
|
54
59
|
console.log(`CONSOLE_DOCKER_REPO=${CONSOLE_DOCKER_REPO}`);
|
|
55
60
|
};
|
|
@@ -46,6 +46,11 @@ module.exports = async function getRedpandaVersion({ beta = false, fromAntora =
|
|
|
46
46
|
const rc = data.latestRcRelease;
|
|
47
47
|
const version = useBeta && rc ? rc.version : stableVersion;
|
|
48
48
|
|
|
49
|
+
if (!version) {
|
|
50
|
+
console.error('Could not determine Redpanda version');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
// Determine the Docker repository
|
|
50
55
|
const dockerRepo = (useBeta && rc) ? 'redpanda-unstable' : 'redpanda';
|
|
51
56
|
|
|
@@ -296,7 +296,7 @@ function generateConsoleReport(report, oldVersion, newVersion) {
|
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
if (report.emptyDescriptions.length > 0) {
|
|
299
|
-
console.log(`\
|
|
299
|
+
console.log(`\nWarning: Properties with empty descriptions (${report.emptyDescriptions.length}):`);
|
|
300
300
|
report.emptyDescriptions.forEach(prop => {
|
|
301
301
|
console.log(` • ${prop.name} (${prop.type})`);
|
|
302
302
|
});
|
|
@@ -362,7 +362,7 @@ function generateJsonReport(report, oldVersion, newVersion, outputPath) {
|
|
|
362
362
|
*/
|
|
363
363
|
function comparePropertyFiles(oldFilePath, newFilePath, oldVersion, newVersion, outputDir, filename = 'property-changes.json') {
|
|
364
364
|
try {
|
|
365
|
-
console.log(
|
|
365
|
+
console.log(`Comparing property files:`);
|
|
366
366
|
console.log(` Old: ${oldFilePath}`);
|
|
367
367
|
console.log(` New: ${newFilePath}`);
|
|
368
368
|
|
|
@@ -383,7 +383,7 @@ function comparePropertyFiles(oldFilePath, newFilePath, oldVersion, newVersion,
|
|
|
383
383
|
|
|
384
384
|
return report;
|
|
385
385
|
} catch (error) {
|
|
386
|
-
console.error(
|
|
386
|
+
console.error(`Error: Error comparing properties: ${error.message}`);
|
|
387
387
|
process.exit(1);
|
|
388
388
|
}
|
|
389
389
|
}
|
|
@@ -25,7 +25,7 @@ const helpers = require('./helpers');
|
|
|
25
25
|
// Register helpers
|
|
26
26
|
Object.entries(helpers).forEach(([name, fn]) => {
|
|
27
27
|
if (typeof fn !== 'function') {
|
|
28
|
-
console.error(
|
|
28
|
+
console.error(`Error: Helper "${name}" is not a function`);
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
handlebars.registerHelper(name, fn);
|
|
@@ -96,9 +96,9 @@ function registerPartials() {
|
|
|
96
96
|
}
|
|
97
97
|
handlebars.registerPartial('deprecated-property', fs.readFileSync(deprecatedPropertyTemplatePath, 'utf8'));
|
|
98
98
|
|
|
99
|
-
console.log('
|
|
99
|
+
console.log('Done: Registered all partials');
|
|
100
100
|
} catch (error) {
|
|
101
|
-
console.error('
|
|
101
|
+
console.error('Error: Failed to register Handlebars templates:');
|
|
102
102
|
console.error(` ${error.message}`);
|
|
103
103
|
throw error;
|
|
104
104
|
}
|
|
@@ -140,7 +140,7 @@ function generatePropertyPartials(properties, partialsDir, onRender) {
|
|
|
140
140
|
|
|
141
141
|
// Skip if we've already processed this key
|
|
142
142
|
if (processedKeys.has(key)) {
|
|
143
|
-
console.warn(
|
|
143
|
+
console.warn(`Warning: Duplicate key detected: ${key}`);
|
|
144
144
|
return;
|
|
145
145
|
}
|
|
146
146
|
processedKeys.add(key);
|
|
@@ -164,7 +164,7 @@ function generatePropertyPartials(properties, partialsDir, onRender) {
|
|
|
164
164
|
propertyGroups['object-storage'].push(prop);
|
|
165
165
|
break;
|
|
166
166
|
default:
|
|
167
|
-
console.warn(
|
|
167
|
+
console.warn(`Warning: Unknown config_scope: ${prop.config_scope} for ${prop.name}`);
|
|
168
168
|
break;
|
|
169
169
|
}
|
|
170
170
|
});
|
|
@@ -185,11 +185,11 @@ function generatePropertyPartials(properties, partialsDir, onRender) {
|
|
|
185
185
|
const content = pieces.join('\n');
|
|
186
186
|
const filename = `${type}-properties.adoc`;
|
|
187
187
|
fs.writeFileSync(path.join(propertiesPartialsDir, filename), AUTOGEN_NOTICE + content, 'utf8');
|
|
188
|
-
console.log(
|
|
188
|
+
console.log(`Done: Generated ${filename} (${props.length} properties)`);
|
|
189
189
|
totalCount += props.length;
|
|
190
190
|
});
|
|
191
191
|
|
|
192
|
-
console.log(
|
|
192
|
+
console.log(`Done: Done. ${totalCount} total properties.`);
|
|
193
193
|
return totalCount;
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -223,7 +223,7 @@ function generateDeprecatedDocs(properties, outputDir) {
|
|
|
223
223
|
|
|
224
224
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
225
225
|
fs.writeFileSync(outputPath, AUTOGEN_NOTICE + template(data), 'utf8');
|
|
226
|
-
console.log(
|
|
226
|
+
console.log(`Done: Generated ${outputPath}`);
|
|
227
227
|
return deprecatedProperties.length;
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -253,7 +253,7 @@ function generateTopicPropertyMappings(properties, partialsDir) {
|
|
|
253
253
|
fs.mkdirSync(propertiesPartialsDir, { recursive: true });
|
|
254
254
|
const mappingsOut = path.join(propertiesPartialsDir, 'topic-property-mappings.adoc');
|
|
255
255
|
fs.writeFileSync(mappingsOut, AUTOGEN_NOTICE + rendered, 'utf8');
|
|
256
|
-
console.log(
|
|
256
|
+
console.log(`Done: Generated ${mappingsOut}`);
|
|
257
257
|
return topicProperties.length;
|
|
258
258
|
}
|
|
259
259
|
|
|
@@ -324,7 +324,7 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
324
324
|
try {
|
|
325
325
|
generateTopicPropertyMappings(properties, process.env.OUTPUT_PARTIALS_DIR);
|
|
326
326
|
} catch (err) {
|
|
327
|
-
console.error(
|
|
327
|
+
console.error(`Error: Failed to generate topic-property-mappings.adoc: ${err.message}`);
|
|
328
328
|
}
|
|
329
329
|
} else {
|
|
330
330
|
console.log('📄 Skipping partial generation (set GENERATE_PARTIALS=1 and OUTPUT_PARTIALS_DIR to enable)');
|
|
@@ -338,7 +338,7 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
338
338
|
? ((partialsCount / totalProperties) * 100).toFixed(2)
|
|
339
339
|
: '0.00';
|
|
340
340
|
|
|
341
|
-
console.log('\
|
|
341
|
+
console.log('\nSummary:');
|
|
342
342
|
console.log(` Total properties found: ${totalProperties}`);
|
|
343
343
|
console.log(` Property partials generated: ${partialsCount} (${pctRendered}% of total)`);
|
|
344
344
|
console.log(` Not documented: ${notRendered}`);
|
|
@@ -374,15 +374,15 @@ if (require.main === module) {
|
|
|
374
374
|
|
|
375
375
|
const [inputFile, outputDir] = args;
|
|
376
376
|
if (!fs.existsSync(inputFile)) {
|
|
377
|
-
console.error(
|
|
377
|
+
console.error(`Error: Input file not found: ${inputFile}`);
|
|
378
378
|
process.exit(1);
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
try {
|
|
382
382
|
generateAllDocs(inputFile, outputDir);
|
|
383
|
-
console.log('
|
|
383
|
+
console.log('Done: Documentation generation completed successfully');
|
|
384
384
|
} catch (err) {
|
|
385
|
-
console.error(
|
|
385
|
+
console.error(`Error: ${err.message}`);
|
|
386
386
|
process.exit(1);
|
|
387
387
|
}
|
|
388
388
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Standalone CLI tool to generate PR summaries from property diff JSON files
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node generate-pr-summary.js <diff-json-file>
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* node generate-pr-summary.js ../../docs-data/redpanda-property-changes-v25.3.1-to-v25.3.3.json
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { printPRSummary } = require('./pr-summary-formatter');
|
|
16
|
+
|
|
17
|
+
// CLI usage
|
|
18
|
+
if (require.main === module) {
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
|
|
21
|
+
if (args.length < 1) {
|
|
22
|
+
console.error('Usage: node generate-pr-summary.js <diff-json-file>');
|
|
23
|
+
console.error('');
|
|
24
|
+
console.error('Example:');
|
|
25
|
+
console.error(' node generate-pr-summary.js redpanda-property-changes-v25.3.1-to-v25.3.3.json');
|
|
26
|
+
console.error('');
|
|
27
|
+
console.error('This tool reads a property diff JSON file (generated by compare-properties.js)');
|
|
28
|
+
console.error('and outputs a GitHub PR-ready markdown summary.');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const diffFilePath = path.resolve(args[0]);
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(diffFilePath)) {
|
|
35
|
+
console.error(`Error: File not found: ${diffFilePath}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const diffData = JSON.parse(fs.readFileSync(diffFilePath, 'utf8'));
|
|
41
|
+
printPRSummary(diffData);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(`Error: Error reading diff file: ${error.message}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|