Skip to content

Commit 64a9ff1

Browse files
authored
Initial coding guidelines framework (#1)
1 parent bfd8526 commit 64a9ff1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+42290
-21
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Build Safety-Critical Rust Coding Guidelines
2+
3+
on:
4+
# Add on:
5+
push:
6+
tags:
7+
- "*.*.*"
8+
branches:
9+
- "main"
10+
pull_request:
11+
branches:
12+
- "main"
13+
# workflow_call trigger to make this workflow reusable
14+
workflow_call:
15+
# You can add inputs here if needed in the future
16+
# inputs:
17+
# example_input:
18+
# required: false
19+
# type: string
20+
# default: 'default value'
21+
22+
jobs:
23+
build:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout repository
27+
uses: actions/checkout@v3
28+
29+
- name: Install uv
30+
run: |
31+
curl -LsSf https://astral.sh/uv/install.sh | sh
32+
export PATH="/root/.cargo/bin:$PATH"
33+
uv --version
34+
35+
- name: Build documentation
36+
run: |
37+
mkdir -p build
38+
./make.py 2>&1 | tee build/build.log
39+
40+
# Check for a wide range of error indicators in the log
41+
if grep -q -E "Traceback" build/build.log; then
42+
echo "::error::Build errors detected in log"
43+
44+
# Extract error contexts and annotate them in the GitHub Actions UI
45+
echo "=== ERROR DETAILS ==="
46+
47+
# Check for the Sphinx temp error file reference and extract it if present
48+
TEMP_ERROR_FILE=$(grep -o '/tmp/sphinx-err-[^ ]*\.log' build/build.log | head -1)
49+
if [ ! -z "$TEMP_ERROR_FILE" ] && [ -f "$TEMP_ERROR_FILE" ]; then
50+
echo "==== SPHINX DETAILED TRACEBACK START ===="
51+
cat "$TEMP_ERROR_FILE"
52+
echo "==== SPHINX DETAILED TRACEBACK END ===="
53+
54+
# Save this traceback for artifacts
55+
cp "$TEMP_ERROR_FILE" build/sphinx_traceback.log
56+
fi
57+
58+
exit 1
59+
fi
60+
61+
- name: Archive build logs
62+
uses: actions/upload-artifact@v4
63+
if: always()
64+
with:
65+
name: build-logs
66+
path: build
67+
retention-days: 7
68+
compression-level: 6 # Default compression level for a good balance of speed and size

.github/workflows/nightly.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Nightly Safety-Critical Rust Coding Guidelines Build Schedule
2+
3+
on:
4+
schedule:
5+
# Run at 02:00 UTC every day
6+
- cron: '0 2 * * *'
7+
# Optional: Allow manual triggering for testing
8+
workflow_dispatch:
9+
# Temporary - remove before merging
10+
11+
jobs:
12+
trigger-build:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v3
17+
18+
- name: Log build start
19+
run: echo "Starting nightly build at $(date)"
20+
21+
# This is a "setup" job that can add pre-build steps if needed in the future
22+
23+
run-build:
24+
needs: trigger-build
25+
# Call the main build workflow
26+
uses: ./.github/workflows/build-guidelines.yml
27+
# If your main workflow is in a different file, adjust the path accordingly
28+
29+

.gitignore

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,2 @@
1-
# Generated by Cargo
2-
# will have compiled files and executables
3-
debug/
4-
target/
5-
6-
# These are backup files generated by rustfmt
7-
**/*.rs.bk
8-
9-
# MSVC Windows builds of rustc generate these, which store debugging information
10-
*.pdb
11-
12-
# RustRover
13-
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
14-
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
15-
# and can be added to the global gitignore or merged into this file. For a more nuclear
16-
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
17-
#.idea/
1+
__pycache__/
2+
build/
File renamed without changes.
File renamed without changes.
File renamed without changes.

README.md

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,59 @@
1-
# safety-critical-rust-coding-guidelines
1+
# Safety-Critical Rust Coding Guidelines
22

33
Coding Guidelines for Safety Critical Rust developed by the [Safety Critical Rust Consortium][safety-critical-rust-consortium].
44

5+
_Note_: Early, subject to changes.
6+
7+
## Building the coding guidelines
8+
9+
The Safety-Critical Rust Coding Guidelines use `Sphinx` and `Sphinx-Needs` to build a rendered version of the coding guidelines, and `uv` to install and manage Python dependencies (including Sphinx itself). To simplify building the rendered version, we created a script called `make.py` that takes care of invoking Sphinx with the right flags.
10+
11+
You can build the rendered version by running:
12+
13+
```shell
14+
./make.py
15+
```
16+
17+
By default, Sphinx uses incremental rebuilds to generate the content that
18+
changed since the last invocation. If you notice a problem with incremental
19+
rebuilds, you can pass the `-c` flag to clear the existing artifacts before
20+
building:
21+
22+
```shell
23+
./make.py -c
24+
```
25+
26+
The rendered version will be available in `build/html/`.
27+
28+
A machine-parseable artifact will be available at `build/html/needs.json`. (ToDo: Pete LeVasseur) The `needs.json` file could use some cleaning up and some description here of the contents.
29+
30+
A record with checksums of the contents is available at `build/html/guidelines-ids.json`. Users of the coding guidelines can reference this file to determine if there have been changes to coding guidelines contents they should be aware of.
31+
32+
## Contributing to the coding guidelines
33+
34+
We have the same chapter layout as the [Ferrocene Language Specification](https://spec.ferrocene.dev/) (FLS). If you would like to contribute you may find a section from the FLS of interest and then write a guideline in the corresponding chapter of these coding guidelines.
35+
36+
### Guideline template
37+
38+
We have a script `./generate-guideline-templates.py` which which assumes you're using `uv` that can be run to generate the template for a guideline with properly randomized IDs.
39+
40+
You can the copy and paste this guideline from the command line into the correct chapter.
41+
42+
### Filling out the guideline
43+
44+
Reference `src/conf.py` to see valid selections for unfilled options in the guideline template.
45+
46+
Note that the `:fls:` option should be filled according to the FLS paragraph ID for which the guideline is covering. One way to go about finding this is to inspect the page using your web browser. You'll be looking for something like:
47+
48+
```html
49+
<p><span class="spec-paragraph-id" id="fls_4rhjpdu4zfqj">4.1:1</span>
50+
```
51+
52+
You would then pull `fls_4rhjpdu4zfqj` to place in the `:fls:` option.
53+
54+
Existing guidelines can also serve as examples on how guidelines are filled.
55+
56+
557
## [Code of Conduct][code-of-conduct]
658

759
The [Rust Foundation][rust-foundation] has adopted a Code of Conduct that we
@@ -37,6 +89,3 @@ You can read about other Rust Foundation policies in the footer of the Foundatio
3789
[media-guide and trademark]: https://foundation.rust-lang.org/policies/logo-policy-and-media-guide/
3890
[rust-foundation]: https://foundation.rust-lang.org/
3991
[safety-critical-rust-consortium]: https://github.com/rustfoundation/safety-critical-rust-consortium
40-
41-
42-

builder/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Builder
2+
3+
A minimal project which creates `build_cli.py` to allow us to build the Safety-Critical Coding Guidelines.

builder/build_cli.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python3
2+
# SPDX-License-Identifier: MIT OR Apache-2.0
3+
# SPDX-FileCopyrightText: The Coding Guidelines Subcommittee Contributors
4+
5+
# Convenience script to build Sphinx books, including setting up a Python
6+
# virtual environment to install Sphinx into (removing the need to manage
7+
# dependencies globally). Each book should have a `make.py` script that updates
8+
# the submodules, import this shared module, and calls the main function here.
9+
10+
from pathlib import Path
11+
import argparse
12+
import subprocess
13+
import sys
14+
15+
16+
# Automatically watch the following extra directories when --serve is used.
17+
EXTRA_WATCH_DIRS = ["exts", "themes"]
18+
19+
20+
def build_docs(root, builder, clear, serve, debug):
21+
dest = root / "build"
22+
23+
args = ["-b", builder, "-d", dest / "doctrees"]
24+
if debug:
25+
# Disable parallel builds and show exceptions in debug mode.
26+
#
27+
# We can't show exceptions in parallel mode because in parallel mode
28+
# all exceptions will be swallowed up by Python's multiprocessing.
29+
# That's also why we don't show exceptions outside of debug mode.
30+
args += ["-j", "1", "-T"]
31+
else:
32+
# Enable parallel builds:
33+
args += ["-j", "auto"]
34+
if clear:
35+
args.append("-E")
36+
if serve:
37+
for extra_watch_dir in EXTRA_WATCH_DIRS:
38+
extra_watch_dir = root / extra_watch_dir
39+
if extra_watch_dir.exists():
40+
args += ["--watch", extra_watch_dir]
41+
else:
42+
# Error out at the *end* of the build if there are warnings:
43+
args += ["-W", "--keep-going"]
44+
45+
try:
46+
subprocess.run(
47+
[
48+
"sphinx-autobuild" if serve else "sphinx-build",
49+
*args,
50+
root / "src",
51+
dest / builder,
52+
],
53+
check=True,
54+
)
55+
except KeyboardInterrupt:
56+
exit(1)
57+
except subprocess.CalledProcessError:
58+
print("\nhint: if you see an exception, pass --debug to see the full traceback")
59+
exit(1)
60+
61+
return dest / builder
62+
63+
def main(root):
64+
root = Path(root)
65+
66+
parser = argparse.ArgumentParser()
67+
parser.add_argument(
68+
"-c", "--clear", help="disable incremental builds", action="store_true"
69+
)
70+
group = parser.add_mutually_exclusive_group()
71+
group.add_argument(
72+
"-s",
73+
"--serve",
74+
help="start a local server with live reload",
75+
action="store_true",
76+
)
77+
group.add_argument(
78+
"--check-links", help="Check whether all links are valid", action="store_true"
79+
)
80+
group.add_argument(
81+
"--xml", help="Generate Sphinx XML rather than HTML", action="store_true"
82+
)
83+
group.add_argument(
84+
"--debug",
85+
help="Debug mode for the extensions, showing exceptions",
86+
action="store_true",
87+
)
88+
args = parser.parse_args()
89+
90+
rendered = build_docs(
91+
root, "xml" if args.xml else "html", args.clear, args.serve, args.debug
92+
)
93+

builder/pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[project]
2+
name = "builder"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.12"
7+
dependencies = []

0 commit comments

Comments
 (0)