Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pkg-fmt = "tgz"

[dependencies]
anyhow = "1"
# Production file output and integration tests share UTF-8 capability paths.
camino = "1.2.4"
cap-std = { version = "4.0.2", features = ["fs_utf8"] }
clap = { version = "4", features = ["derive"] }
Expand Down
8 changes: 1 addition & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,7 @@ check-ripgrep: ## Verify ripgrep is available
}

check-static-regexes: check-ripgrep ## Reject hand-rolled static regular expressions
@status=0; \
$(RG) -U --glob '*.rs' '\bstatic\b[^;=]*=\s*(?:[[:alnum:]_]+::)*LazyLock::new\s*\(\s*\|\|\s*(\{\s*)?(?:[[:alnum:]_]+::)*Regex::new' . || status=$$?; \
case $$status in \
0) echo "static regular expressions must use lazy_regex!"; exit 1 ;; \
1) ;; \
*) echo "failed to scan Rust sources (rg exit $$status)" >&2; exit $$status ;; \
esac
@RG='$(RG)' scripts/check-static-regexes.sh .

markdownlint: ## Lint Markdown files
$(MDLINT) "**/*.md"
Expand Down
2 changes: 2 additions & 0 deletions docs/contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
Rust documentation tests that avoid brittle or misleading examples.
- [Rust testing with rstest fixtures](rust-testing-with-rstest-fixtures.md):
Reference for the fixture and parameterization patterns used in tests.
- [Whitaker user's guide](whitaker-users-guide.md): Imported reference for
Whitaker lints, including path-level `no_std_fs_operations` exclusions.
- [Trailing spaces](trailing-spaces.md): Notes on preserving Markdown hard line
breaks and other trailing-space-sensitive content.

Expand Down
43 changes: 42 additions & 1 deletion docs/developers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ restores the separator row with widths derived from the final table body.

- `check-static-regexes`: Runs before Clippy as part of `make lint` and uses
ripgrep (`rg`) to reject hand-rolled static regular expression declarations.
The scan lives in `scripts/check-static-regexes.sh` and rejects any `static`
that wraps `Regex::new` directly in a supported lazy-wrapper constructor —
`std::sync::LazyLock::new` or `once_cell::sync::Lazy::new`, whether spelled
directly or fully qualified — so `lazy_regex!` remains the sole sanctioned
idiom. `tests/static_regex_lint.rs` exercises every supported form.
Contributors must install ripgrep locally; Continuous Integration (CI)
installs the pinned version before running the lint gate.

Expand Down Expand Up @@ -985,7 +990,43 @@ integration-test binary crates. The `#[expect(unused_macros)]` suppressions
that previously guarded them were replaced by the export attribute when it
became clear that multiple test binaries depend on them.

### 2.3. `test-macros` crate
### 2.3. Capability-scoped test filesystem access

All integration tests under `tests/` use `camino::Utf8Path` and
`camino::Utf8PathBuf` for runtime paths and perform filesystem operations
through `cap_std::fs_utf8::Dir`. Absolute paths are retained only for process
boundaries such as `std::process::Command`; reads, writes, metadata queries,
copies, and permission changes use paths relative to an opened directory
capability.

The `camino` and `cap-std` crates are normal dependencies because the
production CLI already uses them for file output. The integration suite shares
those dependencies instead of declaring redundant dev-dependencies. This keeps
production and test filesystem semantics aligned while avoiding two independent
version declarations.

`tests/common/fs.rs` owns `TestDir`, the reusable temporary-directory boundary.
It converts `tempfile::TempDir`'s platform path to a UTF-8 path once, opens the
directory capability, and retains the `TempDir` guard for the test's lifetime.
Only integration tests may include this helper. Callers compose it by using
relative paths with `TestDir::directory()` and by deriving an absolute
`Utf8PathBuf` from `TestDir::path()` only when invoking a child process. It
must not absorb fixture-specific logic or production filesystem behaviour.

Repository fixture access remains an explicit ambient boundary. Focused modules
such as `tests/cli_matrix/fixture_io.rs` open `CARGO_MANIFEST_DIR` once and
expose only capability-scoped fixture queries. New tests must follow the same
pattern instead of calling `std::fs`, storing `std::path::PathBuf`, or relying
on `Utf8Path::exists`, which performs an ambient metadata query.

Whitaker's `no_std_fs_operations` lint supports `excluded_paths` for genuinely
unavoidable ambient boundaries. Prefer the capability pattern above; use a
path-level exclusion only when the boundary cannot be expressed through
`cap_std`, and record the reason beside the configuration. See the imported
[Whitaker user's guide](whitaker-users-guide.md#no_std_fs_operations) for the
configuration syntax and segment-matching rules.

### 2.4. `test-macros` crate

The `test-macros` workspace crate provides the `allow_fixture_expansion_lints`
proc-macro attribute. It suppresses the `unused_braces` lint that `rstest`
Expand Down
8 changes: 6 additions & 2 deletions docs/repository-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ output and most test fixtures.
│ ├── developers-guide.md
│ ├── documentation-style-guide.md
│ ├── repository-layout.md
│ ├── whitaker-users-guide.md
│ └── users-guide.md
├── src/
│ ├── fences/
Expand Down Expand Up @@ -69,6 +70,8 @@ _Figure 1: Simplified repository tree._
the Markdown processing pipeline.
- `docs/documentation-style-guide.md`: Documentation style rules imported from
the shared Rust agent template.
- `docs/whitaker-users-guide.md`: Imported Whitaker lint reference, including
crate-level and path-level filesystem exclusion configuration.
- `docs/adrs/`: Accepted architecture decision records. Add narrow decision
records here when design choices need a durable audit trail.
- `docs/execplans/`: Living execution plans and roadmap documents for larger
Expand Down Expand Up @@ -98,8 +101,9 @@ _Figure 1: Simplified repository tree._

- `tests/*.rs`: Integration and behavioural tests for command-line workflows
and Markdown transformations.
- `tests/common/`: Shared integration test support. Keep helpers explicit and
avoid direct environment mutation.
- `tests/common/`: Shared integration test support. `fs.rs` owns temporary
directory capability setup; keep other helpers explicit and avoid direct
environment mutation.
- `tests/cli_matrix/`: Matrix-test support for command-line option combinations
and invariants.
- `tests/data/`: Input and expected-output fixtures. Treat these as reviewable
Expand Down
Loading
Loading