Skip to content

Commit 90ff0c9

Browse files
authored
Add bibliography capabilities (rustfoundation#334)
* feat: add bibliography with surrounding automation * fix: made it so that guideline id is included to disambiguate links * feat: add ability to navigate back from bibliography to citation * fix: make ruff pass * fix: prevent back arrows from erroneous behavior -- only go back to citation * fix: make ruff pass
1 parent dfdad06 commit 90ff0c9

File tree

15 files changed

+1683
-8
lines changed

15 files changed

+1683
-8
lines changed

builder/build_cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def build_docs(
3030
debug: bool,
3131
offline: bool,
3232
spec_lock_consistency_check: bool,
33+
validate_urls: bool,
3334
) -> Path:
3435
"""
3536
Builds the Sphinx documentation with the specified options.
@@ -42,6 +43,7 @@ def build_docs(
4243
debug: Whether to enable debug mode.
4344
offline: Whether to build in offline mode.
4445
spec_lock_consistency_check: Whether to check spec lock consistency.
46+
validate_urls: Whether to validate bibliography URLs.
4547
4648
Returns:
4749
Path: The path to the generated documentation.
@@ -73,6 +75,8 @@ def build_docs(
7375
conf_opt_values.append("offline=1")
7476
if debug:
7577
conf_opt_values.append("debug=1")
78+
if validate_urls:
79+
conf_opt_values.append("bibliography_check_urls=1")
7680

7781
# Only add the --define argument if there are options to define
7882
if conf_opt_values:
@@ -162,6 +166,11 @@ def main(root):
162166
parser.add_argument(
163167
"--update-spec-lock-file", help="update spec.lock file", action="store_true"
164168
)
169+
parser.add_argument(
170+
"--validate-urls",
171+
help="validate bibliography URLs (enables URL checking, typically used in CI)",
172+
action="store_true",
173+
)
165174
group.add_argument(
166175
"-s",
167176
"--serve",
@@ -198,4 +207,5 @@ def main(root):
198207
args.debug,
199208
args.offline,
200209
not args.ignore_spec_lock_diff,
210+
args.validate_urls,
201211
)

docs/bibliography.md

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# Bibliography Feature for Safety-Critical Rust Coding Guidelines
2+
3+
This document describes the bibliography feature implementation for the Safety-Critical Rust Coding Guidelines project.
4+
5+
## Overview
6+
7+
The bibliography feature allows guideline authors to include references to external documentation, standards, and other resources that support their guidelines. Citations in the guideline text are clickable links that navigate to the corresponding bibliography entry.
8+
9+
## Features
10+
11+
### 1. In-Text Citations with `:cite:` Role
12+
13+
Contributors can reference citations within guideline text using the `:cite:` role:
14+
15+
```rst
16+
As documented in :cite:`gui_Abc123XyzQrs:RUST-REF-UNION`, union types have specific safety requirements.
17+
```
18+
19+
**Format:** `:cite:`{guideline_id}:{CITATION-KEY}``
20+
21+
- `guideline_id` is the parent guideline's ID (e.g., `gui_Abc123XyzQrs`)
22+
- `CITATION-KEY` is the citation key in UPPERCASE-WITH-HYPHENS format
23+
24+
The `:cite:` role renders as a clickable `[CITATION-KEY]` link that navigates to the bibliography entry.
25+
26+
### 2. Bibliography Entries with `:bibentry:` Role
27+
28+
Each guideline can include an optional bibliography section with entries defined using the `:bibentry:` role:
29+
30+
```rst
31+
.. guideline:: Union Field Validity
32+
:id: gui_Abc123XyzQrs
33+
...
34+
35+
As documented in :cite:`gui_Abc123XyzQrs:RUST-REF-UNION`, unions have requirements.
36+
37+
.. bibliography::
38+
:id: bib_Abc123XyzQrs
39+
:status: draft
40+
41+
.. list-table::
42+
:header-rows: 0
43+
:widths: auto
44+
:class: bibliography-table
45+
46+
* - :bibentry:`gui_Abc123XyzQrs:RUST-REF-UNION`
47+
- The Rust Reference. "Unions." https://doc.rust-lang.org/reference/items/unions.html
48+
* - :bibentry:`gui_Abc123XyzQrs:CERT-C-INT34`
49+
- SEI CERT C Coding Standard. "INT34-C." https://wiki.sei.cmu.edu/confluence/x/ItcxBQ
50+
```
51+
52+
**Format:** `:bibentry:`{guideline_id}:{CITATION-KEY}``
53+
54+
The `:bibentry:` role creates an anchor that the `:cite:` role links to, and renders as a bold `[CITATION-KEY]`.
55+
56+
### 3. Why Namespacing?
57+
58+
The guideline ID prefix (`gui_Abc123XyzQrs:`) is required to avoid conflicts when multiple guidelines use the same citation key (e.g., both guidelines might cite `RUST-REF-UNION`). The prefix ensures each citation anchor is unique across the entire documentation.
59+
60+
When using `generate_guideline_templates.py`, the guideline ID is automatically included in all `:cite:` and `:bibentry:` roles.
61+
62+
### 4. Citation Key Format
63+
64+
Citation keys must follow these rules:
65+
- **Format**: `UPPERCASE-WITH-HYPHENS`
66+
- Must start with an uppercase letter
67+
- Can contain uppercase letters, numbers, and hyphens
68+
- Must end with an uppercase letter or number
69+
- Maximum 50 characters
70+
71+
**Valid examples:**
72+
- `RUST-REF-UNION`
73+
- `CERT-C-INT34`
74+
- `ISO-26262-2018`
75+
- `MISRA-C-2012`
76+
77+
**Invalid examples:**
78+
- `lowercase` - must be uppercase
79+
- `ENDS-WITH-` - cannot end with hyphen
80+
- `-STARTS-HYPHEN` - cannot start with hyphen
81+
82+
### 5. URL Validation
83+
84+
The bibliography validator extension checks:
85+
- URL accessibility (HTTP status)
86+
- Duplicate URLs across guidelines
87+
- Citation key format compliance
88+
- Citation references match definitions
89+
90+
## Configuration
91+
92+
### conf.py Settings
93+
94+
```python
95+
# Enable URL validation (typically only in CI)
96+
bibliography_check_urls = False # Set via --validate-urls flag
97+
98+
# Timeout for URL checks in seconds
99+
bibliography_url_timeout = 10
100+
101+
# Whether broken URLs should fail the build
102+
bibliography_fail_on_broken = True
103+
104+
# Whether duplicate URLs should fail the build
105+
bibliography_fail_on_duplicates = True
106+
```
107+
108+
### Build Commands
109+
110+
```bash
111+
# Normal build (no URL validation)
112+
./make.py
113+
114+
# Build with URL validation (for CI)
115+
./make.py --validate-urls
116+
117+
# Debug build with URL validation
118+
./make.py --debug --validate-urls
119+
```
120+
121+
## GitHub Issue Template
122+
123+
The coding guideline issue template includes an optional bibliography field:
124+
125+
```yaml
126+
- type: textarea
127+
id: bibliography
128+
attributes:
129+
label: Bibliography
130+
description: |
131+
Optional list of references. Format:
132+
[CITATION-KEY] Author. "Title." URL
133+
```
134+
135+
**Example input:**
136+
```
137+
[RUST-REF-UNION] The Rust Reference. "Unions." https://doc.rust-lang.org/reference/items/unions.html
138+
[CERT-C-INT34] SEI CERT C Coding Standard. "INT34-C. Do not shift an expression by a negative number of bits." https://wiki.sei.cmu.edu/confluence/x/ItcxBQ
139+
```
140+
141+
The template generator automatically converts this to the proper `:cite:` and `:bibentry:` role format.
142+
143+
## CI Integration
144+
145+
### Pull Requests to Main
146+
- Bibliography URLs are validated on every PR to main
147+
- Broken or duplicate URLs will fail the build
148+
149+
### Nightly Builds
150+
- Full URL validation runs nightly
151+
- Creates GitHub issues automatically if validation fails
152+
153+
## File Structure
154+
155+
```
156+
exts/coding_guidelines/
157+
├── bibliography_validator.py # URL and citation validation
158+
├── citation_roles.py # :cite: and :bibentry: role implementations
159+
├── __init__.py # Extension setup (updated)
160+
└── write_guidelines_ids.py # JSON export (updated)
161+
162+
scripts/
163+
├── guideline_utils.py # Bibliography parsing utilities
164+
└── generate-rst-comment.py # Preview generation (updated)
165+
166+
.github/
167+
├── ISSUE_TEMPLATE/
168+
│ └── CODING-GUIDELINE.yml # Issue template with bibliography field
169+
└── workflows/
170+
├── build-guidelines.yml # Build workflow with URL validation
171+
└── nightly.yml # Nightly validation
172+
173+
src/
174+
├── conf.py # Sphinx config with bibliography settings
175+
└── _static/
176+
├── bibliography.css # Bibliography table styling
177+
└── citation.css # Citation link styling
178+
```
179+
180+
## JSON Export Format
181+
182+
The `guidelines-ids.json` now includes bibliography data. All IDs follow the same format: `{prefix}_{12_random_alphanumeric_chars}`:
183+
184+
```json
185+
{
186+
"documents": [
187+
{
188+
"guidelines": [
189+
{
190+
"id": "gui_7y0GAMmtMhch",
191+
"title": "Union Field Validity",
192+
"rationale": { "id": "rat_ADHABsmK9FXz", "checksum": "..." },
193+
"non_compliant_example": { "id": "non_compl_ex_RHvQj8BHlz9b", "checksum": "..." },
194+
"compliant_example": { "id": "compl_ex_dCquvqE1csI3", "checksum": "..." },
195+
"bibliography": { "id": "bib_Xn3pQr7sT2vW", "checksum": "..." }
196+
}
197+
]
198+
}
199+
]
200+
}
201+
```
202+
203+
## Error Messages
204+
205+
### Broken URL
206+
```
207+
WARNING: [bibliography_validator] Broken URL in src/gui_Foo.rst:
208+
URL: https://example.com/broken
209+
Guideline: gui_Foo
210+
Error: HTTP 404
211+
Action: Update or remove this reference
212+
```
213+
214+
### Duplicate URL
215+
```
216+
WARNING: [bibliography_validator] Duplicate URL detected:
217+
URL: https://doc.rust-lang.org/reference/items/unions.html
218+
Found in: gui_UnionFieldValidity, gui_UnionLayout
219+
Action: Consider if both guidelines need this reference
220+
```
221+
222+
### Invalid Citation Key
223+
```
224+
ERROR: Invalid citation key format: 'lowercase-key'.
225+
Expected: UPPERCASE-WITH-HYPHENS (e.g., RUST-REF-UNION, CERT-C-INT34)
226+
```
227+
228+
### Invalid Role Format
229+
```
230+
ERROR: Invalid :cite: format: "RUST-REF-UNION".
231+
Expected format: :cite:`gui_XxxYyyZzz:CITATION-KEY`
232+
```
233+
234+
## Migration
235+
236+
Existing guidelines without bibliographies will continue to work. The bibliography section is optional and will not cause build failures if missing.
237+
238+
### From Plain Text Format
239+
240+
If you have guidelines using the older plain text `[CITATION-KEY]` format, update them to use the role-based syntax:
241+
242+
**Before:**
243+
```rst
244+
As documented in [RUST-REF-UNION], ...
245+
246+
* - **[RUST-REF-UNION]**
247+
- The Rust Reference...
248+
```
249+
250+
**After:**
251+
```rst
252+
As documented in :cite:`gui_YourGuidelineId:RUST-REF-UNION`, ...
253+
254+
* - :bibentry:`gui_YourGuidelineId:RUST-REF-UNION`
255+
- The Rust Reference...
256+
```

exts/coding_guidelines/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from sphinx.domains import Domain
55

66
from . import (
7+
bibliography_validator,
8+
citation_roles,
79
common,
810
fls_checks,
911
fls_linking,
@@ -77,6 +79,12 @@ def setup(app):
7779

7880
# Set up rust_examples extension
7981
rust_examples.setup(app)
82+
83+
# Set up bibliography validator extension
84+
bibliography_validator.setup(app)
85+
86+
# Set up citation roles for bibliography linking
87+
citation_roles.setup(app)
8088

8189
app.connect("env-check-consistency", guidelines_checks.validate_required_fields)
8290
app.connect("env-check-consistency", fls_checks.check_fls)

0 commit comments

Comments
 (0)