From 46b09a58251d7e54b8504597316cdf4fd03c6dbe Mon Sep 17 00:00:00 2001 From: Sewer56 Date: Sun, 6 Sep 2026 01:02:04 +0100 Subject: [PATCH] Changed: slim agent guidance and release template v1.4.2 - Delete `.llm/{general,performance,documentation}.md`; inline the performance reminders into `src/AGENTS.md` - Run rust-llm-tidy last in `verify.{sh,ps1}` when installed - Enforce `core` over `std` via the `std_instead_of_core` Clippy lint; benchmark imports `core::hint::black_box` - Add v1.4.2 migration guide; bump version marker, nav, about, and the template test contract Existing projects: follow docs/migration/v1.4.2.md. --- .github/tests/test_template.py | 79 +++++++++---- docs/migration/about.md | 2 + docs/migration/v1.4.2.md | 109 ++++++++++++++++++ mkdocs.yml | 1 + .../general/.github/template-version.txt | 2 +- templates/general/Cargo.toml | 5 + templates/general/src/.llm/documentation.md | 7 -- templates/general/src/.llm/general.md | 5 - templates/general/src/.llm/performance.md | 24 ---- templates/general/src/.llm/verify.ps1 | 7 ++ templates/general/src/.llm/verify.sh | 7 ++ templates/general/src/AGENTS.md | 13 ++- templates/general/src/cli/Cargo.toml | 3 + .../general/src/{{project-name}}/Cargo.toml | 3 + .../benches/my_benchmark/main.rs | 32 ++--- 15 files changed, 222 insertions(+), 77 deletions(-) create mode 100644 docs/migration/v1.4.2.md delete mode 100644 templates/general/src/.llm/documentation.md delete mode 100644 templates/general/src/.llm/general.md delete mode 100644 templates/general/src/.llm/performance.md diff --git a/.github/tests/test_template.py b/.github/tests/test_template.py index 9fc7f36..852b449 100755 --- a/.github/tests/test_template.py +++ b/.github/tests/test_template.py @@ -211,8 +211,8 @@ def validate_file_structure(self) -> bool: # Template version marker: every release bumps this deliberately. marker = self.project_path / ".github" / "template-version.txt" if marker.exists(): - if marker.read_text().strip() != "reloaded-templates-rust:1.4.1": - logger.error("✗ template-version.txt does not match 1.4.1") + if marker.read_text().strip() != "reloaded-templates-rust:1.4.2": + logger.error("✗ template-version.txt does not match 1.4.2") errors += 1 else: logger.error("✗ template-version.txt not found") @@ -644,7 +644,7 @@ def validate_builds(self) -> bool: return True def validate_v1_1_4_template_updates(self) -> bool: - """Validate v1.1.4 template changes (format-check job, AGENTS.md, guidance files, verify headers) and v1.3.0 workspace-root workflow paths.""" + """Validate v1.1.4 template updates (format-check job, AGENTS.md, verify headers) plus v1.3.0 workflow paths and v1.4.2 guidance/lint pins.""" logger.info("Validating v1.1.4 template updates...") errors = 0 @@ -702,31 +702,50 @@ def validate_v1_1_4_template_updates(self) -> bool: agents_text = agents_path.read_text() for line in ( "After changes, find and run `.llm/verify.{sh,ps1}` to test + lint.", - "If relevant to your review task, read `.llm/{general,performance,documentation}.md`.", + "Print all output.", + "Performance:", + "- Keep dependency footprint minimal.", ): if line not in agents_text: logger.error(f"✗ src/AGENTS.md missing guidance line: {line}") errors += 1 + + if ".llm/{general,performance,documentation}.md" in agents_text: + logger.error("✗ src/AGENTS.md still references deleted guidance files") + errors += 1 else: logger.error("✗ src/AGENTS.md not found") errors += 1 - guidance_files = [ - ("src/.llm/general.md", "# General Rules"), - ("src/.llm/performance.md", "# Performance Rules"), - ("src/.llm/documentation.md", "# Documentation Rules"), - ] - for rel_path, heading in guidance_files: - file_path = self.project_path / rel_path - if not file_path.exists(): - logger.error(f"✗ Guidance file not found: {rel_path}") + # v1.4.2: guidance is inlined into src/AGENTS.md; guidance files deleted. + for legacy in ( + "src/.llm/general.md", + "src/.llm/performance.md", + "src/.llm/documentation.md", + ): + errors += self._check_not_exists(legacy, f"Deleted guidance file {legacy}") + + # v1.4.2: core over std is enforced via the std_instead_of_core Clippy lint. + workspace_manifest = self.project_path / "Cargo.toml" + if not workspace_manifest.exists(): + logger.error("✗ Workspace Cargo.toml not found") + errors += 1 + elif "std_instead_of_core" not in workspace_manifest.read_text(): + logger.error("✗ Workspace Cargo.toml missing std_instead_of_core lint") + errors += 1 + + member_manifests = [f"src/{self.config.project_name}/Cargo.toml"] + if self.config.build_cli: + member_manifests.append("src/cli/Cargo.toml") + for rel_path in member_manifests: + manifest = self.project_path / rel_path + if not manifest.exists(): + logger.error(f"✗ Member manifest not found: {rel_path}") errors += 1 else: - content = file_path.read_text() - if heading not in content: - logger.error( - f"✗ Guidance file {rel_path} missing heading: {heading}" - ) + text = manifest.read_text() + if "[lints]" not in text or "workspace = true" not in text: + logger.error(f"✗ {rel_path} missing lint inheritance") errors += 1 gitignore_path = self.project_path / ".gitignore" @@ -739,15 +758,29 @@ def validate_v1_1_4_template_updates(self) -> bool: logger.error("✗ .gitignore not found") errors += 1 - for verify_rel in ["src/.llm/verify.sh", "src/.llm/verify.ps1"]: + # v1.4.2: tidy runs last, after the publish dry-run. + verify_scripts = [ + ("src/.llm/verify.sh", "run_cmd rust-llm-tidy"), + ("src/.llm/verify.ps1", 'Invoke-LoggedCommand "rust-llm-tidy"'), + ] + for verify_rel, invocation in verify_scripts: verify_path = self.project_path / verify_rel if verify_path.exists(): verify_text = verify_path.read_text() - if ( - "Script is relative to git repo root; search if not found" - not in verify_text + for fragment in ( + "Script is relative to git repo root; search if not found", + invocation, + "cargo install rust-llm-tidy-cli", ): - logger.error(f"✗ {verify_rel} missing new path comment") + if fragment not in verify_text: + logger.error(f"✗ {verify_rel} missing: {fragment}") + errors += 1 + + dry_run = verify_text.find("--dry-run") + if dry_run == -1 or verify_text.find(invocation) < dry_run: + logger.error( + f"✗ {verify_rel} tidy step must follow the publish dry-run" + ) errors += 1 else: logger.error(f"✗ {verify_rel} not found") diff --git a/docs/migration/about.md b/docs/migration/about.md index a4f3cce..7aa71f0 100644 --- a/docs/migration/about.md +++ b/docs/migration/about.md @@ -23,6 +23,7 @@ For information about migrating between template versions, see the following gui - **[v1.3.0]** - Project root becomes the workspace: docs to `doc/`, manifest to root, `.cargo` to `.llm` - **[v1.4.0]** - Add rust-llm-tidy CI: auto-tidies changed files on pull requests - **[v1.4.1]** - Remove root `AGENTS.md` shim, move style rule to `.llm/general.md` +- **[v1.4.2]** - Slim `.llm` guidance, tidy in verify, `core` over `std` lint [v1.0.0]: v1.0.0.md [v1.0.1]: v1.0.1.md @@ -36,3 +37,4 @@ For information about migrating between template versions, see the following gui [v1.3.0]: v1.3.0.md [v1.4.0]: v1.4.0.md [v1.4.1]: v1.4.1.md +[v1.4.2]: v1.4.2.md diff --git a/docs/migration/v1.4.2.md b/docs/migration/v1.4.2.md new file mode 100644 index 0000000..71ff703 --- /dev/null +++ b/docs/migration/v1.4.2.md @@ -0,0 +1,109 @@ +# Migration to v1.4.2 + +From `v1.4.1` to `v1.4.2`. + +Slims the LLM guidance and moves `core`-over-`std` to a Clippy lint: + +- Deletes the `.llm/{general,performance,documentation}.md` guidance files. +- Inlines the performance reminders into `src/AGENTS.md`. +- Runs [rust-llm-tidy] at the end of `.llm/verify.{sh,ps1}` when installed. +- Adds the `std_instead_of_core` Clippy lint to the workspace. + +## 1. Delete the guidance files + +```text +src/.llm/documentation.md +src/.llm/general.md +src/.llm/performance.md +``` + +## 2. Replace `src/AGENTS.md` + +```markdown +After changes, find and run `.llm/verify.{sh,ps1}` to test + lint. +Print all output. + +Performance: + +- Prefer borrows: `&str` / `&[T]` returns, `&'static str` constants, + `Cow<'_, str>` for conditional ownership. +- `Box` for immutable strings. +- Reuse buffers via `.clear()`. +- Const generics for compile-time branching such as + ``. +- Prefer performance-oriented crates such as `parking_lot` and `memchr`. +- Keep dependency footprint minimal. +``` + +## 3. Add the tidy step to the verify scripts + +In `.llm/verify.sh`, after the publish dry-run: + +```diff + echo "Publish dry-run..." + run_cmd cargo publish --dry-run --allow-dirty --quiet --workspace ++ ++echo "Tidy..." ++if command -v rust-llm-tidy >/dev/null 2>&1; then ++ run_cmd rust-llm-tidy ++else ++ echo "Skipping; rust-llm-tidy not installed. Install: cargo install rust-llm-tidy-cli" ++fi + + if [ "$EXIT_CODE" -eq 0 ]; then +``` + +In `.llm/verify.ps1`, after the publish dry-run: + +```diff + Write-Host "Publish dry-run..." + Invoke-LoggedCommand "cargo" @("publish", "--dry-run", "--allow-dirty", "--quiet", "--workspace") ++ ++ Write-Host "Tidy..." ++ if (Get-Command rust-llm-tidy -ErrorAction SilentlyContinue) { ++ Invoke-LoggedCommand "rust-llm-tidy" @() ++ } else { ++ Write-Host "Skipping; rust-llm-tidy not installed. Install: cargo install rust-llm-tidy-cli" ++ } + } finally { +``` + +## 4. Add the Clippy lint + +Root `Cargo.toml`: + +```diff + [workspace] + resolver = "2" + members = ["src/my-project"] ++ ++# Inherited by members via `[lints] workspace = true`. ++[workspace.lints.clippy] ++# Prefer `core` over `std` where both work. ++std_instead_of_core = "warn" +``` + +Every member crate (`src/my-project/Cargo.toml`, `src/cli/Cargo.toml` if present): + +```diff + # categories = ["command-line-utilities"] ++ ++[lints] ++workspace = true +``` + +Then fix any hits, for example the benchmark: + +```diff +-use std::hint::black_box; ++use core::hint::black_box; +``` + +## 5. Update the template version marker + +```diff +-reloaded-templates-rust:1.4.1 ++reloaded-templates-rust:1.4.2 +``` + +[rust-llm-tidy]: https://github.com/Sewer56/rust-llm-tidy diff --git a/mkdocs.yml b/mkdocs.yml index abc6cb8..1a79369 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -92,5 +92,6 @@ nav: - To v1.3.0: migration/v1.3.0.md - To v1.4.0: migration/v1.4.0.md - To v1.4.1: migration/v1.4.1.md + - To v1.4.2: migration/v1.4.2.md - License: https://reloaded-project.github.io/Reloaded.MkDocsMaterial.Themes.R2/Pages/license.html - How to Document: https://reloaded-project.github.io/Reloaded.MkDocsMaterial.Themes.R2/Pages/contributing.html diff --git a/templates/general/.github/template-version.txt b/templates/general/.github/template-version.txt index 9324afa..c69c592 100644 --- a/templates/general/.github/template-version.txt +++ b/templates/general/.github/template-version.txt @@ -1 +1 @@ -reloaded-templates-rust:1.4.1 +reloaded-templates-rust:1.4.2 diff --git a/templates/general/Cargo.toml b/templates/general/Cargo.toml index 4db4682..8c3f834 100644 --- a/templates/general/Cargo.toml +++ b/templates/general/Cargo.toml @@ -5,6 +5,11 @@ resolver = "2" members = ["src/{{project-name}}"{% if build_cli %}, "src/cli"{% endif %}] +# Inherited by members via `[lints] workspace = true`. +[workspace.lints.clippy] +# Prefer `core` over `std` where both work. +std_instead_of_core = "warn" + # Profile Build [profile.profile] inherits = "release" diff --git a/templates/general/src/.llm/documentation.md b/templates/general/src/.llm/documentation.md deleted file mode 100644 index dbbaea1..0000000 --- a/templates/general/src/.llm/documentation.md +++ /dev/null @@ -1,7 +0,0 @@ -# Documentation Rules - -- Document public items with `///`. -- Add examples in docs where helpful. -- Use `//!` for module-level docs. -- Focus comments on why, not what. -- Use [`TypeName`] rustdoc links instead of backticks. diff --git a/templates/general/src/.llm/general.md b/templates/general/src/.llm/general.md deleted file mode 100644 index 341fa51..0000000 --- a/templates/general/src/.llm/general.md +++ /dev/null @@ -1,5 +0,0 @@ -# General Rules - -- Keep modules under 500 lines excluding tests. -- Place `use` inside functions only for `#[cfg]` conditional compilation. -- Prefer `-` over `—`. Preserve explanatory user comments in method bodies. diff --git a/templates/general/src/.llm/performance.md b/templates/general/src/.llm/performance.md deleted file mode 100644 index 1e23079..0000000 --- a/templates/general/src/.llm/performance.md +++ /dev/null @@ -1,24 +0,0 @@ -# Performance Rules - -## Memory and allocation - -- Preallocate collections when size is known or estimable: - - `String::with_capacity(estimated_len)` - - `Vec::with_capacity(count)` - - `BufReader::with_capacity(size, reader)` -- Prefer `&str` / `&[T]` returns over owned types when lifetime allows. -- Use `Cow<'_, str>` for conditional ownership such as `String::from_utf8_lossy`. -- Use `&'static str` for compile-time constant strings. -- Reuse buffers with `.clear()` instead of reallocating. - -## Zero-cost abstractions - -- Use const generics for compile-time branching such as ``. -- Use `#[inline]` on small hot-path functions. -- Prefer `core` over `std` where possible. -- Stream data instead of loading entire files when possible. - -## Dependencies - -- Prefer performance-oriented crates such as `parking_lot` and `memchr`. -- Keep dependency footprint minimal. diff --git a/templates/general/src/.llm/verify.ps1 b/templates/general/src/.llm/verify.ps1 index abd422a..de2a2d7 100644 --- a/templates/general/src/.llm/verify.ps1 +++ b/templates/general/src/.llm/verify.ps1 @@ -80,6 +80,13 @@ try { Write-Host "Publish dry-run..." Invoke-LoggedCommand "cargo" @("publish", "--dry-run", "--allow-dirty", "--quiet", "--workspace") + + Write-Host "Tidy..." + if (Get-Command rust-llm-tidy -ErrorAction SilentlyContinue) { + Invoke-LoggedCommand "rust-llm-tidy" @() + } else { + Write-Host "Skipping; rust-llm-tidy not installed. Install: cargo install rust-llm-tidy-cli" + } } finally { $env:RUSTDOCFLAGS = $originalRustdocFlags Set-Location $originalDir diff --git a/templates/general/src/.llm/verify.sh b/templates/general/src/.llm/verify.sh index 1d5ce1b..e8c6432 100755 --- a/templates/general/src/.llm/verify.sh +++ b/templates/general/src/.llm/verify.sh @@ -51,6 +51,13 @@ run_cmd cargo fmt --all --quiet echo "Publish dry-run..." run_cmd cargo publish --dry-run --allow-dirty --quiet --workspace +echo "Tidy..." +if command -v rust-llm-tidy >/dev/null 2>&1; then + run_cmd rust-llm-tidy +else + echo "Skipping; rust-llm-tidy not installed. Install: cargo install rust-llm-tidy-cli" +fi + if [ "$EXIT_CODE" -eq 0 ]; then echo "All checks passed!" else diff --git a/templates/general/src/AGENTS.md b/templates/general/src/AGENTS.md index bee9b1f..f095553 100644 --- a/templates/general/src/AGENTS.md +++ b/templates/general/src/AGENTS.md @@ -1,2 +1,13 @@ After changes, find and run `.llm/verify.{sh,ps1}` to test + lint. -If relevant to your review task, read `.llm/{general,performance,documentation}.md`. +Print all output. + +Performance: + +- Prefer borrows: `&str` / `&[T]` returns, `&'static str` constants, + `Cow<'_, str>` for conditional ownership. +- `Box` for immutable strings. +- Reuse buffers via `.clear()`. +- Const generics for compile-time branching such as + ``. +- Prefer performance-oriented crates such as `parking_lot` and `memchr`. +- Keep dependency footprint minimal. diff --git a/templates/general/src/cli/Cargo.toml b/templates/general/src/cli/Cargo.toml index e224aa2..8ae8abf 100644 --- a/templates/general/src/cli/Cargo.toml +++ b/templates/general/src/cli/Cargo.toml @@ -11,5 +11,8 @@ readme = "README.MD" # categories (fixed list): https://crates.io/categories # categories = ["command-line-utilities"] +[lints] +workspace = true + [dependencies] {{project-name}} = { path = "../{{project-name}}" } diff --git a/templates/general/src/{{project-name}}/Cargo.toml b/templates/general/src/{{project-name}}/Cargo.toml index 302f022..e357b29 100644 --- a/templates/general/src/{{project-name}}/Cargo.toml +++ b/templates/general/src/{{project-name}}/Cargo.toml @@ -12,6 +12,9 @@ readme = "README.MD" # categories (fixed list): https://crates.io/categories # categories = ["development-tools"] +[lints] +workspace = true + [features] {% if std-by-default -%} default = ["std"] diff --git a/templates/general/src/{{project-name}}/benches/my_benchmark/main.rs b/templates/general/src/{{project-name}}/benches/my_benchmark/main.rs index 3d51952..75b2b4b 100644 --- a/templates/general/src/{{project-name}}/benches/my_benchmark/main.rs +++ b/templates/general/src/{{project-name}}/benches/my_benchmark/main.rs @@ -1,17 +1,17 @@ -// Example of how to include a 2nd file. -mod util; +criterion_group! { + name = benches; + config = Criterion::default(); + targets = criterion_benchmark +} + +criterion_main!(benches); use criterion::{criterion_group, criterion_main, Criterion}; -use std::hint::black_box; +use core::hint::black_box; -fn fibonacci(n: u64) -> u64 { - match n { - 0 => 1, - 1 => 1, - n => fibonacci(n-1) + fibonacci(n-2), - } -} +// Example of how to include a 2nd file. +mod util; fn criterion_benchmark(c: &mut Criterion) { c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20)))); @@ -24,10 +24,10 @@ fn criterion_benchmark(c: &mut Criterion) { {% endif %} } -criterion_group! { - name = benches; - config = Criterion::default(); - targets = criterion_benchmark +fn fibonacci(n: u64) -> u64 { + match n { + 0 => 1, + 1 => 1, + n => fibonacci(n-1) + fibonacci(n-2), + } } - -criterion_main!(benches); \ No newline at end of file