@redpanda-data/docs-extensions-and-macros 4.10.1 → 4.10.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.js +21 -3
- package/package.json +1 -1
- package/tools/property-extractor/Makefile +1 -0
- package/tools/property-extractor/generate-handlebars-docs.js +255 -85
- package/tools/property-extractor/property_extractor.py +7 -4
- package/tools/property-extractor/templates/property-cloud.hbs +4 -9
- package/tools/property-extractor/templates/property-page-with-includes.hbs +17 -0
- package/tools/property-extractor/templates/property.hbs +6 -11
- package/tools/property-extractor/templates/topic-property-cloud.hbs +3 -6
- package/tools/property-extractor/templates/topic-property.hbs +2 -6
package/bin/doc-tools.js
CHANGED
|
@@ -1032,17 +1032,20 @@ automation
|
|
|
1032
1032
|
|
|
1033
1033
|
automation
|
|
1034
1034
|
.command('property-docs')
|
|
1035
|
-
.description('Generate JSON and AsciiDoc documentation for Redpanda configuration properties')
|
|
1035
|
+
.description('Generate JSON and AsciiDoc documentation for Redpanda configuration properties. By default, only extracts properties to JSON. Use --generate-partials to create consolidated AsciiDoc partials (including deprecated properties). Use --generate-pages to create complete property pages that include the partials using AsciiDoc includes.')
|
|
1036
1036
|
.option('--tag <tag>', 'Git tag or branch to extract from', 'dev')
|
|
1037
|
-
.option('--diff <oldTag>', 'Also diff autogenerated properties from <oldTag>
|
|
1037
|
+
.option('--diff <oldTag>', 'Also diff autogenerated properties from <oldTag> to <tag>')
|
|
1038
1038
|
.option('--overrides <path>', 'Optional JSON file with property description overrides')
|
|
1039
1039
|
.option('--output-dir <dir>', 'Where to write all generated files', 'modules/reference')
|
|
1040
|
-
.option('--cloud-support', '
|
|
1040
|
+
.option('--cloud-support', 'Add AsciiDoc tags to generated property docs to indicate which ones are supported in Redpanda Cloud. This data is fetched from the cloudv2 repository so requires a GitHub token with repo permissions. Set the token as an environment variable using GITHUB_TOKEN, GH_TOKEN, or REDPANDA_GITHUB_TOKEN')
|
|
1041
1041
|
.option('--template-property-page <path>', 'Custom Handlebars template for property page layout')
|
|
1042
1042
|
.option('--template-property <path>', 'Custom Handlebars template for individual property sections')
|
|
1043
1043
|
.option('--template-topic-property <path>', 'Custom Handlebars template for individual topic property sections')
|
|
1044
1044
|
.option('--template-deprecated <path>', 'Custom Handlebars template for deprecated properties page')
|
|
1045
1045
|
.option('--template-deprecated-property <path>', 'Custom Handlebars template for individual deprecated property sections')
|
|
1046
|
+
.option('--generate-partials', 'Generate consolidated property partials (cluster-properties.adoc, topic-properties.adoc, etc.) in the partials directory')
|
|
1047
|
+
.option('--partials-dir <path>', 'Directory for property partials (relative to output-dir)', 'partials')
|
|
1048
|
+
.option('--generate-pages', 'Generate complete property pages that include the partials using AsciiDoc includes')
|
|
1046
1049
|
.action((options) => {
|
|
1047
1050
|
verifyPropertyDependencies();
|
|
1048
1051
|
|
|
@@ -1091,6 +1094,7 @@ automation
|
|
|
1091
1094
|
}
|
|
1092
1095
|
if (templates.propertyPage) {
|
|
1093
1096
|
env.TEMPLATE_PROPERTY_PAGE = path.resolve(templates.propertyPage);
|
|
1097
|
+
env.TEMPLATE_PROPERTY_PAGE_WITH_INCLUDES = env.TEMPLATE_PROPERTY_PAGE;
|
|
1094
1098
|
}
|
|
1095
1099
|
if (templates.property) {
|
|
1096
1100
|
env.TEMPLATE_PROPERTY = path.resolve(templates.property);
|
|
@@ -1115,6 +1119,20 @@ automation
|
|
|
1115
1119
|
env.OUTPUT_ASCIIDOC_DIR = path.resolve(outputDir, 'pages', 'properties');
|
|
1116
1120
|
}
|
|
1117
1121
|
|
|
1122
|
+
// Set partials generation options
|
|
1123
|
+
if (options.generatePartials) {
|
|
1124
|
+
env.GENERATE_PARTIALS = '1';
|
|
1125
|
+
env.OUTPUT_PARTIALS_DIR = path.resolve(outputDir, options.partialsDir || 'partials');
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
// Set page generation options
|
|
1129
|
+
if (options.generatePages) {
|
|
1130
|
+
env.GENERATE_PAGES = '1';
|
|
1131
|
+
if (templates.propertyPage) {
|
|
1132
|
+
env.TEMPLATE_PROPERTY_PAGE_WITH_INCLUDES = env.TEMPLATE_PROPERTY_PAGE;
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1118
1136
|
const r = spawnSync('make', args, { cwd, stdio: 'inherit', env });
|
|
1119
1137
|
if (r.error) {
|
|
1120
1138
|
console.error(`❌ ${r.error.message}`);
|
package/package.json
CHANGED
|
@@ -28,6 +28,7 @@ TREE_SITTER := npx tree-sitter
|
|
|
28
28
|
OUTPUT_AUTOGENERATED_DIR ?= $(REPO_ROOT)/modules/reference
|
|
29
29
|
OUTPUT_ASCIIDOC_DIR ?= $(OUTPUT_AUTOGENERATED_DIR)/pages
|
|
30
30
|
OUTPUT_JSON_DIR ?= $(OUTPUT_AUTOGENERATED_DIR)/examples
|
|
31
|
+
OUTPUT_PARTIALS_DIR ?= $(OUTPUT_AUTOGENERATED_DIR)/partials
|
|
31
32
|
|
|
32
33
|
# --- Main build: venv, fetch code, build parser, extract & docgen ---
|
|
33
34
|
build: venv redpanda-git treesitter
|
|
@@ -27,6 +27,23 @@ Object.entries(helpers).forEach(([name, fn]) => {
|
|
|
27
27
|
handlebars.registerHelper(name, fn);
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Determines if a property is related to object storage.
|
|
32
|
+
* @param {Object} prop - The property object
|
|
33
|
+
* @returns {boolean} True if the property is object storage related
|
|
34
|
+
*/
|
|
35
|
+
function isObjectStorageProperty(prop) {
|
|
36
|
+
return prop.name && (
|
|
37
|
+
prop.name.includes('cloud_storage') ||
|
|
38
|
+
prop.name.includes('s3_') ||
|
|
39
|
+
prop.name.includes('azure_') ||
|
|
40
|
+
prop.name.includes('gcs_') ||
|
|
41
|
+
prop.name.includes('archival_') ||
|
|
42
|
+
prop.name.includes('remote_') ||
|
|
43
|
+
prop.name.includes('tiered_')
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
30
47
|
/**
|
|
31
48
|
* Configuration mapping for different property types
|
|
32
49
|
*/
|
|
@@ -60,17 +77,7 @@ NOTE: Some cluster properties require that you restart the cluster for any updat
|
|
|
60
77
|
sectionTitle: 'Cluster configuration',
|
|
61
78
|
groups: [
|
|
62
79
|
{
|
|
63
|
-
filter: (prop) => prop.config_scope === 'cluster' && !prop.is_deprecated && !(
|
|
64
|
-
prop.name && (
|
|
65
|
-
prop.name.includes('cloud_storage') ||
|
|
66
|
-
prop.name.includes('s3_') ||
|
|
67
|
-
prop.name.includes('azure_') ||
|
|
68
|
-
prop.name.includes('gcs_') ||
|
|
69
|
-
prop.name.includes('archival_') ||
|
|
70
|
-
prop.name.includes('remote_') ||
|
|
71
|
-
prop.name.includes('tiered_')
|
|
72
|
-
)
|
|
73
|
-
)
|
|
80
|
+
filter: (prop) => prop.config_scope === 'cluster' && !prop.is_deprecated && !isObjectStorageProperty(prop)
|
|
74
81
|
}
|
|
75
82
|
],
|
|
76
83
|
filename: 'cluster-properties.adoc'
|
|
@@ -85,15 +92,7 @@ NOTE: Some object storage properties require that you restart the cluster for an
|
|
|
85
92
|
sectionIntro: 'Object storage properties should only be set if you enable xref:manage:tiered-storage.adoc[Tiered Storage].',
|
|
86
93
|
groups: [
|
|
87
94
|
{
|
|
88
|
-
filter: (prop) => prop
|
|
89
|
-
prop.name.includes('cloud_storage') ||
|
|
90
|
-
prop.name.includes('s3_') ||
|
|
91
|
-
prop.name.includes('azure_') ||
|
|
92
|
-
prop.name.includes('gcs_') ||
|
|
93
|
-
prop.name.includes('archival_') ||
|
|
94
|
-
prop.name.includes('remote_') ||
|
|
95
|
-
prop.name.includes('tiered_')
|
|
96
|
-
) && !prop.is_deprecated
|
|
95
|
+
filter: (prop) => isObjectStorageProperty(prop) && !prop.is_deprecated
|
|
97
96
|
}
|
|
98
97
|
],
|
|
99
98
|
filename: 'object-storage-properties.adoc'
|
|
@@ -207,39 +206,165 @@ function registerPartials(hasCloudSupport = false) {
|
|
|
207
206
|
* Generates documentation for a specific property type
|
|
208
207
|
*/
|
|
209
208
|
function generatePropertyDocs(properties, config, outputDir) {
|
|
209
|
+
// Check if partials are being generated to determine which template to use
|
|
210
|
+
const useIncludes = process.env.GENERATE_PARTIALS === '1';
|
|
211
|
+
|
|
212
|
+
let templatePath;
|
|
213
|
+
if (useIncludes) {
|
|
214
|
+
// Use the include-based template when partials are also being generated
|
|
215
|
+
templatePath = getTemplatePath(
|
|
216
|
+
path.join(__dirname, 'templates', 'property-page-with-includes.hbs'),
|
|
217
|
+
'TEMPLATE_PROPERTY_PAGE_WITH_INCLUDES'
|
|
218
|
+
);
|
|
219
|
+
} else {
|
|
220
|
+
// Use the standard template for full content
|
|
221
|
+
templatePath = getTemplatePath(
|
|
222
|
+
path.join(__dirname, 'templates', 'property-page.hbs'),
|
|
223
|
+
'TEMPLATE_PROPERTY_PAGE'
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const template = handlebars.compile(fs.readFileSync(templatePath, 'utf8'));
|
|
228
|
+
|
|
229
|
+
if (useIncludes) {
|
|
230
|
+
// For include-based pages, we need minimal data - just page metadata and filename for include
|
|
231
|
+
const data = {
|
|
232
|
+
...config,
|
|
233
|
+
filename: config.filename.replace('.adoc', '') // Remove .adoc extension for include
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const output = template(data);
|
|
237
|
+
const outputPath = path.join(outputDir, config.filename);
|
|
238
|
+
|
|
239
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
240
|
+
fs.writeFileSync(outputPath, output, 'utf8');
|
|
241
|
+
|
|
242
|
+
console.log(`✅ Generated include-based page ${outputPath}`);
|
|
243
|
+
|
|
244
|
+
// Count properties for this type
|
|
245
|
+
const typeCount = Object.values(properties).filter(prop => {
|
|
246
|
+
return config.groups.some(group => group.filter(prop));
|
|
247
|
+
}).length;
|
|
248
|
+
|
|
249
|
+
return typeCount;
|
|
250
|
+
} else {
|
|
251
|
+
// Filter and group properties according to configuration
|
|
252
|
+
const groups = config.groups.map(group => {
|
|
253
|
+
const filteredProperties = Object.values(properties)
|
|
254
|
+
.filter(prop => group.filter(prop))
|
|
255
|
+
.sort((a, b) => String(a.name || '').localeCompare(String(b.name || '')));
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
title: group.title,
|
|
259
|
+
intro: group.intro,
|
|
260
|
+
properties: filteredProperties,
|
|
261
|
+
template: group.template || 'property' // Default to 'property' template
|
|
262
|
+
};
|
|
263
|
+
}).filter(group => group.properties.length > 0);
|
|
264
|
+
|
|
265
|
+
const data = {
|
|
266
|
+
...config,
|
|
267
|
+
groups
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
const output = template(data);
|
|
271
|
+
const outputPath = path.join(outputDir, config.filename);
|
|
272
|
+
|
|
273
|
+
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
274
|
+
fs.writeFileSync(outputPath, output, 'utf8');
|
|
275
|
+
|
|
276
|
+
console.log(`✅ Generated full content page ${outputPath}`);
|
|
277
|
+
return groups.reduce((total, group) => total + group.properties.length, 0);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Generate consolidated AsciiDoc partials for properties grouped by type.
|
|
283
|
+
*
|
|
284
|
+
* Creates separate .adoc files for each property type (cluster-properties.adoc,
|
|
285
|
+
* topic-properties.adoc, object-storage-properties.adoc, broker-properties.adoc)
|
|
286
|
+
* containing all properties of that type using the appropriate templates.
|
|
287
|
+
*
|
|
288
|
+
* @param {Object} properties - Map of properties (property name → property object).
|
|
289
|
+
* @param {string} partialsDir - Directory where consolidated property files will be written.
|
|
290
|
+
* @param {boolean} [hasCloudSupport=false] - If true, use cloud-aware templates.
|
|
291
|
+
* @returns {number} The total number of properties included in the consolidated partials.
|
|
292
|
+
*/
|
|
293
|
+
function generatePropertyPartials(properties, partialsDir, hasCloudSupport = false) {
|
|
294
|
+
console.log(`📝 Generating consolidated property partials in ${partialsDir}…`);
|
|
295
|
+
|
|
296
|
+
// Use the appropriate template based on cloud support
|
|
297
|
+
const templateName = hasCloudSupport ? 'property-cloud' : 'property';
|
|
210
298
|
const templatePath = getTemplatePath(
|
|
211
|
-
path.join(__dirname, 'templates',
|
|
212
|
-
'
|
|
299
|
+
path.join(__dirname, 'templates', `${templateName}.hbs`),
|
|
300
|
+
'TEMPLATE_PROPERTY'
|
|
213
301
|
);
|
|
214
302
|
const template = handlebars.compile(fs.readFileSync(templatePath, 'utf8'));
|
|
215
303
|
|
|
216
|
-
//
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
title: group.title,
|
|
224
|
-
intro: group.intro,
|
|
225
|
-
properties: filteredProperties,
|
|
226
|
-
template: group.template || 'property' // Default to 'property' template
|
|
227
|
-
};
|
|
228
|
-
}).filter(group => group.properties.length > 0);
|
|
304
|
+
// Use the topic property template for topic properties
|
|
305
|
+
const topicTemplateName = hasCloudSupport ? 'topic-property-cloud' : 'topic-property';
|
|
306
|
+
const topicTemplatePath = getTemplatePath(
|
|
307
|
+
path.join(__dirname, 'templates', `${topicTemplateName}.hbs`),
|
|
308
|
+
'TEMPLATE_TOPIC_PROPERTY'
|
|
309
|
+
);
|
|
310
|
+
const topicTemplate = handlebars.compile(fs.readFileSync(topicTemplatePath, 'utf8'));
|
|
229
311
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
312
|
+
// Create the main partials directory
|
|
313
|
+
const propertiesPartialsDir = path.join(partialsDir, 'properties');
|
|
314
|
+
fs.mkdirSync(propertiesPartialsDir, { recursive: true });
|
|
315
|
+
|
|
316
|
+
// Group properties by type
|
|
317
|
+
const propertyGroups = {
|
|
318
|
+
cluster: [],
|
|
319
|
+
topic: [],
|
|
320
|
+
broker: [],
|
|
321
|
+
'object-storage': []
|
|
233
322
|
};
|
|
234
323
|
|
|
235
|
-
|
|
236
|
-
|
|
324
|
+
// Categorize properties
|
|
325
|
+
Object.values(properties).forEach(prop => {
|
|
326
|
+
if (!prop.name || !prop.config_scope) return; // Skip properties without names or scope
|
|
327
|
+
|
|
328
|
+
if (prop.config_scope === 'topic') {
|
|
329
|
+
propertyGroups.topic.push(prop);
|
|
330
|
+
} else if (prop.config_scope === 'broker') {
|
|
331
|
+
propertyGroups.broker.push(prop);
|
|
332
|
+
} else if (prop.config_scope === 'cluster') {
|
|
333
|
+
// Check if it's an object storage property
|
|
334
|
+
if (isObjectStorageProperty(prop)) {
|
|
335
|
+
propertyGroups['object-storage'].push(prop);
|
|
336
|
+
} else {
|
|
337
|
+
propertyGroups.cluster.push(prop);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
let totalCount = 0;
|
|
237
343
|
|
|
238
|
-
|
|
239
|
-
|
|
344
|
+
// Generate consolidated partials for each property type
|
|
345
|
+
Object.entries(propertyGroups).forEach(([type, props]) => {
|
|
346
|
+
if (props.length === 0) return;
|
|
347
|
+
|
|
348
|
+
// Sort properties by name
|
|
349
|
+
props.sort((a, b) => String(a.name || '').localeCompare(String(b.name || '')));
|
|
350
|
+
|
|
351
|
+
// Choose the appropriate template based on property type
|
|
352
|
+
const selectedTemplate = type === 'topic' ? topicTemplate : template;
|
|
353
|
+
|
|
354
|
+
// Generate content for all properties of this type
|
|
355
|
+
const content = props.map(prop => selectedTemplate(prop)).join('\n');
|
|
356
|
+
|
|
357
|
+
// Write the consolidated file
|
|
358
|
+
const filename = `${type}-properties.adoc`;
|
|
359
|
+
const outputPath = path.join(propertiesPartialsDir, filename);
|
|
360
|
+
fs.writeFileSync(outputPath, content, 'utf8');
|
|
361
|
+
|
|
362
|
+
console.log(`✅ Generated ${outputPath} with ${props.length} properties`);
|
|
363
|
+
totalCount += props.length;
|
|
364
|
+
});
|
|
240
365
|
|
|
241
|
-
console.log(`✅ Generated ${
|
|
242
|
-
return
|
|
366
|
+
console.log(`✅ Generated consolidated property partials in ${partialsDir} (${totalCount} total properties)`);
|
|
367
|
+
return totalCount;
|
|
243
368
|
}
|
|
244
369
|
|
|
245
370
|
/**
|
|
@@ -279,8 +404,19 @@ function generateDeprecatedDocs(properties, outputDir) {
|
|
|
279
404
|
};
|
|
280
405
|
|
|
281
406
|
const output = template(data);
|
|
282
|
-
|
|
283
|
-
|
|
407
|
+
|
|
408
|
+
// Determine the correct path for deprecated properties
|
|
409
|
+
let outputPath;
|
|
410
|
+
if (process.env.OUTPUT_PARTIALS_DIR) {
|
|
411
|
+
// Use the explicitly set partials directory
|
|
412
|
+
outputPath = path.join(process.env.OUTPUT_PARTIALS_DIR, 'deprecated', 'deprecated-properties.adoc');
|
|
413
|
+
} else if (outputDir.includes('pages/properties')) {
|
|
414
|
+
// Fallback: Navigate back from pages/properties to reference, then into partials/deprecated
|
|
415
|
+
outputPath = path.join(path.dirname(path.dirname(outputDir)), 'partials', 'deprecated', 'deprecated-properties.adoc');
|
|
416
|
+
} else {
|
|
417
|
+
// Fallback: Direct path when outputDir is the base directory
|
|
418
|
+
outputPath = path.join(outputDir, 'partials', 'deprecated', 'deprecated-properties.adoc');
|
|
419
|
+
}
|
|
284
420
|
|
|
285
421
|
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
286
422
|
fs.writeFileSync(outputPath, output, 'utf8');
|
|
@@ -341,26 +477,68 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
341
477
|
let totalObjectStorageProperties = 0;
|
|
342
478
|
let totalTopicProperties = 0;
|
|
343
479
|
|
|
344
|
-
// Generate
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
480
|
+
// Generate complete property pages only if requested
|
|
481
|
+
if (process.env.GENERATE_PAGES === '1') {
|
|
482
|
+
console.log(`📄 Generating complete property pages...`);
|
|
483
|
+
|
|
484
|
+
// Generate each type of documentation
|
|
485
|
+
for (const [type, config] of Object.entries(PROPERTY_CONFIG)) {
|
|
486
|
+
const count = generatePropertyDocs(properties, config, outputDir);
|
|
487
|
+
totalProperties += count;
|
|
488
|
+
|
|
489
|
+
if (type === 'broker') totalBrokerProperties = count;
|
|
490
|
+
else if (type === 'cluster') totalClusterProperties = count;
|
|
491
|
+
else if (type === 'object-storage') totalObjectStorageProperties = count;
|
|
492
|
+
else if (type === 'topic') totalTopicProperties = count;
|
|
493
|
+
}
|
|
494
|
+
} else {
|
|
495
|
+
console.log(`📄 Skipping complete property pages (use --generate-pages to enable)`);
|
|
348
496
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
497
|
+
// Still count properties for summary
|
|
498
|
+
Object.values(properties).forEach(prop => {
|
|
499
|
+
if (prop.config_scope === 'broker' && !prop.is_deprecated) totalBrokerProperties++;
|
|
500
|
+
else if (prop.config_scope === 'cluster' && !prop.is_deprecated) {
|
|
501
|
+
if (prop.name && (
|
|
502
|
+
prop.name.includes('cloud_storage') ||
|
|
503
|
+
prop.name.includes('s3_') ||
|
|
504
|
+
prop.name.includes('azure_') ||
|
|
505
|
+
prop.name.includes('gcs_') ||
|
|
506
|
+
prop.name.includes('archival_') ||
|
|
507
|
+
prop.name.includes('remote_') ||
|
|
508
|
+
prop.name.includes('tiered_')
|
|
509
|
+
)) {
|
|
510
|
+
totalObjectStorageProperties++;
|
|
511
|
+
} else {
|
|
512
|
+
totalClusterProperties++;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else if (prop.config_scope === 'topic' && !prop.is_deprecated) totalTopicProperties++;
|
|
516
|
+
});
|
|
517
|
+
totalProperties = totalBrokerProperties + totalClusterProperties + totalObjectStorageProperties + totalTopicProperties;
|
|
353
518
|
}
|
|
354
519
|
|
|
355
|
-
// Generate
|
|
356
|
-
|
|
520
|
+
// Generate individual property partials if requested
|
|
521
|
+
let partialsCount = 0;
|
|
522
|
+
let deprecatedCount = 0;
|
|
523
|
+
if (process.env.GENERATE_PARTIALS === '1' && process.env.OUTPUT_PARTIALS_DIR) {
|
|
524
|
+
// Generate deprecated properties documentation
|
|
525
|
+
deprecatedCount = generateDeprecatedDocs(properties, outputDir);
|
|
526
|
+
|
|
527
|
+
partialsCount = generatePropertyPartials(properties, process.env.OUTPUT_PARTIALS_DIR, hasCloudSupport);
|
|
528
|
+
} else {
|
|
529
|
+
console.log(`📄 Skipping property partials (use --generate-partials to enable)`);
|
|
530
|
+
console.log(`📄 Skipping deprecated properties documentation (use --generate-partials to enable)`);
|
|
531
|
+
}
|
|
357
532
|
|
|
358
|
-
// Generate
|
|
359
|
-
const
|
|
360
|
-
fs.writeFileSync(path.join(outputDir, 'all_properties.txt'), allPropertiesContent, 'utf8');
|
|
533
|
+
// Generate error reports and add to input JSON output
|
|
534
|
+
const errorReport = generateErrorReports(properties, outputDir);
|
|
361
535
|
|
|
362
|
-
//
|
|
363
|
-
|
|
536
|
+
// Add error arrays directly to the input file so they're included when copied
|
|
537
|
+
const inputData = JSON.parse(fs.readFileSync(inputFile, 'utf8'));
|
|
538
|
+
inputData.empty_descriptions = errorReport.empty_descriptions;
|
|
539
|
+
inputData.deprecated_properties = errorReport.deprecated_properties;
|
|
540
|
+
fs.writeFileSync(inputFile, JSON.stringify(inputData, null, 2), 'utf8');
|
|
541
|
+
console.log(`📝 Added error arrays to ${inputFile}`);
|
|
364
542
|
|
|
365
543
|
console.log(`📊 Generation Summary:`);
|
|
366
544
|
console.log(` Total properties read: ${Object.keys(properties).length}`);
|
|
@@ -369,6 +547,9 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
369
547
|
console.log(` Total Object Storage properties: ${totalObjectStorageProperties}`);
|
|
370
548
|
console.log(` Total Topic properties: ${totalTopicProperties}`);
|
|
371
549
|
console.log(` Total Deprecated properties: ${deprecatedCount}`);
|
|
550
|
+
if (partialsCount > 0) {
|
|
551
|
+
console.log(` Total Property partials: ${partialsCount}`);
|
|
552
|
+
}
|
|
372
553
|
|
|
373
554
|
return {
|
|
374
555
|
totalProperties: Object.keys(properties).length,
|
|
@@ -376,7 +557,8 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
376
557
|
clusterProperties: totalClusterProperties,
|
|
377
558
|
objectStorageProperties: totalObjectStorageProperties,
|
|
378
559
|
topicProperties: totalTopicProperties,
|
|
379
|
-
deprecatedProperties: deprecatedCount
|
|
560
|
+
deprecatedProperties: deprecatedCount,
|
|
561
|
+
propertyPartials: partialsCount
|
|
380
562
|
};
|
|
381
563
|
}
|
|
382
564
|
|
|
@@ -384,9 +566,6 @@ function generateAllDocs(inputFile, outputDir) {
|
|
|
384
566
|
* Generate error reports for properties with missing or invalid data
|
|
385
567
|
*/
|
|
386
568
|
function generateErrorReports(properties, outputDir) {
|
|
387
|
-
const errorDir = path.join(outputDir, 'error');
|
|
388
|
-
fs.mkdirSync(errorDir, { recursive: true });
|
|
389
|
-
|
|
390
569
|
const emptyDescriptions = [];
|
|
391
570
|
const deprecatedProperties = [];
|
|
392
571
|
|
|
@@ -399,34 +578,25 @@ function generateErrorReports(properties, outputDir) {
|
|
|
399
578
|
}
|
|
400
579
|
});
|
|
401
580
|
|
|
402
|
-
//
|
|
581
|
+
// Add these arrays to the properties JSON file
|
|
403
582
|
const totalProperties = Object.keys(properties).length;
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
emptyDescriptions.join('\n'),
|
|
409
|
-
'utf8'
|
|
410
|
-
);
|
|
411
|
-
const percentage = totalProperties > 0 ? ((emptyDescriptions.length / totalProperties) * 100).toFixed(2) : '0.00';
|
|
412
|
-
console.log(`You have ${emptyDescriptions.length} properties with empty description. Percentage of errors: ${percentage}%. Data written in 'empty_description.txt'.`);
|
|
413
|
-
}
|
|
583
|
+
const percentageEmpty = totalProperties > 0 ? ((emptyDescriptions.length / totalProperties) * 100).toFixed(2) : '0.00';
|
|
584
|
+
const percentageDeprecated = totalProperties > 0 ? ((deprecatedProperties.length / totalProperties) * 100).toFixed(2) : '0.00';
|
|
585
|
+
console.log(`You have ${emptyDescriptions.length} properties with empty description. Percentage of errors: ${percentageEmpty}%.`);
|
|
586
|
+
console.log(`You have ${deprecatedProperties.length} deprecated properties. Percentage of errors: ${percentageDeprecated}%.`);
|
|
414
587
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
);
|
|
421
|
-
const percentage = totalProperties > 0 ? ((deprecatedProperties.length / totalProperties) * 100).toFixed(2) : '0.00';
|
|
422
|
-
console.log(`You have ${deprecatedProperties.length} deprecated properties. Percentage of errors: ${percentage}%. Data written in 'deprecated_properties.txt'.`);
|
|
423
|
-
}
|
|
588
|
+
// Return the arrays sorted for deterministic output
|
|
589
|
+
return {
|
|
590
|
+
empty_descriptions: emptyDescriptions.sort(),
|
|
591
|
+
deprecated_properties: deprecatedProperties.sort()
|
|
592
|
+
};
|
|
424
593
|
}
|
|
425
594
|
|
|
426
595
|
module.exports = {
|
|
427
596
|
generateAllDocs,
|
|
428
597
|
generatePropertyDocs,
|
|
429
598
|
generateDeprecatedDocs,
|
|
599
|
+
generatePropertyPartials,
|
|
430
600
|
PROPERTY_CONFIG
|
|
431
601
|
};
|
|
432
602
|
|
|
@@ -877,15 +877,18 @@ def add_config_scope(properties):
|
|
|
877
877
|
if prop.get("is_topic_property", False):
|
|
878
878
|
prop["config_scope"] = "topic"
|
|
879
879
|
else:
|
|
880
|
-
#
|
|
881
|
-
if prop.get("
|
|
882
|
-
# Keep the existing config_scope from override
|
|
880
|
+
# Skip config_scope assignment if it's already been set by an override
|
|
881
|
+
if prop.get("config_scope") is not None:
|
|
882
|
+
# Keep the existing config_scope from override or previous assignment
|
|
883
883
|
pass
|
|
884
884
|
else:
|
|
885
885
|
defined_in = prop.get("defined_in", "")
|
|
886
886
|
if defined_in == "src/v/config/configuration.cc":
|
|
887
887
|
prop["config_scope"] = "cluster"
|
|
888
|
-
elif defined_in
|
|
888
|
+
elif defined_in in ["src/v/config/node_config.cc",
|
|
889
|
+
"src/v/pandaproxy/rest/configuration.cc",
|
|
890
|
+
"src/v/kafka/client/configuration.cc",
|
|
891
|
+
"src/v/pandaproxy/schema_registry/configuration.cc"]:
|
|
889
892
|
prop["config_scope"] = "broker"
|
|
890
893
|
else:
|
|
891
894
|
prop["config_scope"] = None
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
{{#unless is_deprecated}}
|
|
1
2
|
{{#if cloud_supported}}
|
|
2
3
|
// tag::redpanda-cloud[]
|
|
3
4
|
{{/if}}
|
|
@@ -20,8 +21,9 @@ ifndef::env-cloud[]
|
|
|
20
21
|
endif::[]
|
|
21
22
|
{{/if}}
|
|
22
23
|
{{#if cloud_byoc_only}}
|
|
23
|
-
|
|
24
|
+
ifdef::env-cloud[]
|
|
24
25
|
NOTE: This property is available only in Redpanda Cloud BYOC deployments.
|
|
26
|
+
endif::[]
|
|
25
27
|
{{/if}}
|
|
26
28
|
{{#if units}}
|
|
27
29
|
|
|
@@ -71,9 +73,7 @@ ifndef::env-cloud[]
|
|
|
71
73
|
endif::[]
|
|
72
74
|
{{/if}}
|
|
73
75
|
|
|
74
|
-
// tag::self-managed-only[]
|
|
75
76
|
*Nullable:* {{#if nullable}}Yes{{else}}No{{/if}}
|
|
76
|
-
// end::self-managed-only[]
|
|
77
77
|
{{#if example}}
|
|
78
78
|
|
|
79
79
|
{{{renderPropertyExample this}}}
|
|
@@ -92,14 +92,9 @@ endif::[]
|
|
|
92
92
|
*Aliases:* {{join aliases ", "}}
|
|
93
93
|
// end::self-managed-only[]
|
|
94
94
|
{{/if}}
|
|
95
|
-
{{#if is_deprecated}}
|
|
96
95
|
|
|
97
|
-
[WARNING]
|
|
98
|
-
====
|
|
99
|
-
This property is deprecated.
|
|
100
|
-
====
|
|
101
|
-
{{/if}}
|
|
102
96
|
---
|
|
103
97
|
{{#if cloud_supported}}
|
|
104
98
|
// end::redpanda-cloud[]
|
|
105
99
|
{{/if}}
|
|
100
|
+
{{/unless}}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
= {{pageTitle}}
|
|
2
|
+
{{#if pageAliases}}
|
|
3
|
+
:page-aliases: {{join pageAliases ", "}}
|
|
4
|
+
{{/if}}
|
|
5
|
+
:description: {{description}}
|
|
6
|
+
|
|
7
|
+
{{{intro}}}
|
|
8
|
+
|
|
9
|
+
{{#if sectionTitle}}
|
|
10
|
+
== {{sectionTitle}}
|
|
11
|
+
{{/if}}
|
|
12
|
+
|
|
13
|
+
{{#if sectionIntro}}
|
|
14
|
+
{{{sectionIntro}}}
|
|
15
|
+
{{/if}}
|
|
16
|
+
|
|
17
|
+
include::reference:partial$properties/{{filename}}.adoc[]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
{{#unless is_deprecated}}
|
|
1
2
|
=== {{name}}
|
|
2
3
|
|
|
3
4
|
{{#if version}}
|
|
@@ -58,28 +59,22 @@ endif::[]
|
|
|
58
59
|
|
|
59
60
|
{{/if}}
|
|
60
61
|
*Nullable:* {{#if nullable}}Yes{{else}}No{{/if}}
|
|
61
|
-
|
|
62
62
|
{{#if example}}
|
|
63
|
+
|
|
63
64
|
{{{renderPropertyExample this}}}
|
|
64
65
|
{{/if}}
|
|
65
|
-
|
|
66
66
|
{{#if related_topics}}
|
|
67
|
+
|
|
67
68
|
*Related topics:*
|
|
68
69
|
|
|
69
70
|
{{#each related_topics}}
|
|
70
71
|
* {{{this}}}
|
|
71
72
|
{{/each}}
|
|
72
73
|
{{/if}}
|
|
73
|
-
|
|
74
74
|
{{#if aliases}}
|
|
75
|
-
*Aliases:* {{join aliases ", "}}
|
|
76
|
-
|
|
77
|
-
{{/if}}
|
|
78
|
-
{{#if is_deprecated}}
|
|
79
|
-
[WARNING]
|
|
80
|
-
====
|
|
81
|
-
This property is deprecated.
|
|
82
|
-
====
|
|
83
75
|
|
|
76
|
+
*Aliases:* {{join aliases ", "}}
|
|
84
77
|
{{/if}}
|
|
85
78
|
---
|
|
79
|
+
{{/unless}}
|
|
80
|
+
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
{{#unless is_deprecated}}
|
|
1
2
|
{{#if cloud_supported}}
|
|
2
3
|
// tag::redpanda-cloud[]
|
|
3
4
|
{{/if}}
|
|
@@ -84,14 +85,10 @@ endif::[]
|
|
|
84
85
|
*Aliases:* {{join aliases ", "}}
|
|
85
86
|
// end::self-managed-only[]
|
|
86
87
|
{{/if}}
|
|
87
|
-
{{#if is_deprecated}}
|
|
88
88
|
|
|
89
|
-
[WARNING]
|
|
90
|
-
====
|
|
91
|
-
This property is deprecated.
|
|
92
|
-
====
|
|
93
|
-
{{/if}}
|
|
94
89
|
---
|
|
95
90
|
{{#if cloud_supported}}
|
|
96
91
|
// end::redpanda-cloud[]
|
|
97
92
|
{{/if}}
|
|
93
|
+
|
|
94
|
+
{{/unless}}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
{{#unless is_deprecated}}
|
|
1
2
|
=== {{name}}
|
|
2
3
|
{{#if version}}
|
|
3
4
|
|
|
@@ -63,11 +64,6 @@ endif::[]
|
|
|
63
64
|
|
|
64
65
|
*Aliases:* {{join aliases ", "}}
|
|
65
66
|
{{/if}}
|
|
66
|
-
{{#if is_deprecated}}
|
|
67
67
|
|
|
68
|
-
[WARNING]
|
|
69
|
-
====
|
|
70
|
-
This property is deprecated.
|
|
71
|
-
====
|
|
72
|
-
{{/if}}
|
|
73
68
|
---
|
|
69
|
+
{{/unless}}
|