Skip to content
Merged
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
59 changes: 54 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
toolchain: stable
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
- run: cargo fmt --all --check
- run: cargo clippy --all-targets -- -D warnings
- run: cargo clippy --locked --all-targets -- -D warnings

test:
name: test (${{ matrix.os }})
Expand All @@ -41,9 +41,55 @@ jobs:
with:
toolchain: stable
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
- run: cargo test --all-targets
# Correctness suites only; the criterion harness runs in its own job.
- run: cargo test --locked --lib --bins --tests
# Snapshot tests use `insta::assert_snapshot!`; doctests run separately.
- run: cargo test --doc
- run: cargo test --locked --doc

reuse-differential:
name: reuse differential (6.2.0)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b9e0990d219a03df7633c93f6f005a8fecbcab22
- uses: dtolnay/rust-toolchain@67ef31d5b988238dd797d409d6f9574278e20537
with:
toolchain: stable
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
- name: Install pinned comparator in an isolated venv
run: |
python3 -m venv .venv-reuse
.venv-reuse/bin/python -m pip install 'reuse[charset-normalizer]==6.2.0'
echo "$PWD/.venv-reuse/bin" >> "$GITHUB_PATH"
# The comparator is mandatory here: absence or failure is fatal, and the
# REUSE-interop suites run against it (not skipped).
- name: Differential conformance (comparator required)
env:
LICET_REQUIRE_REUSE: "1"
run: cargo test --locked --test reuse_differential --test us5_reuse
- name: Publish comparator evidence
if: always()
run: |
{
echo "### Comparator versions"
echo '```'
.venv-reuse/bin/reuse --version 2>&1 | head -3
echo '```'
echo "### Frozen comparator requirements"
echo '```'
.venv-reuse/bin/python -m pip freeze
echo '```'
} >> "$GITHUB_STEP_SUMMARY"

bench:
name: criterion (scan)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@b9e0990d219a03df7633c93f6f005a8fecbcab22
- uses: dtolnay/rust-toolchain@67ef31d5b988238dd797d409d6f9574278e20537
with:
toolchain: stable
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
- run: cargo bench --locked --bench scan -- --quick

msrv:
name: msrv (1.89)
Expand All @@ -54,7 +100,7 @@ jobs:
with:
toolchain: 1.89.0
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
- run: cargo check --all-targets
- run: cargo check --locked --all-targets

offline-guard:
name: offline-by-default (FR-002, FR-017)
Expand All @@ -67,10 +113,13 @@ jobs:
- uses: Swatinem/rust-cache@baf1a810e98b6a3001d0d7234864ed75a17c42fb
# The binary must remain hermetic: no HTTP/TLS/socket crate may enter the tree.
# `licet` ships SPDX texts embedded, so any such dependency is a regression.
# The tree is produced to a file FIRST so a failed cargo invocation fails
# the check itself instead of grepping an empty pipe.
- name: Assert no network-capable crates
run: |
cargo tree --locked --edges normal --prefix none | sort -u > dependency-tree.txt
banned='reqwest|hyper|^ureq|curl|native-tls|openssl-sys|^rustls|^tokio '
if cargo tree --edges normal --prefix none | sort -u | grep -iE "$banned"; then
if grep -iE "$banned" dependency-tree.txt; then
echo "::error::a network-capable crate entered the dependency tree (offline-by-default violated)"
exit 1
fi
Expand Down
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## What this is

`licet` is a single-binary Rust CLI that manages SPDX/REUSE-compatible license/copyright
headers across a repository from one declarative config (`license.toml`). You declare
headers across a repository from one declarative config (`licet.toml`). You declare
intent once; `licet` projects it onto the working tree, classifies drift, and reconciles
files to match. It is **offline and hermetic by default** — SPDX license texts are
embedded in the binary at build time — and output stays compatible with the upstream
Expand Down Expand Up @@ -74,7 +74,7 @@ content (destructive on the license id by default; `--additive` keeps both), cop
`git checkout` is always a clean undo.

Supporting modules:
- `src/config/` — `license.toml` loading/validation (`schema.rs` is the raw serde model;
- `src/config/` — `licet.toml` loading/validation (`schema.rs` is the raw serde model;
`mod.rs` validates into the domain types). This is the **only** authoring surface for
intent; `REUSE.toml`/dep5 are read for interop/detection only.
- `src/comment/` — built-in comment-style registry (seeded to the REUSE-known set),
Expand All @@ -84,8 +84,8 @@ Supporting modules:
from `assets/licenses/*.txt` into `OUT_DIR/licet_licenses.rs`, `include!`d here.
- `src/report/` — `Report` JSON model (matches `contracts/report.schema.json`) and the
human renderer.
- `src/walk/cache.rs` — scan cache keyed by content+config+SPDX-version, stored in
`.git/licet-cache` so it never dirties the working tree.
- `src/walk/` — file enumeration with no scan cache: every run classifies from
current bytes (stateless), so repeat runs are identical by construction.

### Adding a bundled license

Expand All @@ -106,7 +106,7 @@ and contracts live under `specs/001-declarative-license-headers/`:
- `spec.md`, `data-model.md` — requirements and domain model (code comments cite `FR-0xx`
/ `data-model §x` tags that map back here).
- `contracts/cli.md` — CLI surface and exit-code contract.
- `contracts/config-schema.md` — full `license.toml` schema.
- `contracts/config-schema.md` — full `licet.toml` schema.
- `contracts/report.schema.json` — JSON output schema.

When changing behavior, update the spec/contracts alongside the code, and keep the
Expand Down
Loading
Loading