Skip to content

Commit fc179e3

Browse files
authored
Normalize terminology to fit other standards (rustfoundation#23)
* Updated to more closely follow best practices in coding guidelines * Update guideline template generator to comply with guidelines spec changes * Added ability to use flag --update-spec-lock-file to update the spec lock file: spec.lock
1 parent 47dd576 commit fc179e3

File tree

9 files changed

+39819
-39750
lines changed

9 files changed

+39819
-39750
lines changed

builder/build_cli.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
import argparse
1212
import subprocess
1313
import sys
14-
14+
import requests
15+
import json
1516

1617
# Automatically watch the following extra directories when --serve is used.
1718
EXTRA_WATCH_DIRS = ["exts", "themes"]
1819

20+
SPEC_CHECKSUM_URL = "https://spec.ferrocene.dev/paragraph-ids.json"
21+
SPEC_LOCKFILE = "spec.lock"
1922

2023
def build_docs(root, builder, clear, serve, debug):
2124
dest = root / "build"
@@ -60,6 +63,34 @@ def build_docs(root, builder, clear, serve, debug):
6063

6164
return dest / builder
6265

66+
def update_spec_lockfile(spec_checksum_location, lockfile_location):
67+
68+
try:
69+
response = requests.get(spec_checksum_location, stream=True)
70+
71+
response.raise_for_status()
72+
73+
with open(lockfile_location, 'wb') as file:
74+
for chunk in response.iter_content(chunk_size=8192):
75+
if chunk:
76+
file.write(chunk)
77+
78+
with open(lockfile_location, 'r') as file:
79+
data = json.load(file)
80+
81+
print("-- read in --")
82+
83+
with open(lockfile_location, 'w') as outfile:
84+
json.dump(data, outfile, indent=4, sort_keys=True)
85+
86+
print("-- wrote back out --")
87+
88+
return True
89+
90+
except Exception as e:
91+
print(f"Error downloading file: {e}")
92+
return False
93+
6394
def main(root):
6495
root = Path(root)
6596

@@ -68,6 +99,11 @@ def main(root):
6899
"-c", "--clear", help="disable incremental builds", action="store_true"
69100
)
70101
group = parser.add_mutually_exclusive_group()
102+
parser.add_argument(
103+
"--update-spec-lock-file",
104+
help="update fls.lock file",
105+
action="store_true"
106+
)
71107
group.add_argument(
72108
"-s",
73109
"--serve",
@@ -87,6 +123,9 @@ def main(root):
87123
)
88124
args = parser.parse_args()
89125

126+
if args.update_spec_lock_file:
127+
update_spec_lockfile(SPEC_CHECKSUM_URL, root / "src" / SPEC_LOCKFILE)
128+
90129
rendered = build_docs(
91130
root, "xml" if args.xml else "html", args.clear, args.serve, args.debug
92131
)

exts/coding_guidelines/fls_checks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def check_fls(app, env):
5858

5959
def read_fls_ignore_list(app):
6060
"""Read the list of FLS IDs to ignore from a file"""
61-
ignore_file_path = app.confdir / 'fls_ignore_list.txt'
61+
ignore_file_path = app.confdir / 'spec_ignore_list.txt'
6262
ignore_list = []
6363

