Skip to content

Commit 5325c5a

Browse files
authored
Merge pull request #434 from control-toolbox/philosophy-docs-and-code-fixes
Philosophy docs and code fixes
2 parents 03d4d02 + 2e32150 commit 5325c5a

35 files changed

Lines changed: 684 additions & 682 deletions

.github/workflows/CI.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ on:
66
- main
77
tags: '*'
88
pull_request:
9-
9+
types: [labeled, synchronize, opened, reopened]
10+
1011
jobs:
1112
call:
1213
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'run ci')

.github/workflows/Documentation.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ on:
66
- main
77
tags: '*'
88
pull_request:
9-
9+
types: [labeled, synchronize, opened, reopened]
10+
1011
jobs:
1112
call:
1213
if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'run documentation')

BREAKINGS.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22

33
This document outlines all breaking changes introduced in CTBase v0.18.0-beta compared to v0.17.4. Use this guide to migrate your code and understand the impact of these changes.
44

5+
## Non-breaking note (0.18.15-beta)
6+
7+
- **Philosophy documentation**: Added comprehensive code philosophy documentation in `dev/philosophy/` covering modules, types/traits, exceptions, docstrings, testing, and documentation standards. No API changes; purely documentation additions.
8+
- **Agent guides**: Added `AGENTS.md` and `CLAUDE.md` for agent navigation and project context. No API changes; purely documentation additions.
9+
- **Documentation build improvements**: Changed `docs/make.jl` build method and fixed cross-references. No API changes; purely documentation improvements.
10+
- **Typed exceptions**: Replaced untyped `error()` and `ArgumentError` with structured CTBase exceptions in `ext/` files. No API changes; internal error handling improvement.
11+
- **Import qualification**: Qualified imports in submodules (`using DocStringExtensions``import DocStringExtensions: TYPEDEF, TYPEDSIGNATURES`). No API changes; internal code quality improvement.
12+
- **Code cleanup**: Removed dead ternary branches, fixed byte-indexing, removed circular imports. No API changes; internal code quality improvement.
13+
- **TestRunner auto-discovery fix**: Fixed non-recursive test discovery in auto-discovery mode. No API changes; bug fix.
14+
- **Docstring refactoring**: Rewrote ExtensionError and SolverFailure docstrings with `$(TYPEDEF)` and standardized sections. No API changes; documentation improvement.
15+
- **No migration required**: All changes are internal or documentation-only. No breaking changes.
16+
517
## Non-breaking note (0.18.14-beta)
618

719
- **TestRunner progress display refactoring**: Renamed `progress` parameter to `show_progress_line` for clarity, and added new `show_progress_bar` parameter for granular control. Users with `progress=false` should change to `show_progress_line=false`. Users with `progress=true` (default) can keep using defaults or set `show_progress_line=true, show_progress_bar=false` for minimal display without the graphical bar. No breaking changes; purely parameter rename with backward-compatible defaults. Migration: replace `progress=` with `show_progress_line=`.

