[package]
name = "kache"
version = "0.7.0"
edition = "2024"
description = "Zero-copy, content-addressed build cache for Rust, C/C++ and more. No copies, no wasted disk — just hardlinks locally and S3 for sharing."
license = "Apache-2.0"
repository = "https://github.com/kunobi-ninja/kache"
homepage = "https://kunobi.ninja/docs/kache"
keywords = ["build-cache", "rustc-wrapper", "blake3", "cargo"]
categories = ["development-tools::build-utils", "caching"]
rust-version = "1.95"

[workspace]
members = ["crates/kache-core", "crates/kache-e2e", "crates/kache-service"]
# scenarios/e2e-*/source and test-projects/* are not listed: each declares its own empty
# `[workspace]` so cargo treats them as standalone, which is what the
# e2e harness (and the integration tests) need to drive them as
# realistic standalone consumers of kache.
resolver = "3"

[dependencies]
blake3 = "1"
# TLS provider: `ring`, NOT aws-lc-rs. We avoid `aws-lc-sys` entirely
# because its cmake/NASM C build hangs when cross-compiling to
# `aarch64-pc-windows-msvc` under cargo-xwin; `ring` ships prebuilt asm
# for that target and cross-compiles cleanly.
#
# `aws-lc-sys` enters ONLY as the rustls crypto provider — `sigv4a` uses
# pure-Rust `p256`/`crypto-bigint`, not aws-lc. To force `ring`, every
# rustls consumer must opt out of aws-lc AND avoid re-enabling it via
# additive features:
#   - aws-sdk-s3: drop `default-https-client` (it hard-wires
#     `aws-smithy-http-client/rustls-aws-lc` on aws-smithy-runtime).
#     We inject our own ring-backed Smithy client in `src/remote.rs`.
#   - aws-config: `default-features = false` for the same reason — its
#     default pulls `default-https-client`. We inject the client there too.
#   - aws-smithy-http-client: `rustls-ring` (modern rustls 0.23 + ring).
#     NOT `legacy-rustls-ring`, which pins vulnerable rustls 0.21
#     (RUSTSEC-2026-0098/0099/0104).
#   - reqwest: `rustls-no-provider` + a process-default ring CryptoProvider
#     installed at startup (see `src/main.rs`).
aws-sdk-s3 = { version = "1", default-features = false, features = ["sigv4a", "http-1x", "rt-tokio"] }
aws-config = { version = "1", default-features = false, features = ["rt-tokio", "credentials-process", "sso"] }
aws-smithy-http-client = { version = "1", features = ["rustls-ring"] }
# Direct dep so we can install ring as the process-wide rustls crypto
# provider (reqwest uses `rustls-no-provider`, so one must be installed).
rustls = { version = "0.23", default-features = false, features = ["ring"] }
kache-core = { version = "0.7.0", path = "crates/kache-core", default-features = false, features = ["planning"] }
async-trait = "0.1"
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros", "process", "fs", "io-util", "net", "time", "signal", "sync"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
toml = "1"
clap = { version = "4", features = ["derive"] }
rusqlite = { version = "0.39", features = ["bundled"] }
ratatui = "0.30"
crossterm = "0.29"
filetime = "0.2"
anyhow = "1"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt", "registry"] }
zstd = "0.13"
bytesize = "2"
chrono = { version = "0.4", features = ["serde"] }
dirs = "6"
tar = "0.4"
futures = "0.3"
glob = "0.3"
guppy = "0.17"
libc = "0.2"
tempfile = "3"
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-no-provider"] }
interprocess = { version = "2.4.2", features = ["tokio"] }
unicode-normalization = "0.1"
# Used by `src/compiler/flags.rs` (the cc / future Swift / future MSVC
# flag classifier). The `regex` crate is linear-time by construction
# (no backtracking, no lookarounds) — matters because the wrapper runs
# the classifier on every cc compile argument; bounded cost is a design
# requirement.
regex = { version = "1", default-features = false, features = ["std", "perf"] }

[target.'cfg(windows)'.dependencies]
# `pure` drops blake3's C SIMD (`c/blake3_neon.c` / SSE intrinsics), whose
# arm64 NEON path doesn't cross-compile under cargo-xwin's clang + MSVC
# sysroot. Windows-only so native/Linux/macOS keep the fast C SIMD backend.
blake3 = { version = "1", features = ["pure"] }
windows-sys = { version = "0.61", features = [
    "Win32_Foundation",
    "Win32_System_Threading",
    "Win32_Storage_FileSystem",
] }

[dev-dependencies]
assert_cmd = "2"
predicates = "3"
serde_json = "1"
# Wire-level mock S3 server (WireMockServer) for testing the remote/S3 code
# paths without network — see src/remote.rs and src/remote_layout.rs tests.
# `test-util` is dev-only; the release build never enables it.
aws-smithy-http-client = { version = "1", features = ["test-util", "wire-mock"] }
bytes = "1"

# `{ archive-suffix }` resolves from each target's pkg-fmt (".tar.gz" for
# tgz, ".zip" for zip) — never hardcode the extension here: the release
# workflow (_release-rust.yml) packages Windows targets as .zip and
# everything else as .tar.gz (see #311). Guarded by
# tests/binstall_metadata_test.rs.
[package.metadata.binstall]
pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }{ archive-suffix }"
pkg-fmt = "tgz"

[package.metadata.binstall.overrides.x86_64-pc-windows-msvc]
pkg-fmt = "zip"

[package.metadata.binstall.overrides.aarch64-pc-windows-msvc]
pkg-fmt = "zip"

# Debian packaging (cargo-deb). Read by the _workflows build_deb step to
# produce kache_<version>_{amd64,arm64}.deb, which package-publish.yml then
# pushes into the apt repo on R2. cargo-deb reads this regardless of the
# --target passed, so the same config drives both amd64 and arm64 builds.
[package.metadata.deb]
maintainer = "Kunobi Ninja <feedback@kunobi.ninja>"
copyright = "2026, Zondax AG"
license-file = ["LICENSE", "0"]
extended-description = """\
kache is a zero-copy, content-addressed build cache for Rust, C/C++ and more. \
It avoids file \
copies and wasted disk by hardlinking artifacts locally and sharing them \
via S3-compatible object storage."""
section = "utils"
priority = "optional"
# CRITICAL: empty depends. kache is built as a static musl binary, so it has
# no shared-library runtime dependencies. An auto-resolved or non-empty
# `depends` would pin glibc and break install on musl/minimal systems.
depends = ""
assets = [
    ["target/release/kache", "usr/bin/kache", "755"],
    ["README.md", "usr/share/doc/kache/README", "644"],
]

[profile.release]
lto = "fat"
codegen-units = 1
strip = "symbols"

[lints.rust]
warnings = "deny"

[lints.clippy]
permissions_set_readonly_false = "allow"
too_many_arguments = "allow"