6464
if ignore_file_path.exists():
@@ -276,7 +276,7 @@ def check_fls_lock_consistency(app, env, fls_raw_data):
276276
- List of difference descriptions with affected guidelines (for error reporting)
277277
"""
278278
logger.info("Checking FLS lock file consistency")
279-
lock_path = app.confdir / 'fls.lock'
279+
lock_path = app.confdir / 'spec.lock'
280280

281281
# Get the needs data to find affected guidelines
282282
data = SphinxNeedsData(env)

exts/coding_guidelines/write_guidelines_ids.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ def write_guidelines_ids(app):
7070
"link": f"{doc_uri}#{need['id']}",
7171
"checksum": checksum,
7272
"rationale": None,
73-
"bad_example": None,
74-
"good_example": None
73+
"non_compliant_example": None,
74+
"compliant_example": None
7575
}
7676

7777
# Look for associated elements using parent_needs_back
@@ -101,18 +101,18 @@ def write_guidelines_ids(app):
101101
# Add to the appropriate field based on type
102102
if related_type == 'rationale':
103103
guideline_data["rationale"] = related_data
104-
elif related_type == 'bad_example':
105-
guideline_data["bad_example"] = related_data
106-
elif related_type == 'good_example':
107-
guideline_data["good_example"] = related_data
104+
elif related_type == 'non_compliant_example':
105+
guideline_data["non_compliant_example"] = related_data
106+
elif related_type == 'compliant_example':
107+
guideline_data["compliant_example"] = related_data
108108

109109
# Check for missing elements
110110
if guideline_data["rationale"] is None:
111111
missing_elements.append("rationale")
112-
if guideline_data["bad_example"] is None:
113-
missing_elements.append("bad_example")
114-
if guideline_data["good_example"] is None:
115-
missing_elements.append("good_example")
112+
if guideline_data["non_compliant_example"] is None:
113+
missing_elements.append("non_compliant_example")
114+
if guideline_data["compliant_example"] is None:
115+
missing_elements.append("compliant_example")
116116

117117
# Track incomplete guidelines
118118
if missing_elements:

generate-guideline-templates.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ def generate_guideline_template():
2020
# Generate IDs for all sections
2121
guideline_id = generate_id("gui")
2222
rationale_id = generate_id("rat")
23-
bad_example_id = generate_id("bad_ex")
24-
good_example_id = generate_id("good_ex")
23+
non_compliant_example_id = generate_id("non_compl_ex")
24+
compliant_example_id = generate_id("compl_ex")
2525

2626
template = f""".. guideline:: Title Here
2727
:id: {guideline_id}
28+
:category:
2829
:status: draft
29-
:fls:
30-
:tags:
31-
:category:
32-
:recommendation:
30+
:fls:
31+
:decidability:
32+
:scope:
33+
:tags:
3334
3435
Description of the guideline goes here.
3536
@@ -39,28 +40,28 @@ def generate_guideline_template():
3940
4041
Explanation of why this guideline is important.
4142
42-
.. bad_example::
43-
:id: {bad_example_id}
43+
.. non_compliant_example::
44+
:id: {non_compliant_example_id}
4445
:status: draft
4546
4647
Explanation of code example.
4748
4849
.. code-block:: rust
4950
5051
fn example_function() {{
51-
// Bad implementation
52+
// Non-compliant implementation
5253
}}
5354
54-
.. good_example::
55-
:id: {good_example_id}
55+
.. compliant_example::
56+
:id: {compliant_example_id}
5657
:status: draft
5758
5859
Explanation of code example.
5960
6061
.. code-block:: rust
6162
6263
fn example_function() {{
63-
// Bad implementation
64+
// Compliant implementation
6465
}}
6566
"""
6667
return template

src/coding-guidelines/types-and-traits.rst

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@ Types and Traits
88

99
.. guideline:: Avoid Implicit Integer Wrapping
1010
:id: gui_xztNdXA2oFNB
11+
:category: required
1112
:status: draft
1213
:fls: fls_cokwseo3nnr
14+
:decidability: decidable
15+
:scope: module
1316
:tags: numerics
14-
:category: types
15-
:recommendation: required
1617

1718
Code must not rely on Rust's implicit integer wrapping behavior that occurs in release builds.
1819
Instead, explicitly handle potential overflows using the standard library's checked,
1920
saturating, or wrapping operations.
2021

21-
.. rationale::
22+
.. rationale::
2223
:id: rat_kYiIiW8R2qD1
2324
:status: draft
2425

@@ -30,8 +31,8 @@ Types and Traits
3031
configurations. Explicit handling of potential overflow conditions improves code clarity,
3132
maintainability, and reduces the risk of numerical errors in production.
3233

33-
.. bad_example::
34-
:id: bad_ex_PO5TyFsRTlWv
34+
.. non_compliant_example::
35+
:id: non_compl_ex_PO5TyFsRTlWv
3536
:status: draft
3637

3738
.. code-block:: rust
@@ -41,8 +42,8 @@ Types and Traits
4142
current + velocity
4243
}
4344
44-
.. good_example::
45-
:id: good_ex_WTe7GoPu5Ez0
45+
.. compliant_example::
46+
:id: compl_ex_WTe7GoPu5Ez0
4647
:status: draft
4748

4849
.. code-block:: rust

src/conf.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@
4848
"style": "node"
4949
},
5050
{
51-
"directive": "good_example",
52-
"title": "Good Example",
53-
"prefix": "good_ex_",
51+
"directive": "compliant_example",
52+
"title": "Compliant Example",
53+
"prefix": "compl_ex_",
5454
"color": "#729FCF",
5555
"style": "node"
5656
},
5757
{
58-
"directive": "bad_example",
59-
"title": "Bad Example",
60-
"prefix": "bad_ex_",
58+
"directive": "non_compliant_example",
59+
"title": "Non-Compliant Example",
60+
"prefix": "non_compl_ex_",
6161
"color": "#729FCF",
6262
"style": "node"
6363
}
@@ -69,8 +69,8 @@
6969
"content": [
7070
"content",
7171
"rationale",
72-
"good_example",
73-
"bad_example"
72+
"non_compliant_example",
73+
"compliant_example"
7474
]
7575
}
7676
}
@@ -79,12 +79,12 @@
7979
needs_render_contexts = {
8080
"guideline": {
8181
"content": ["content"],
82-
"extra_content": ["rationale", "bad_example", "good_example"]
82+
"extra_content": ["rationale", "non_compliant_example", "non_compliant_example"]
8383
}
8484
}
8585

8686
# Make sure these sections are included in the JSON
87-
needs_extra_sections = ["rationale", "good_example", "bad_example"]
87+
needs_extra_sections = ["rationale", "compliant_example", "non_compliant_example"]
8888

8989
needs_statuses = [
9090
dict(name="draft", description="This guideline is in draft stage", color="#999999"),
@@ -101,13 +101,26 @@
101101
dict(name="numerics", description="Numerics-related guideline"),
102102
]
103103

104-
needs_recommendations = [
105-
dict(name="encouraged", description="This guideline is encouraged", color="#999999"),
104+
needs_categories = [
105+
dict(name="mandatory", description="This guideline is mandatory", color="#999999"),
106106
dict(name="required", description="This guideline is required", color="#FFCC00"),
107+
dict(name="advisory", description="This guideline is advisory, should be followed when able", color="#FFCC00"),
108+
dict(name="disapplied", description="This guideline is advisory, should be followed when able", color="#FFCC00"),
109+
]
110+
111+
needs_decidabilities = [
112+
dict(name="decidable", description="This guideline can be automatically checked with tooling", color="#999999"),
113+
dict(name="undecidable", description="This guideline cannot be automatically checked with tooling", color="#999999"),
114+
]
115+
116+
needs_scopes = [
117+
dict(name="module", description="This guideline can be checked at the module level", color="#999999"),
118+
dict(name="crate", description="This guideline can be checked at the crate level", color="#FFCC00"),
119+
dict(name="system", description="This guideline must be checked alongside the entire source", color="#FFCC00"),
107120
]
108121

109122
# Enable needs export
110-
needs_extra_options = ["category", "recommendation", "fls"]
123+
needs_extra_options = ["category", "recommendation", "fls", "decidability", "scope"]
111124

112125
# -- Options for HTML output -------------------------------------------------
113126

0 commit comments

Comments
 (0)