Skip to content

Commit 86e5931

Browse files
chore: Add uv/mdformat tooling and format all documentation
- Add pyproject.toml with docs and dev dependency groups - Add uv.lock for reproducible environments - Configure mdformat with mkdocs, tables, frontmatter, and config plugins - Format all 73 markdown files with mdformat - Update .gitignore for .venv/ and site/ - Update contributing docs to reference uv workflow
1 parent 39fc0f2 commit 86e5931

76 files changed

Lines changed: 1543 additions & 653 deletions

Some content is hidden

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

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ docs/doxygen_sqlite3.db
2929
*.sublime-workspace
3030
.DS_Store
3131
site/
32+
.venv/
33+
34+
site/

docs/contributing/code-style.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ Coding conventions for the NUClear codebase.
99

1010
## Naming
1111

12-
| Element | Convention | Example |
13-
|---------|-----------|---------|
14-
| Variables, functions | `snake_case` | `log_level`, `emit_data()` |
15-
| Types, classes, structs | `PascalCase` | `PowerPlant`, `ReactionTask` |
16-
| Template parameters | `PascalCase` | `typename T`, `typename DSLWords` |
17-
| Constants | `UPPER_SNAKE_CASE` or `constexpr` variable | `LogLevel::INFO` |
18-
| Namespaces | `snake_case` | `NUClear::dsl::word` |
12+
| Element | Convention | Example |
13+
| ----------------------- | ------------------------------------------ | --------------------------------- |
14+
| Variables, functions | `snake_case` | `log_level`, `emit_data()` |
15+
| Types, classes, structs | `PascalCase` | `PowerPlant`, `ReactionTask` |
16+
| Template parameters | `PascalCase` | `typename T`, `typename DSLWords` |
17+
| Constants | `UPPER_SNAKE_CASE` or `constexpr` variable | `LogLevel::INFO` |
18+
| Namespaces | `snake_case` | `NUClear::dsl::word` |
1919

2020
## Formatting
2121

