Skip to content

Commit 0324627

Browse files
committed
feat(adr): add multiple ADRs for Rust and Go tech stacks
- Add ADR-003f for Go CLI argument parsing using cobra. - Add ADR-004a for Rust dependency management using Cargo. - Add ADR-004b for Rust linting and formatting using rustfmt and clippy. - Add ADR-004c for Rust type checking using cargo check. - Add ADR-004d for Rust testing tooling using cargo test. - Add ADR-004e for Rust logging using tracing. - Add ADR-004f for Rust CLI argument parsing using clap. - Update Tech Radar to reflect new decisions and versions.
1 parent bf15d5e commit 0324627

25 files changed

+3798
-14
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# ADR-001a: Python dependency management 🧾
2+
3+
> | | |
4+
> | ------------ | ----------------------------------------------- |
5+
> | Date | `2026-02-08` when the decision was last updated |
6+
> | Status | `Accepted` |
7+
> | Significance | `Dependencies, Delivery & build` |
8+
9+
---
10+
11+
- [ADR-001a: Python dependency management 🧾](#adr-001a-python-dependency-management-)
12+
- [Context 🧭](#context-)
13+
- [Decision ✅](#decision-)
14+
- [Assumptions 🧩](#assumptions-)
15+
- [Drivers 🎯](#drivers-)
16+
- [Options 🔀](#options-)
17+
- [Option A: uv (Selected) ✅](#option-a-uv-selected-)
18+
- [Option B: Poetry](#option-b-poetry)
19+
- [Option C: pip-tools](#option-c-pip-tools)
20+
- [Option D: Pipenv](#option-d-pipenv)
21+
- [Option E: PDM](#option-e-pdm)
22+
- [Outcome 🏁](#outcome-)
23+
- [Rationale 🧠](#rationale-)
24+
- [Consequences ⚖️](#consequences-️)
25+
- [Compliance 📏](#compliance-)
26+
- [Notes 🔗](#notes-)
27+
- [Actions ✅](#actions-)
28+
- [Tags 🏷️](#tags-️)
29+
30+
## Context 🧭
31+
32+
The Python tech stack needs a default dependency manager that is fast, deterministic, and aligned with the toolchain. The decision must support a lock file and standard Python packaging workflows.
33+
34+
## Decision ✅
35+
36+
### Assumptions 🧩
37+
38+
- Python 3.14.3 is the baseline runtime.
39+
- `pyproject.toml` is the single source of truth for dependencies.
40+
- Deterministic installs and a lock file are required.
41+
42+
### Drivers 🎯
43+
44+
- Deterministic, reproducible installs
45+
- Alignment with modern Python packaging
46+
- Fast dependency resolution and installs
47+
- Low operational complexity
48+
- Good editor and CI support
49+
50+
### Options 🔀
51+
52+
#### Option A: uv (Selected) ✅
53+
54+
Use [`uv`](https://github.com/astral-sh/uv) with `pyproject.toml` and a lock file.
55+
56+
| Criteria | Score/Notes |
57+
| ------------------- | ---------------------------------------- |
58+
| Toolchain alignment | ⭐⭐⭐ Modern and fast |
59+
| Reproducibility | ⭐⭐⭐ Lock file is first-class |
60+
| Performance | ⭐⭐⭐ Very fast resolution and installs |
61+
| Workflow simplicity | ⭐⭐ Single tool for sync and run |
62+
| Ecosystem support | ⭐⭐ Growing adoption |
63+
| Effort | S |
64+
65+
#### Option B: Poetry
66+
67+
Use [`Poetry`](https://github.com/python-poetry/poetry) with its lock file and environment management.
68+
69+
| Criteria | Score/Notes |
70+
| ------------------- | -------------------------- |
71+
| Toolchain alignment | ⭐⭐ Common but heavier |
72+
| Reproducibility | ⭐⭐⭐ Lock file is strong |
73+
| Performance | ⭐⭐ Slower than uv |
74+
| Workflow simplicity | ⭐⭐ More tooling concepts |
75+
| Ecosystem support | ⭐⭐⭐ Widely used |
76+
| Effort | M |
77+
78+
**Why not chosen**: Strong feature set but slower and heavier for the baseline workflow.
79+
80+
#### Option C: pip-tools
81+
82+
Use [`pip-tools`](https://github.com/jazzband/pip-tools) for `requirements.txt` locking.
83+
84+
| Criteria | Score/Notes |
85+
| ------------------- | ---------------------------------- |
86+
| Toolchain alignment | ⭐⭐ Standard pip workflow |
87+
| Reproducibility | ⭐⭐⭐ Good lock via `pip-compile` |
88+
| Performance | ⭐⭐ Reasonable |
89+
| Workflow simplicity | ⭐⭐ Separate steps and files |
90+
| Ecosystem support | ⭐⭐⭐ Stable and familiar |
91+
| Effort | M |
92+
93+
**Why not chosen**: Does not centre `pyproject.toml` and adds extra workflow steps.
94+
95+
#### Option D: Pipenv
96+
97+
Use [`Pipenv`](https://github.com/pypa/pipenv) for dependency and virtualenv management.
98+
99+
| Criteria | Score/Notes |
100+
| ------------------- | ----------------------------------- |
101+
| Toolchain alignment | ⭐ Low, less common in new projects |
102+
| Reproducibility | ⭐⭐ Lock file exists |
103+
| Performance | ⭐ Low on larger sets |
104+
| Workflow simplicity | ⭐⭐ Mixed behaviours |
105+
| Ecosystem support | ⭐⭐ Maintained but lower adoption |
106+
| Effort | M |
107+
108+
**Why not chosen**: Lower adoption and slower resolution for larger projects.
109+
110+
#### Option E: PDM
111+
112+
Use [`PDM`](https://github.com/pdm-project/pdm) for PEP 582-style workflows.
113+
114+
| Criteria | Score/Notes |
115+
| ------------------- | ---------------------------------- |
116+
| Toolchain alignment | ⭐⭐ Modern but less common |
117+
| Reproducibility | ⭐⭐⭐ Lock file is strong |
118+
| Performance | ⭐⭐ Good |
119+
| Workflow simplicity | ⭐⭐ Different conventions |
120+
| Ecosystem support | ⭐⭐ Growing but smaller ecosystem |
121+
| Effort | M |
122+
123+
**Why not chosen**: Smaller ecosystem and less standardised workflows than uv.
124+
125+
### Outcome 🏁
126+
127+
Adopt `uv` as the default dependency manager for Python. This decision is reversible if the toolchain changes or if `uv` loses ecosystem support.
128+
129+
### Rationale 🧠
130+
131+
`uv` delivers fast, deterministic installs with a simple workflow aligned to modern Python packaging. It supports lock files and keeps the toolchain lean.
132+
133+
## Consequences ⚖️
134+
135+
- Python projects should use `pyproject.toml` with `uv` lock files.
136+
- Alternative tools require explicit justification.
137+
138+
## Compliance 📏
139+
140+
- `uv lock --check` produces no changes.
141+
- `uv sync` succeeds in CI.
142+
143+
## Notes 🔗
144+
145+
- Tech Radar: `./Tech_Radar.md`
146+
- Python downloads: <https://www.python.org/downloads/>
147+
148+
## Actions ✅
149+
150+
- [x] Copilot, 2026-02-08, record the dependency management decision
151+
152+
## Tags 🏷️
153+
154+
`#dependencies #build #reproducibility #maintainability`
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# ADR-001b: Python linting and formatting 🧾
2+
3+
> | | |
4+
> | ------------ | ----------------------------------------------- |
5+
> | Date | `2026-02-08` when the decision was last updated |
6+
> | Status | `Accepted` |
7+
> | Significance | `Quality attributes, Delivery & build` |
8+
9+
---
10+
11+
- [ADR-001b: Python linting and formatting 🧾](#adr-001b-python-linting-and-formatting-)
12+
- [Context 🧭](#context-)
13+
- [Decision ✅](#decision-)
14+
- [Assumptions 🧩](#assumptions-)
15+
- [Drivers 🎯](#drivers-)
16+
- [Options 🔀](#options-)
17+
- [Option A: Ruff (Selected) ✅](#option-a-ruff-selected-)
18+
- [Option B: Black + isort + Flake8](#option-b-black--isort--flake8)
19+
- [Option C: Pylint + Black](#option-c-pylint--black)
20+
- [Option D: autopep8 + pycodestyle](#option-d-autopep8--pycodestyle)
21+
- [Option E: YAPF + Flake8](#option-e-yapf--flake8)
22+
- [Outcome 🏁](#outcome-)
23+
- [Rationale 🧠](#rationale-)
24+
- [Consequences ⚖️](#consequences-️)
25+
- [Compliance 📏](#compliance-)
26+
- [Notes 🔗](#notes-)
27+
- [Actions ✅](#actions-)
28+
- [Tags 🏷️](#tags-️)
29+
30+
## Context 🧭
31+
32+
The Python tech stack needs a single, fast, consistent approach for linting and formatting that can run in CI and locally without heavy configuration.
33+
34+
## Decision ✅
35+
36+
### Assumptions 🧩
37+
38+
- Python 3.14.3 is the baseline runtime.
39+
- Formatting must be deterministic and consistent across the codebase.
40+
- Linting should catch correctness and style issues with low noise.
41+
42+
### Drivers 🎯
43+
44+
- One-tool workflow where possible
45+
- Fast execution for local and CI use
46+
- Deterministic formatting
47+
- High signal linting
48+
- Active maintenance and ecosystem support
49+
50+
### Options 🔀
51+
52+
#### Option A: Ruff (Selected) ✅
53+
54+
Use [`ruff`](https://github.com/astral-sh/ruff) for both linting and formatting.
55+
56+
| Criteria | Score/Notes |
57+
| ---------------------- | ------------------------------- |
58+
| Formatting consistency | ⭐⭐⭐ Built-in formatter |
59+
| Lint coverage | ⭐⭐⭐ Broad checks in one tool |
60+
| Performance | ⭐⭐⭐ Very fast |
61+
| Configuration overhead | ⭐⭐ Simple unified config |
62+
| Ecosystem support | ⭐⭐⭐ Strong and growing |
63+
| Effort | S |
64+
65+
#### Option B: Black + isort + Flake8
66+
67+
Use [`Black`](https://github.com/psf/black), [`isort`](https://github.com/PyCQA/isort), and [`Flake8`](https://github.com/PyCQA/flake8) together.
68+
69+
| Criteria | Score/Notes |
70+
| ---------------------- | --------------------------------- |
71+
| Formatting consistency | ⭐⭐⭐ Black is stable |
72+
| Lint coverage | ⭐⭐ Needs multiple plugins |
73+
| Performance | ⭐⭐ Multiple tools add overhead |
74+
| Configuration overhead | ⭐⭐ Many configs to keep in sync |
75+
| Ecosystem support | ⭐⭐⭐ Mature and stable |
76+
| Effort | M |
77+
78+
**Why not chosen**: Good quality but slower and more complex than a single tool.
79+
80+
#### Option C: Pylint + Black
81+
82+
Use [`Pylint`](https://github.com/pylint-dev/pylint) for linting and Black for formatting.
83+
84+
| Criteria | Score/Notes |
85+
| ---------------------- | ----------------------------------- |
86+
| Formatting consistency | ⭐⭐⭐ Black is stable |
87+
| Lint coverage | ⭐⭐⭐ Deep checks but can be noisy |
88+
| Performance | ⭐⭐ Slower on large codebases |
89+
| Configuration overhead | ⭐⭐ Significant tuning |
90+
| Ecosystem support | ⭐⭐ Stable but heavier |
91+
| Effort | M |
92+
93+
**Why not chosen**: Higher noise and slower than Ruff for the default stack.
94+
95+
#### Option D: autopep8 + pycodestyle
96+
97+
Use [`autopep8`](https://github.com/hhatto/autopep8) and [`pycodestyle`](https://github.com/PyCQA/pycodestyle).
98+
99+
| Criteria | Score/Notes |
100+
| ---------------------- | ------------------------------------- |
101+
| Formatting consistency | ⭐⭐ Less strict and less predictable |
102+
| Lint coverage | ⭐ Low, basic checks |
103+
| Performance | ⭐⭐⭐ Fast |
104+
| Configuration overhead | ⭐⭐ Moderate |
105+
| Ecosystem support | ⭐⭐ Stable but older stack |
106+
| Effort | M |
107+
108+
**Why not chosen**: Weaker lint coverage and less deterministic formatting.
109+
110+
#### Option E: YAPF + Flake8
111+
112+
Use [`YAPF`](https://github.com/google/yapf) with Flake8.
113+
114+
| Criteria | Score/Notes |
115+
| ---------------------- | -------------------------------- |
116+
| Formatting consistency | ⭐⭐ Configurable but subjective |
117+
| Lint coverage | ⭐⭐ Depends on Flake8 plugins |
118+
| Performance | ⭐⭐ Reasonable |
119+
| Configuration overhead | ⭐⭐ More tuning required |
120+
| Ecosystem support | ⭐⭐ Maintained but less common |
121+
| Effort | M |
122+
123+
**Why not chosen**: More configuration with no clear benefit over Ruff.
124+
125+
### Outcome 🏁
126+
127+
Adopt `ruff` for both linting and formatting. This decision is reversible if tooling changes or if ruff ceases to meet coverage needs.
128+
129+
### Rationale 🧠
130+
131+
Ruff provides a fast, single-tool workflow with strong lint coverage and a built-in formatter. It keeps the toolchain simple and consistent.
132+
133+
## Consequences ⚖️
134+
135+
- Projects should configure Ruff in `pyproject.toml`.
136+
- Additional linters require explicit justification.
137+
138+
## Compliance 📏
139+
140+
- `uv run ruff format --check .` produces no changes.
141+
- `uv run ruff check .` succeeds in CI.
142+
143+
## Notes 🔗
144+
145+
- Tech Radar: `./Tech_Radar.md`
146+
147+
## Actions ✅
148+
149+
- [x] Copilot, 2026-02-08, record the linting and formatting decision
150+
151+
## Tags 🏷️
152+
153+
`#quality #consistency #maintainability`

0 commit comments

Comments
 (0)