@redpanda-data/docs-extensions-and-macros 4.11.1 → 4.12.0
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 +4 -2
- package/package.json +3 -1
- package/tools/property-extractor/COMPUTED_CONSTANTS.md +173 -0
- package/tools/property-extractor/Makefile +12 -1
- package/tools/property-extractor/README.adoc +828 -97
- package/tools/property-extractor/compare-properties.js +38 -13
- package/tools/property-extractor/constant_resolver.py +610 -0
- package/tools/property-extractor/file_pair.py +42 -0
- package/tools/property-extractor/generate-handlebars-docs.js +41 -8
- package/tools/property-extractor/helpers/gt.js +9 -0
- package/tools/property-extractor/helpers/includes.js +17 -0
- package/tools/property-extractor/helpers/index.js +3 -0
- package/tools/property-extractor/helpers/isEnterpriseEnum.js +24 -0
- package/tools/property-extractor/helpers/renderPropertyExample.js +6 -5
- package/tools/property-extractor/overrides.json +248 -0
- package/tools/property-extractor/parser.py +254 -32
- package/tools/property-extractor/property_bag.py +40 -0
- package/tools/property-extractor/property_extractor.py +1417 -430
- package/tools/property-extractor/requirements.txt +1 -0
- package/tools/property-extractor/templates/property-backup.hbs +161 -0
- package/tools/property-extractor/templates/property.hbs +104 -49
- package/tools/property-extractor/templates/topic-property-backup.hbs +148 -0
- package/tools/property-extractor/templates/topic-property.hbs +72 -34
- package/tools/property-extractor/tests/test_known_values.py +617 -0
- package/tools/property-extractor/tests/transformers_test.py +81 -6
- package/tools/property-extractor/topic_property_extractor.py +23 -10
- package/tools/property-extractor/transformers.py +2191 -369
- package/tools/property-extractor/type_definition_extractor.py +669 -0
- package/tools/property-extractor/definitions.json +0 -245
package/bin/doc-tools.js
CHANGED
|
@@ -1148,8 +1148,10 @@ automation
|
|
|
1148
1148
|
|
|
1149
1149
|
// If we used Antora's latest-redpanda-tag for diff, update it to the new tag
|
|
1150
1150
|
if (!options.diff && !tagsAreSame) {
|
|
1151
|
-
setAntoraValue('asciidoc.attributes.latest-redpanda-tag', newTag);
|
|
1152
|
-
|
|
1151
|
+
const success = setAntoraValue('asciidoc.attributes.latest-redpanda-tag', newTag);
|
|
1152
|
+
if (success) {
|
|
1153
|
+
console.log(`✅ Updated Antora latest-redpanda-tag to: ${newTag}`);
|
|
1154
|
+
}
|
|
1153
1155
|
}
|
|
1154
1156
|
|
|
1155
1157
|
process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redpanda-data/docs-extensions-and-macros",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Antora extensions and macros developed for Redpanda documentation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antora",
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
"build": "antora --to-dir docs --fetch local-antora-playbook.yml",
|
|
23
23
|
"serve": "wds --node-resolve --open preview/test/ --watch --root-dir docs",
|
|
24
24
|
"test": "jest",
|
|
25
|
+
"test:python": "./__tests__/tools/property-extractor/setup-and-test.sh",
|
|
26
|
+
"test:all": "npm run test && npm run test:python",
|
|
25
27
|
"bundle:admin": "doc-tools generate bundle-openapi --surface admin",
|
|
26
28
|
"bundle:connect": "doc-tools generate bundle-openapi --surface connect",
|
|
27
29
|
"bundle:both": "doc-tools generate bundle-openapi --surface both"
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Computed C++ Constants Resolution
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Some C++ constants in Redpanda are defined with complex compile-time expressions that cannot be easily parsed by the property-extractor. These constants need to be pre-computed and mapped to their actual values.
|
|
6
|
+
|
|
7
|
+
## Problem Statement
|
|
8
|
+
|
|
9
|
+
Properties like `log_message_timestamp_before_max_ms` use constants like `max_serializable_ms` as their default values. These constants are defined with complex expressions:
|
|
10
|
+
|
|
11
|
+
```cpp
|
|
12
|
+
// From src/v/serde/rw/chrono.h:20
|
|
13
|
+
inline constexpr auto max_serializable_ms
|
|
14
|
+
= std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
15
|
+
std::chrono::nanoseconds::max());
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Without resolution, the extracted schema would show:
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"log_message_timestamp_before_max_ms": {
|
|
22
|
+
"default": "max_serializable_ms" // ❌ String instead of numeric value
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Solution
|
|
28
|
+
|
|
29
|
+
### 1. COMPUTED_CONSTANTS Dictionary
|
|
30
|
+
|
|
31
|
+
Added a dictionary in `transformers.py` that maps constant names to their computed values:
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
COMPUTED_CONSTANTS = {
|
|
35
|
+
# From src/v/serde/rw/chrono.h:20
|
|
36
|
+
# inline constexpr auto max_serializable_ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::nanoseconds::max());
|
|
37
|
+
# Calculation: std::numeric_limits<int64_t>::max() / 1,000,000 = 9223372036854775807 / 1000000 = 9223372036854 ms
|
|
38
|
+
"max_serializable_ms": 9223372036854, # ~292 years in milliseconds
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 2. FriendlyDefaultTransformer Enhancement
|
|
43
|
+
|
|
44
|
+
Updated the `FriendlyDefaultTransformer` to check the `COMPUTED_CONSTANTS` dictionary before falling back to string normalization:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
# ------------------------------------------------------------------
|
|
48
|
+
# Computed C++ constants (max_serializable_ms, etc.)
|
|
49
|
+
# ------------------------------------------------------------------
|
|
50
|
+
if d in COMPUTED_CONSTANTS:
|
|
51
|
+
property["default"] = COMPUTED_CONSTANTS[d]
|
|
52
|
+
return property
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Test Coverage
|
|
56
|
+
|
|
57
|
+
Added comprehensive test in `tests/test_known_values.py`:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
def test_max_serializable_ms_constant_resolution(self):
|
|
61
|
+
"""Test that max_serializable_ms constant is resolved to actual numeric value"""
|
|
62
|
+
info = create_complete_property_info(
|
|
63
|
+
name="log_message_timestamp_before_max_ms",
|
|
64
|
+
description="Maximum timestamp difference for record validation",
|
|
65
|
+
declaration="property<std::chrono::milliseconds> log_message_timestamp_before_max_ms;",
|
|
66
|
+
metadata="meta{.needs_restart = needs_restart::no, .visibility = visibility::user}",
|
|
67
|
+
default_value="max_serializable_ms"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
property = apply_transformer_pipeline(info)
|
|
71
|
+
|
|
72
|
+
self.assertEqual(property["name"], "log_message_timestamp_before_max_ms")
|
|
73
|
+
self.assertEqual(property["type"], "integer")
|
|
74
|
+
# max_serializable_ms = std::numeric_limits<int64_t>::max() / 1,000,000 = 9223372036854 ms
|
|
75
|
+
self.assertEqual(property["default"], 9223372036854)
|
|
76
|
+
self.assertFalse(property["needs_restart"])
|
|
77
|
+
self.assertEqual(property["visibility"], "user")
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Calculation Details
|
|
81
|
+
|
|
82
|
+
### max_serializable_ms
|
|
83
|
+
|
|
84
|
+
**Definition Location:** `src/v/serde/rw/chrono.h:20`
|
|
85
|
+
|
|
86
|
+
**C++ Expression:**
|
|
87
|
+
```cpp
|
|
88
|
+
std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
89
|
+
std::chrono::nanoseconds::max()
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Calculation:**
|
|
94
|
+
1. `std::chrono::nanoseconds::max()` = `std::numeric_limits<int64_t>::max()` = `9223372036854775807` nanoseconds
|
|
95
|
+
2. Convert to milliseconds (truncating division): `9223372036854775807 / 1000000` = `9223372036854` milliseconds
|
|
96
|
+
3. This is approximately **292.47 years**
|
|
97
|
+
|
|
98
|
+
**Verification:**
|
|
99
|
+
```python
|
|
100
|
+
import sys
|
|
101
|
+
|
|
102
|
+
# std::chrono::nanoseconds uses int64_t for rep
|
|
103
|
+
max_int64 = 9223372036854775807
|
|
104
|
+
|
|
105
|
+
# Convert nanoseconds to milliseconds (duration_cast truncates)
|
|
106
|
+
max_ms = max_int64 // 1000000
|
|
107
|
+
|
|
108
|
+
print(f'max_serializable_ms = {max_ms} ms')
|
|
109
|
+
print(f'Which is approximately {max_ms / (1000 * 60 * 60 * 24 * 365):.2f} years')
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Output:
|
|
113
|
+
```
|
|
114
|
+
max_serializable_ms = 9223372036854 ms
|
|
115
|
+
Which is approximately 292.47 years
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Result
|
|
119
|
+
|
|
120
|
+
After the fix, the extracted schema correctly shows:
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"log_message_timestamp_before_max_ms": {
|
|
124
|
+
"default": 9223372036854, // ✅ Correct numeric value
|
|
125
|
+
"type": "integer"
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Adding New Computed Constants
|
|
131
|
+
|
|
132
|
+
To add support for new computed constants:
|
|
133
|
+
|
|
134
|
+
1. **Find the definition** in the Redpanda source code
|
|
135
|
+
2. **Compute the value** - either manually or with a Python/C++ test
|
|
136
|
+
3. **Add to COMPUTED_CONSTANTS** dictionary in `transformers.py`:
|
|
137
|
+
```python
|
|
138
|
+
COMPUTED_CONSTANTS = {
|
|
139
|
+
"existing_constant": 12345,
|
|
140
|
+
"new_constant_name": computed_value, # Add comment with source location
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
4. **Add a test** in `tests/test_known_values.py` to verify resolution
|
|
144
|
+
5. **Document the calculation** with comments including:
|
|
145
|
+
- Source file location
|
|
146
|
+
- C++ expression
|
|
147
|
+
- Calculation steps
|
|
148
|
+
- Human-readable interpretation
|
|
149
|
+
|
|
150
|
+
## Test Coverage
|
|
151
|
+
|
|
152
|
+
All 53 tests pass, including the new test for `max_serializable_ms` resolution:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
cd tools/property-extractor
|
|
156
|
+
python -m pytest tests/ -v --tb=short
|
|
157
|
+
# ================================================= 53 passed =================================================
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Benefits
|
|
161
|
+
|
|
162
|
+
✅ **Accurate defaults** - Properties show actual numeric values instead of symbolic names
|
|
163
|
+
✅ **Type safety** - Numeric properties have numeric defaults, not strings
|
|
164
|
+
✅ **Documentation quality** - Users see real values they can use
|
|
165
|
+
✅ **Maintainability** - Centralized mapping makes updates easy
|
|
166
|
+
✅ **Test coverage** - Ensures constants resolve correctly
|
|
167
|
+
|
|
168
|
+
## Related Files
|
|
169
|
+
|
|
170
|
+
- `tools/property-extractor/transformers.py` - COMPUTED_CONSTANTS dictionary and resolution logic
|
|
171
|
+
- `tools/property-extractor/tests/test_known_values.py` - Test for constant resolution
|
|
172
|
+
- `src/v/serde/rw/chrono.h` - Source definition of max_serializable_ms
|
|
173
|
+
- `tools/property-extractor/CI_INTEGRATION.md` - Updated test count documentation
|
|
@@ -119,7 +119,18 @@ generate-docs: node-deps
|
|
|
119
119
|
fi
|
|
120
120
|
@echo "📄 Copying properties JSON files to $(OUTPUT_JSON_DIR)…"
|
|
121
121
|
@if [ -f "$(TOOL_ROOT)/gen/$(TAG)-properties.json" ]; then \
|
|
122
|
-
|
|
122
|
+
echo " Source: $(TOOL_ROOT)/gen/$(TAG)-properties.json"; \
|
|
123
|
+
echo " Target: $(OUTPUT_JSON_DIR)/$(TAG)-properties.json"; \
|
|
124
|
+
cp "$(TOOL_ROOT)/gen/$(TAG)-properties.json" "$(OUTPUT_JSON_DIR)/" && \
|
|
125
|
+
echo " ✅ Successfully copied $(TAG)-properties.json" || \
|
|
126
|
+
{ echo " ❌ Failed to copy $(TAG)-properties.json"; exit 1; }; \
|
|
127
|
+
if [ -f "$(OUTPUT_JSON_DIR)/$(TAG)-properties.json" ]; then \
|
|
128
|
+
echo " 📊 Verification: Target file exists and has $$(wc -c < "$(OUTPUT_JSON_DIR)/$(TAG)-properties.json") bytes"; \
|
|
129
|
+
else \
|
|
130
|
+
echo " ❌ Verification failed: Target file does not exist"; exit 1; \
|
|
131
|
+
fi; \
|
|
132
|
+
else \
|
|
133
|
+
echo " ⚠️ Source file $(TOOL_ROOT)/gen/$(TAG)-properties.json not found, skipping copy"; \
|
|
123
134
|
fi
|
|
124
135
|
@echo "✅ Docs generated at $(OUTPUT_AUTOGENERATED_DIR)"
|
|
125
136
|
|