docs/contributing/development.md

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,40 +23,49 @@ Tests use [Catch2](https://github.com/catchorg/Catch2) and are automatically dow
2323
## Build Documentation
2424

2525
```bash
26-
pip install -r docs/requirements.txt
27-
mkdocs serve
26+
uv sync --group docs
27+
uv run mkdocs serve
2828
```
2929

3030
The docs will be available at `http://127.0.0.1:8000`.
3131

32+
## Format Documentation
33+
34+
Markdown files are formatted with [mdformat](https://github.com/hukkin/mdformat):
35+
36+
```bash
37+
uv sync --group dev
38+
uv run mdformat docs/
39+
```
40+
3241
## Project Structure
3342

34-
| Directory | Contents |
35-
|-----------|----------|
36-
| `src/` | Core library — PowerPlant, Reactor, DSL words, threading, utilities |
37-
| `src/dsl/word/` | Individual DSL word implementations (one header per word) |
38-
| `src/extension/` | Built-in extensions (network, IO, etc.) |
39-
| `src/threading/` | Scheduler, reactions, and thread pool management |
40-
| `tests/` | Test suite organized by feature area |
41-
| `tests/test_util/` | Shared test utilities (TestBase, TimeUnit, etc.) |
42-
| `docs/` | MkDocs documentation source |
43-
| `cmake/` | CMake modules and configuration templates |
43+
| Directory | Contents |
44+
| ------------------ | ------------------------------------------------------------------- |
45+
| `src/` | Core library — PowerPlant, Reactor, DSL words, threading, utilities |
46+
| `src/dsl/word/` | Individual DSL word implementations (one header per word) |
47+
| `src/extension/` | Built-in extensions (network, IO, etc.) |
48+
| `src/threading/` | Scheduler, reactions, and thread pool management |
49+
| `tests/` | Test suite organized by feature area |
50+
| `tests/test_util/` | Shared test utilities (TestBase, TimeUnit, etc.) |
51+
| `docs/` | MkDocs documentation source |
52+
| `cmake/` | CMake modules and configuration templates |
4453

4554
## Adding a New DSL Word
4655

4756
1. Create a header in `src/dsl/word/YourWord.hpp`
48-
2. Implement the required static methods (`bind`, `get`, `precondition`, etc.)
49-
3. Add it to the forward declarations in `src/Reactor.hpp`
50-
4. Add a `using` alias in the Reactor class
57+
1. Implement the required static methods (`bind`, `get`, `precondition`, etc.)
58+
1. Add it to the forward declarations in `src/Reactor.hpp`
59+
1. Add a `using` alias in the Reactor class
5160

5261
See [Extending the DSL](../how-to/extending-dsl.md) for the full guide on DSL word interfaces.
5362

5463
## Adding a Test
5564

5665
1. Create a `.cpp` file in the appropriate `tests/tests/` subdirectory
57-
2. Include `<catch2/catch_test_macros.hpp>` and `"nuclear"`
58-
3. Use `test_util::TestBase` as a base class for reactor-based tests
59-
4. Register the test in the corresponding `CMakeLists.txt`
66+
1. Include `<catch2/catch_test_macros.hpp>` and `"nuclear"`
67+
1. Use `test_util::TestBase` as a base class for reactor-based tests
68+
1. Register the test in the corresponding `CMakeLists.txt`
6069

6170
Example structure:
6271

docs/contributing/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ Welcome! We're glad you're interested in contributing to NUClear.
1212
## Getting Started
1313

1414
1. Read the [Development Setup](development.md) guide to build and test locally
15-
2. Review the [Code Style](code-style.md) conventions
16-
3. Pick an issue labeled `good first issue` or open a new one to discuss your idea
17-
4. Fork the repo, create a branch, and submit a PR
15+
1. Review the [Code Style](code-style.md) conventions
16+
1. Pick an issue labeled `good first issue` or open a new one to discuss your idea
17+
1. Fork the repo, create a branch, and submit a PR
1818

1919
## Pull Request Guidelines
2020

docs/explanation/architecture.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ This means:
6969
A **Reactor** is a self-contained component that:
7070

7171
1. **Declares its interests** — "When X happens, run this function"
72-
2. **Processes events** — the function runs with the relevant data
73-
3. **Produces outputs** — emits new messages for others to react to
72+
1. **Processes events** — the function runs with the relevant data
73+
1. **Produces outputs** — emits new messages for others to react to
7474

7575
```cpp
7676
class Vision : public NUClear::Reactor {
@@ -139,14 +139,14 @@ NUClear is built on the principle of **zero-cost abstractions**:
139139

140140
## How NUClear Compares
141141

142-
| Aspect | NUClear | ROS 2 |
143-
|--------|---------|-------|
144-
| Language | C++14+ | C++/Python |
145-
| Message routing | Compile-time types | Runtime topic strings |
146-
| Threading | Built-in scheduler with pools | Executor model |
147-
| Overhead | Near-zero (templates) | Serialization + IPC |
148-
| Scope | In-process (+ network) | Distributed by default |
149-
| Real-time | Designed for it | Possible (DDS) |
142+
| Aspect | NUClear | ROS 2 |
143+
| --------------- | ----------------------------- | ---------------------- |
144+
| Language | C++14+ | C++/Python |
145+
| Message routing | Compile-time types | Runtime topic strings |
146+
| Threading | Built-in scheduler with pools | Executor model |
147+
| Overhead | Near-zero (templates) | Serialization + IPC |
148+
| Scope | In-process (+ network) | Distributed by default |
149+
| Real-time | Designed for it | Possible (DDS) |
150150

151151
NUClear is intentionally focused on **in-process concurrency** with optional networking, rather than being a distributed middleware. This keeps it lightweight and predictable — exactly what you want when reactions need to complete in microseconds.
152152

docs/explanation/dsl-system.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ This single statement does a lot. Let's break it apart.
3838

3939
## Phase 2: Template Instantiation — `on<>()`
4040

41-
When you call `on<`[`Trigger`](../reference/dsl/trigger.md)`<T>, `[`Sync`](../reference/dsl/sync.md)`<G>>()`, the Reactor base class constructs a `Binder`:
41+
When you call `on<Trigger<T>, Sync<G>>()`, the Reactor base class constructs a `Binder`:
4242

4343
```cpp
4444
template <typename... DSL, typename... Arguments>
@@ -56,9 +56,9 @@ The key type here is `dsl::Parse<Trigger<T>, Sync<G>>` — this is the "fused" D
5656
When `.then()` is called, several things happen in sequence:
5757
5858
1. **CallbackGenerator created** — wraps your lambda with the DSL's get/precondition/scope logic
59-
2. **Reaction object created** — stores the generator, identifiers, and reactor reference
60-
3. **`DSL::bind(reaction)` called** — each word registers itself (e.g., Trigger adds to TypeCallbackStore)
61-
4. **ReactionHandle returned** — lets you enable/disable the reaction later
59+
1. **Reaction object created** — stores the generator, identifiers, and reactor reference
60+
1. **`DSL::bind(reaction)` called** — each word registers itself (e.g., Trigger adds to TypeCallbackStore)
61+
1. **ReactionHandle returned** — lets you enable/disable the reaction later
6262
6363
```cpp
6464
auto reaction = std::make_shared<threading::Reaction>(
@@ -103,9 +103,9 @@ emit(std::make_unique<SensorData>(...));
103103
This calls `Local::emit` which:
104104
105105
1. Stores the data in the global `DataStore<SensorData>`
106-
2. Sets `ThreadStore<SensorData>` (thread-local pointer) to the new data
107-
3. Looks up `TypeCallbackStore<SensorData>` for all registered reactions
108-
4. For each reaction: calls `reaction->get_task()` to create a task
106+
1. Sets `ThreadStore<SensorData>` (thread-local pointer) to the new data
107+
1. Looks up `TypeCallbackStore<SensorData>` for all registered reactions
108+
1. For each reaction: calls `reaction->get_task()` to create a task
109109
110110
## Phase 6: Task Creation — CallbackGenerator
111111
@@ -127,9 +127,9 @@ The `CallbackGenerator` does this in order:
127127

128128
1. **Creates a ReactionTask** with priority, inline preference, pool, and group functions
129129
1. **Checks precondition** — if false, task is dropped (e.g., [`Single`](../reference/dsl/single.md) blocks if already running)
130-
3. **Calls `DSL::get()`** — reads the data from ThreadStore (freshest) or DataStore (latest)
131-
4. **Checks data validity** — if any required data is null, task is dropped
132-
5. **Captures the callback** — binds the data into a closure stored on the task
130+
1. **Calls `DSL::get()`** — reads the data from ThreadStore (freshest) or DataStore (latest)
131+
1. **Checks data validity** — if any required data is null, task is dropped
132+
1. **Captures the callback** — binds the data into a closure stored on the task
133133

134134
## Phase 7: Task Submitted
135135

@@ -184,7 +184,7 @@ flowchart TD
184184

185185
The DSL uses several layers of compile-time machinery:
186186

187-
### Parse<Words...>
187+
### Parse\<Words...>
188188

189189
`Parse` is the entry point. It creates `Fusion<Words...>` and delegates each operation (bind, get, group, pool, priority, etc.) to the fusion, falling back to a `NoOp` if no word implements that operation.
190190

docs/explanation/index.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ If you've already followed the tutorials and know how to use NUClear, this is wh
66

77
## Pages
88

9-
| Page | What It Covers |
10-
|------|---------------|
11-
| [Architecture](architecture.md) | Why NUClear exists, the problems it solves, and the event-driven reactive pattern at its core |
12-
| [Threading Model](threading.md) | How tasks are scheduled across thread pools, priority queues, and group constraints |
13-
| [Lifecycle](lifecycle.md) | The three phases of a NUClear system: initialisation, execution, and shutdown |
14-
| [The DSL System](dsl-system.md) | How `on<>().then()` works from top to bottom — template metaprogramming in action |
15-
| [Message Flow](message-flow.md) | What happens when you emit data, from call site to reaction execution |
16-
| [NUClearNet](nuclear-net.md) | The peer-to-peer networking mesh that connects NUClear instances |
17-
| [Serialization](serialization.md) | How data is converted for network transmission |
9+
| Page | What It Covers |
10+
| --------------------------------- | --------------------------------------------------------------------------------------------- |
11+
| [Architecture](architecture.md) | Why NUClear exists, the problems it solves, and the event-driven reactive pattern at its core |
12+
| [Threading Model](threading.md) | How tasks are scheduled across thread pools, priority queues, and group constraints |
13+
| [Lifecycle](lifecycle.md) | The three phases of a NUClear system: initialisation, execution, and shutdown |
14+
| [The DSL System](dsl-system.md) | How `on<>().then()` works from top to bottom — template metaprogramming in action |
15+
| [Message Flow](message-flow.md) | What happens when you emit data, from call site to reaction execution |
16+
| [NUClearNet](nuclear-net.md) | The peer-to-peer networking mesh that connects NUClear instances |
17+
| [Serialization](serialization.md) | How data is converted for network transmission |

0 commit comments

Comments
 (0)