CHANGELOGS.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,71 @@ All notable changes to CTBase will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.18.15-beta] - 2026-06-06
9+
10+
### 📚 Documentation
11+
12+
#### **Philosophy Documentation**
13+
14+
- **Added philosophy documentation**: Added comprehensive code philosophy documentation in `dev/philosophy/`
15+
- `modules.md`: Submodule organization, imports/qualification, DAG, exports
16+
- `types-traits-interfaces.md`: Types vs traits, interfaces/contracts, SOLID/DRY/YAGNI, type stability
17+
- `exceptions.md`: The 7 exceptions and the choice rule
18+
- `docstrings.md`: Docstring templates, cross-references, example safety
19+
- `testing.md`: Categories, fakes/stubs, module + callable function template
20+
- `documentation.md`: API generation, guides, draft workflow
21+
- **Added agent guides**: Added `AGENTS.md` (agent navigation guide) and `CLAUDE.md` (Claude project context)
22+
- **Added planning template**: Added `dev/planning.md` for implementation plans
23+
- **Added operational rules**: Added `dev/RULES.md` for MCP, doc build, git, and output capture procedures
24+
25+
#### **Documentation Build Improvements**
26+
27+
- **Faster builds**: Changed `docs/make.jl` from `Pkg.activate/instantiate` to `pushfirst!(LOAD_PATH, ...)` for faster builds
28+
- **Fixed cross-references**: Fixed unresolved `@ref` links for extension tags (AbstractCoveragePostprocessingTag, TestRunnerTag, AbstractTestRunnerTag)
29+
- **Added examples**: Added example code blocks for extension tags in docstrings
30+
- **Refactored docstrings**: Rewrote ExtensionError and SolverFailure docstrings with `$(TYPEDEF)`, standardized sections, and cross-references
31+
32+
### 🐛 Bug Fixes
33+
34+
#### **TestRunner Auto-Discovery**
35+
36+
- **Fixed non-recursive discovery**: Fixed test discovery in auto-discovery mode to use `_collect_test_files_recursive` instead of flat `readdir`
37+
- **Impact**: Tests in subdirectories were silently ignored in auto-discovery mode; now properly collected recursively
38+
39+
#### **Typed Exceptions (Tenet 6)**
40+
41+
- **Replaced untyped errors**: Replaced all `error()` and `ArgumentError` with structured CTBase exceptions across `ext/` files
42+
- `ext/TestRunner.jl`: 7 replacements (IncorrectArgument, PreconditionError)
43+
- `ext/CoveragePostprocessing.jl`: 4 replacements (PreconditionError)
44+
- `ext/DocumenterReference.jl`: 2 replacements (IncorrectArgument)
45+
- **Fixed invalid Julia syntax**: Fixed 2 occurrences of `catch e::CTBase.Exceptions.CTException``catch e` + `e isa ... || rethrow()`
46+
- **Fixed docstring output**: Corrected incorrect output in `_progress_bar` docstring (width=20 → 10 blocks)
47+
- **Updated tests**: Updated 7 test files to reflect new exception types
48+
49+
### 🧹 Code Quality
50+
51+
#### **Import Qualification**
52+
53+
- **Qualified imports**: Changed `using DocStringExtensions` to `import DocStringExtensions: TYPEDEF, TYPEDSIGNATURES` in all submodules
54+
- **Qualified Coverage import**: Changed `using Coverage` to `using Coverage: Coverage` in CoveragePostprocessing
55+
- **Removed circular import**: Removed `using CTBase` from src/Exceptions/Exceptions.jl
56+
- **Removed redundant imports**: Removed redundant `using DocStringExtensions` from src/Descriptions/types.jl
57+
58+
#### **Code Cleanup**
59+
60+
- **Removed dead ternary branches**: Simplified `_normalize_selections` and `_builder_to_string` in TestRunner
61+
- **Fixed byte-indexing**: Changed path slicing from byte-indexing to `relpath()` in CoveragePostprocessing
62+
- **Fixed collision risk**: Normalized flat names in cov file flattening to prevent collisions
63+
64+
### 🧪 Testing
65+
66+
- **All tests pass**: 1161/1161 tests pass
67+
- **Documentation builds**: Documentation builds successfully with no extension errors
68+
69+
### 🧹 Maintenance
70+
71+
- **Version bump**: Bumped to 0.18.15-beta for development.
72+
873
## [0.18.14-beta] - 2026-05-30
974

1075
### ✨ New Features

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "CTBase"
22
uuid = "54762871-cc72-4466-b8e8-f6c8b58076cd"
3-
version = "0.18.14-beta"
3+
version = "0.18.15-beta"
44
authors = ["Olivier Cots <olivier.cots@irit.fr>", "Jean-Baptiste Caillau <caillau@univ-cotedazur.fr>"]
55

66
[deps]

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[deps]
2+
CTBase = "54762871-cc72-4466-b8e8-f6c8b58076cd"
23
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
34
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
45
MarkdownAST = "d0879d2d-cac2-40c8-9cee-1863dc0c7391"

