diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed0b5ae..5c6aafa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,3 +22,12 @@ jobs: - run: cargo clippy --all-targets -- -D warnings - run: cargo test - run: cargo llvm-cov --all-features --workspace --fail-under-lines 80 + + msrv: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1 + with: + toolchain: "1.88.0" + - run: cargo check --locked --all-targets diff --git a/Cargo.toml b/Cargo.toml index 520f184..0bdd306 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,14 @@ name = "nova" version = "0.3.1" edition = "2024" +rust-version = "1.88" license = "MIT" +readme = "README.md" description = "A fast, customizable zsh prompt renderer." homepage = "https://github.com/lemtoc-labs/nova" repository = "https://github.com/lemtoc-labs/nova" +keywords = ["zsh", "prompt", "shell", "terminal", "async"] +categories = ["command-line-utilities"] [dependencies] serde = { version = "1", features = ["derive"] } @@ -27,6 +31,10 @@ tempfile = "3" name = "render" harness = false +# Do not set panic = "abort"; worker job isolation in src/worker/jobs.rs relies on catch_unwind. +[profile.release] +panic = "unwind" + # The profile that 'dist' will build with [profile.dist] inherits = "release" diff --git a/tests/manifest.rs b/tests/manifest.rs new file mode 100644 index 0000000..6bc9268 --- /dev/null +++ b/tests/manifest.rs @@ -0,0 +1,74 @@ +use toml::Value; + +fn manifest() -> Value { + toml::from_str(include_str!("../Cargo.toml")).expect("Cargo.toml should be valid TOML") +} + +#[test] +fn package_metadata_is_declared() { + let manifest = manifest(); + let package = manifest + .get("package") + .and_then(Value::as_table) + .expect("Cargo.toml should contain a package table"); + + assert_eq!( + package.get("rust-version").and_then(Value::as_str), + Some("1.88") + ); + assert_eq!( + package.get("readme").and_then(Value::as_str), + Some("README.md") + ); + + let keywords = package + .get("keywords") + .and_then(Value::as_array) + .expect("package keywords should be an array") + .iter() + .map(|keyword| keyword.as_str().expect("keywords should be strings")) + .collect::>(); + assert_eq!(keywords, ["zsh", "prompt", "shell", "terminal", "async"]); + + let categories = package + .get("categories") + .and_then(Value::as_array) + .expect("package categories should be an array") + .iter() + .map(|category| category.as_str().expect("categories should be strings")) + .collect::>(); + assert_eq!(categories, ["command-line-utilities"]); +} + +#[test] +fn release_profiles_keep_unwinding_enabled() { + let manifest = manifest(); + let profiles = manifest + .get("profile") + .and_then(Value::as_table) + .expect("Cargo.toml should contain profile tables"); + let release = profiles + .get("release") + .and_then(Value::as_table) + .expect("Cargo.toml should contain a release profile"); + + assert_eq!( + release.get("panic").and_then(Value::as_str), + Some("unwind"), + "worker job isolation relies on catch_unwind" + ); + + let dist = profiles + .get("dist") + .and_then(Value::as_table) + .expect("Cargo.toml should contain a dist profile"); + assert_eq!( + dist.get("inherits").and_then(Value::as_str), + Some("release") + ); + assert_ne!( + dist.get("panic").and_then(Value::as_str), + Some("abort"), + "the dist profile must not disable panic unwinding" + ); +}