ktstr 0.10.0

Test harness for Linux process schedulers
# All commands live here so they are runnable locally and on CI
# identically.  CI YAML handles only checkout, toolchain, cache, and
# tool installation; every `run:` step calls a justfile recipe.

default:
    @just --list

# Format code
fmt:
    cargo fmt --all

# Run all lints (format check + type check + clippy + rustdoc warnings)
lint:
    cargo fmt -- --check
    cargo check --workspace --all-targets
    cargo check --workspace --all-targets --features wprof
    cargo clippy --workspace --all-targets
    cargo clippy --workspace --all-targets --features wprof
    just doc-strict

# Promote every rustdoc warning to an error. RUSTDOCFLAGS reaches every
# crate in the workspace (including ktstr-macros), where `cargo doc -- -D
# warnings` would only forward the flag to the top-level invocation.
# `--document-private-items` gates the private-item intra-doc link
# and broken-html-tag warnings the project cleared in batch — without
# it a regression would silently slip past CI on a private-symbol
# rename that broke its intra-doc references.
doc-strict:
    RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --all-features --document-private-items

# Build a test kernel
kernel-build version="":
    cargo run --bin cargo-ktstr -- ktstr kernel build --skip-sha256 {{version}}

# Run tests against a kernel version. `extra-features` is passed BOTH to
# the cargo-ktstr build AND appended to the inner test feature list. The
# build pass matters for a blob-embedding feature like `wprof`: cargo-ktstr
# only embeds WPROF_BYTES — exported as KTSTR_WPROF_PATH at startup, which
# the #[ktstr_test(wprof)] tests require — when itself built with the
# feature. E.g. `just test 6.14 wprof` → cargo-ktstr built `--features
# wprof`; tests run `--features integration,wprof`.
test kernel extra-features="":
    cargo run --bin cargo-ktstr {{ if extra-features != "" { "--features " + extra-features } else { "" } }} -- ktstr test --kernel {{kernel}} -- --profile ci --features integration{{ if extra-features != "" { "," + extra-features } else { "" } }} -j $(nproc)

# Run trybuild compile_fail fixtures.
#
# Each trybuild fixture spawns its own `cargo build`, all of which
# share target/'s build lock; trybuild iterates them sequentially.
# The stale-target race surfaces only when compile_fail runs
# concurrently with OTHER tests that also touch target/ — the
# `compile-fail` nextest test-group (see .config/nextest.toml)
# reserves a single slot for the matched filter so no neighbour
# test runs alongside the compile_fail driver. The filter
# `binary(compile_fail) & test(=compile_fail)` is anchored to the
# exact driver fn so a future test whose name happens to contain
# `compile_fail` is not accidentally swept into the serial slot.
#
# Regenerate snapshots after intentional diagnostic changes:
#   TRYBUILD=overwrite just compile-fail
# Re-bless with the pinned minimal toolchain (no rust-src — see
# rust-toolchain.toml); rust-src makes rustc emit std-source snippets
# that won't match CI's minimal toolchain.
#
# KTSTR_SKIP_WPROF_BUILD stubs the wprof blob (0-byte $OUT_DIR/wprof):
# trybuild is compile-only and needs the `wprof` feature (so the
# wprof-gated compile_fail fixtures emit their diagnostics) but not a
# real blob, and the wprof/blazesym clone-build fails on the
# GitHub-hosted compile-fail runner (libblazesym_c.a not produced).
compile-fail:
    KTSTR_SKIP_WPROF_BUILD=1 cargo nextest run --profile ci --features wprof -E 'binary(compile_fail) & test(=compile_fail)' --run-ignored all

# Verify ktstr stays out of a downstream consumer's release binary.
# Drives `tests/devdep-isolation/verify.sh`, which builds a tiny
# fixture crate that takes ktstr as a [dev-dependencies] and asserts:
#   (1) `cargo build --release` of the fixture does NOT compile ktstr,
#   (2) the resulting binary contains no `ktstr::` symbols.
# Pins Cargo's dev-dep isolation contract so a future regression that
# accidentally widens ktstr's reach into prod builds fails CI loudly.
devdep-isolation:
    tests/devdep-isolation/verify.sh

# Run coverage. `extra-features` is passed to the cargo-ktstr build (so a
# blob-embedding feature like `wprof` is provisioned — see `test`) AND
# appended to the inner coverage feature list.
coverage extra-features="":
    cargo run --bin cargo-ktstr {{ if extra-features != "" { "--features " + extra-features } else { "" } }} -- ktstr coverage -- --profile ci --lcov --output-path lcov.info --features integration{{ if extra-features != "" { "," + extra-features } else { "" } }} --exclude-from-report scx-ktstr

# Show sccache statistics
sccache-stats:
    sccache --show-stats

# Show test statistics
stats:
    cargo run --bin cargo-ktstr -- ktstr stats

# Build and link-check the guide book
docs:
    mdbook build doc/guide
    mdbook test doc/guide

# Build the guide book and validate every internal link / anchor in the
# rendered HTML via lychee. `--offline` skips external HTTP fetches so
# the check is deterministic and CI-friendly (no network flakes). Run
# locally before opening a PR that touches doc/guide/src to catch
# broken cross-page anchors that mdbook-linkcheck2's pre-render check
# can miss (e.g. typo'd #fragment refs against post-render heading IDs).
# `mdbook test` also runs every doctest inside the guide so a code
# block that drifts away from the live API surfaces at PR time
# rather than after a release goes out.
link-check:
    mdbook build doc/guide
    mdbook test doc/guide
    lychee --offline --no-progress --exclude-path 'doc/guide/book/html/404.html' doc/guide/book/html

# Build API reference
api-docs:
    cargo doc --workspace --no-deps --all-features

# Build and serve the guide locally
book-serve:
    mdbook serve doc/guide --open

# Assemble the full documentation site (guide + API docs)
site: docs api-docs
    #!/usr/bin/env bash
    set -euo pipefail
    mkdir -p _site/guide _site/api
    cp -r doc/guide/book/html/* _site/guide/
    cp -r target/doc/* _site/api/
    cat > _site/index.html <<'HTML'
    <!DOCTYPE html>
    <meta http-equiv="refresh" content="0; url=guide/">
    HTML