docs/README.md

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,29 @@ The documentation is built using [Documenter.jl](https://github.com/JuliaDocs/Do
88

99
## Building the Documentation
1010

11-
There are several ways to build the documentation locally.
12-
13-
### 1. Terminal One-Liner (Recommended)
14-
15-
From the root of the `CTBase.jl` repository, run:
11+
From the root of the repository:
1612

1713
```bash
18-
julia --project=docs/ -e 'using Pkg; Pkg.develop(path=pwd()); include("docs/make.jl"); Pkg.rm("CTBase")'
14+
julia --project=. docs/make.jl
1915
```
2016

21-
This command:
22-
- Activates the `docs` project environment.
23-
- Temporarily "develops" the current package so changes are reflected in the build.
24-
- Executes `make.jl` to build the site.
25-
- Cleans up the `docs` environment by removing the temporary link to `CTBase`.
26-
27-
### 2. Manual REPL Build
17+
`make.jl` prepends both `docs/` and the package root to `LOAD_PATH`, so the package
18+
project is picked up automatically — no `Pkg.develop` step needed.
2819

29-
If you prefer working inside the Julia REPL:
20+
### Draft mode (fast link validation)
3021

31-
```julia
32-
# 1. Activate the docs project
33-
using Pkg
34-
Pkg.activate("docs/")
22+
Set `draft = true` at the top of `docs/make.jl` to skip `@repl`/`@example` block
23+
execution. This is much faster when iterating on cross-references and page structure:
3524

36-
# 2. Add CTBase in development mode (if not already done)
37-
Pkg.develop(path=pwd())
38-
39-
# 3. Build the documentation
40-
include("docs/make.jl")
25+
```bash
26+
# edit docs/make.jl: draft = true (line 16)
27+
julia --project=. docs/make.jl
4128
```
4229

30+
!!! note "warnonly"
31+
`make.jl` uses `warnonly=[:cross_references]`, so cross-reference warnings do not
32+
abort the build. Other errors (missing pages, broken `@repl` blocks) still fail.
33+
4334
## Viewing the Documentation
4435

4536
After a successful build, the generated HTML files are located in `docs/build/`. You can open `index.html` in your browser:
@@ -54,7 +45,7 @@ xdg-open docs/build/index.html
5445

5546
## Directory Structure
5647

57-
- `src/`: Contains the manual markdown files (Introduction, Tutorials, etc.).
48+
- `src/`: Contains the manual markdown files (Introduction, Getting Started, Guides, etc.).
5849
- `make.jl`: The main build script for Documenter.
5950
- `api_reference.jl`: Contains the logic for automatic API reference generation. It extracts docstrings from the source code and creates temporary markdown files.
6051
- `build/`: The directory where the static website is generated (ignored by git).

docs/make.jl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
using Pkg
2-
Pkg.activate(@__DIR__)
3-
Pkg.develop(PackageSpec(; path=joinpath(@__DIR__, "..")))
4-
Pkg.instantiate()
1+
# to run the documentation generation:
2+
# julia --project=. docs/make.jl
3+
pushfirst!(LOAD_PATH, joinpath(@__DIR__))
4+
pushfirst!(LOAD_PATH, joinpath(@__DIR__, ".."))
55

66
using Documenter
77
using CTBase
@@ -54,7 +54,7 @@ with_api_reference(src_dir) do api_pages
5454
makedocs(;
5555
draft=draft,
5656
remotes=nothing, # Disable remote links. Needed for DocumenterReference
57-
warnonly=true,
57+
warnonly=[:cross_references],
5858
sitename="CTBase.jl",
5959
format=Documenter.HTML(;
6060
repolink="https://" * repo_url,
@@ -67,6 +67,7 @@ with_api_reference(src_dir) do api_pages
6767
),
6868
pages=[
6969
"Introduction" => "index.md",
70+
"Getting Started" => "getting-started.md",
7071
"User Guides" => [
7172
"Descriptions" => joinpath("guide", "descriptions.md"),
7273
"Exceptions" => joinpath("guide", "exceptions.md"),

docs/src/getting-started.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
```@meta
2+
CurrentModule = CTBase
3+
```
4+
5+
# Getting Started
6+
7+
## Installation
8+
9+
CTBase.jl is typically installed as a dependency of another package in the ecosystem
10+
(e.g. [OptimalControl.jl](https://github.com/control-toolbox/OptimalControl.jl)).
11+
To install it directly:
12+
13+
```julia
14+
import Pkg
15+
Pkg.add("CTBase")
16+
```
17+
18+
**Requires Julia ≥ 1.10.**
19+
20+
## Mental Model
21+
22+
CTBase is the **base layer** of the control-toolbox ecosystem.
23+
It provides infrastructure shared by every package above it.
24+
25+
Three things to keep in mind:
26+
27+
1. **No top-level exports.** `using CTBase` loads the package but brings no symbols
28+
into scope. Every symbol is accessed via its qualified path:
29+
```julia
30+
CTBase.Descriptions.add # ✓ always works
31+
CTBase.Exceptions.NotImplemented
32+
```
33+
2. **Submodule-first API.** The public API lives in named submodules
34+
(`Descriptions`, `Exceptions`, `Extensions`, `Core`, `Unicode`).
35+
You can bring a submodule's exports into scope explicitly:
36+
```julia
37+
using CTBase.Exceptions # brings IncorrectArgument, NotImplemented, … into scope
38+
```
39+
3. **Extension-backed features.** `run_tests`, `postprocess_coverage`, and
40+
`automatic_reference_documentation` require loading the matching weak dependency
41+
(`Test`, `Coverage`, `Documenter` respectively) before they become active.
42+
43+
## 5-Minute Walkthrough
44+
45+
### Working with Descriptions
46+
47+
A *description* is a `Tuple` of `Symbol`s that declaratively identifies an algorithm
48+
or configuration. Catalogues collect known descriptions; `complete` resolves a partial
49+
description to an exact one.
50+
51+
```@repl walkthrough
52+
using CTBase
53+
54+
# Build a catalogue
55+
descs = CTBase.Descriptions.add((), (:euler, :explicit))
56+
descs = CTBase.Descriptions.add(descs, (:euler, :implicit))
57+
descs = CTBase.Descriptions.add(descs, (:runge_kutta, :explicit))
58+
59+
# Partial completion: find the unique entry containing :implicit
60+
CTBase.Descriptions.complete(:implicit; descriptions=descs)
61+
62+
# Ambiguous completion raises AmbiguousDescription
63+
try
64+
CTBase.Descriptions.complete(:euler; descriptions=descs)
65+
catch e
66+
println(typeof(e))
67+
end
68+
```
69+
70+
For more, see the **[Descriptions guide](guide/descriptions.md)**.
71+
72+
### Working with Exceptions
73+
74+
CTBase defines a typed exception hierarchy rooted at
75+
[`CTBase.Exceptions.CTException`](@ref).
76+
Each type carries structured context fields for actionable error messages.
77+
78+
```@repl walkthrough
79+
# IncorrectArgument — invalid input value
80+
try
81+
throw(CTBase.Exceptions.IncorrectArgument(
82+
"state dimension must be positive";
83+
got="0",
84+
expected="n > 0",
85+
suggestion="Pass a positive integer for the state dimension",
86+
))
87+
catch e
88+
println(e)
89+
end
90+
91+
# NotImplemented — interface stub
92+
try
93+
throw(CTBase.Exceptions.NotImplemented(
94+
"solve! is not implemented";
95+
required_method="solve!(::MyStrategy, ocp)",
96+
suggestion="Import the package that provides this strategy",
97+
))
98+
catch e
99+
println(typeof(e))
100+
end
101+
```
102+
103+
For more, see the **[Exceptions guide](guide/exceptions.md)**.
104+
105+
## Next Steps
106+
107+
| Topic | Guide |
108+
|:---|:---|
109+
| Descriptions catalogue and completion | [Descriptions](guide/descriptions.md) |
110+
| Exception hierarchy and best practices | [Exceptions](guide/exceptions.md) |
111+
| Modular test runner setup | [Test Runner](guide/test-runner.md) |
112+
| Coverage report generation | [Coverage](guide/coverage.md) |
113+
| Auto-generated API reference | [API Documentation](guide/api-documentation.md) |
114+
| Full API reference | API Reference (left sidebar) |

docs/src/guide/api-documentation.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
```@meta
2+
CurrentModule = CTBase
3+
```
4+
15
# API Documentation Guide
26

37
This guide explains how to set up automated API reference documentation generation using the **DocumenterReference** extension of `CTBase.jl`. This is particularly useful for maintaining comprehensive and up-to-date API documentation as your codebase evolves.
48

59
## Overview
610

7-
The `DocumenterReference` extension provides the `CTBase.automatic_reference_documentation()` function, which automatically generates API reference pages from your Julia source code. It:
11+
The `DocumenterReference` extension provides the [`CTBase.automatic_reference_documentation`](@ref) function, which automatically generates API reference pages from your Julia source code. It:
812

913
- Extracts docstrings from your modules
1014
- Separates public and private APIs

0 commit comments

Comments
 (0)