alias b := bench
alias t := test

# Run the full test suite across the feature combinations CI checks.
test:
    cargo test
    cargo test --features approx
    cargo test --features approx,rayon
    cargo test --release --features approx

# Fast inner-loop tests.
check:
    cargo test --features approx

# Posteriors must be bit-identical across rayon worker counts.
determinism:
    #!/usr/bin/env bash
    set -euo pipefail
    for threads in 1 2 4 8; do
        echo "== RAYON_NUM_THREADS=$threads =="
        RAYON_NUM_THREADS=$threads cargo test --release \
            --features approx,rayon --test determinism
    done

lint:
    cargo clippy --all-targets --all-features -- -D warnings

# Always nightly: rustfmt.toml uses nightly-only options.
fmt:
    cargo +nightly fmt

fmt-check:
    cargo +nightly fmt --check

# Everything CI runs.
ci: fmt-check lint test determinism

store:
    cargo bench -- --save-baseline base

bench:
    cargo bench -- --baseline base

flame:
    cargo flamegraph --root --example atp

# ---------------------------------------------------------------------------
# Release workflow
#
# Publishing goes to the private kellnr registry only: `Cargo.toml` sets
# `publish = ["kellnr"]`, so an accidental `cargo publish` to crates.io is a
# hard error rather than an irreversible mistake. The index is declared in the
# committed `.cargo/config.toml`; the token is per-user and lives in
# `~/.cargo/credentials.toml` (`cargo login --registry kellnr`).
#
#   Step 1:  just release-plan [level]   — dry run, no writes
#   Step 2:  just release [level]        — bump, changelog, tag, publish, push
#
# LEVEL is the cargo-release bump level (default `minor`). On 0.x:
#   minor -> breaking bump  (0.1.2 -> 0.2.0)   <- any public-API change
#   patch -> additive only  (0.1.2 -> 0.1.3)
#   major -> reserved for the 1.0.0 jump
#
# `release.toml` regenerates CHANGELOG.md with git-cliff in a pre-release hook
# and keeps push = false; this recipe pushes last, after publish has succeeded.
# ---------------------------------------------------------------------------

# Dry-run preview of the next release. Inspect the version bump and the
# "Publishing ..." line before running `just release`.
release-plan level="minor":
    cargo release {{level}}

# Cut a release from a clean main: gate -> bump -> tag -> publish -> push.
release level="minor":
    #!/usr/bin/env bash
    set -euo pipefail

    if [[ "$(git branch --show-current)" != "main" ]]; then
        echo "error: run 'just release' from the 'main' branch" >&2; exit 1
    fi
    if [[ -n "$(git status --porcelain)" ]]; then
        echo "error: working tree is dirty — commit or stash first" >&2; exit 1
    fi

    # cargo-release only verify-compiles the packaged crate; it does not run the
    # suite, and publishing is irreversible. Run the same gate CI does, which
    # includes the release profile where debug_assert! is compiled out.
    just ci

    cargo release {{level}} --execute --no-confirm
    git push --follow-tags
