Replace cargo audit with cargo deny for CLI dependency policy#96
Open
juangaitanv wants to merge 8 commits into
Open
Replace cargo audit with cargo deny for CLI dependency policy#96juangaitanv wants to merge 8 commits into
juangaitanv wants to merge 8 commits into
Conversation
Zero-dep bash runner (check/fix/lint/test/audit/coverage/pre-commit/ci/ post-edit/setup-hooks/suppressions/install) wrapping cargo + git. ./harness ci is the single source of truth for the strict gate: clippy -D warnings, fmt check, cargo audit, and cargo-llvm-cov tests with a --fail-under-lines floor (13% baseline, will ratchet up as more code ships with tests). GitHub Actions test.yml runs the same gate so cloud CI matches local. AGENTS.md documents the commands. CLAUDE.md and .claude/ are gitignored so personal agent configs stay local.
Reformats per rustfmt and applies clippy lints (needless_return,
collapsible_if, eq_ignore_ascii_case, double_ended_iterator_last,
print_with_newline, contains_key, needless_late_init,
useless_format/vec, borrowed_box, etc.) so ./harness ci's strict
clippy gate passes.
Adds unit tests for utils::api::{is_jwt, auth_headers,
check_for_warnings} so the coverage gate isn't sitting on 0%.
Pure refactor + tests: no behavior change.
…able Pre-commit now mirrors CI (strict clippy + fmt --check + tests) instead of running autofix, which could rewrite the working tree behind the commit. Drops the unimplemented `install` from harness docs. Extracts `should_warn_deprecated` from `check_for_warnings` so the 299 deprecation contract is covered by tests; deleting the branch now fails the suite.
Resolve conflicts from #94 (network-error retry) vs the harness branch: - src/scan.rs: keep main's retry_on_network_error wrapping around all four uploads (file/scan-chunk/scan/git-config); apply branch rustfmt. - src/utils/api.rs: union merge — keep both should_warn_deprecated + JWT/auth/deprecation tests (branch) and retry_on_network_error + backoff consts + retry tests (main). - src/authorize.rs: .err().expect() -> .expect_err() so main's new bind-error test passes the branch's strict clippy gate (-D warnings). Validated: cargo build, clippy -D warnings, fmt --check, 21 tests pass.
Replace all eprintln! diagnostics with log macros routed through env_logger, and reroute the homegrown debug() wrapper to log::debug!. User-facing stdout (println!/print!) and the terminal TUI are left untouched. - Add log + env_logger; init logger in main(), bridging CORGEA_DEBUG (env/config) and RUST_LOG to the level, message-only format so CLI errors/warnings read exactly as before. - Map eprintln! by severity: error! for genuine failures, warn! for recoverable/advisory paths (retries, fallbacks, best-effort uploads, deprecation notices), info! for the "no issues found" completion. - debug() now delegates to log::debug!, dropping the per-call Config::load() (filesystem read + TOML parse) it ran on every call. Tally: 82 error!, 18 warn!, 1 info!; 109 print(ln)! preserved.
Cover the eprintln! -> log facade migration across three layers, std-only with no new dependencies (cargo audit stays green): - Layer A: extract default_log_level(i8) out of init_logging and unit-test the ==1 (not "nonzero") debug semantics; main.rs gains its first test mod. - Layer B: behavioral tests on no-exit log paths — sarif/coverity parsers returning None (exercising the migrated error! lines) and create_zip_from_target excluding matched files (exercising the warn block). - Layer C: new tests/logging_e2e.rs drives the real binary at the no-network empty-token seam (corgea scan -> error! -> exit 1) to verify default level, message-only format, RUST_LOG/CORGEA_DEBUG filtering + precedence, exit code, and stdout/stderr separation. Coverage rises to ~23% lines (floor 13%). Also gitignore *.profraw (the env_clear'd e2e subprocess leaks default-named profraw under coverage) and document the Homebrew-Rust llvm-tools fallback for ./harness coverage.
cargo audit only checked RustSec advisories. For a binary we distribute to customers, that left licenses, sources, and bans untested. cargo deny covers all three plus advisories from the same RustSec DB — a strict superset — so consolidate to one supply-chain tool. - deny.toml: advisories (deny), licenses (permissive allowlist + option-ext MPL-2.0), sources (lock to crates.io), bans (warn on duplicates/wildcards). - harness: cmd_audit/_cmd_audit_inner -> cmd_deny/_cmd_deny_inner; ci + dispatch + help/header updated. Local stays lenient, CI stays strict. - test.yml: install cargo-deny instead of cargo-audit. - Cargo.toml: mark corgea publish=false. It ships via maturin (npm + pip), never crates.io, and its own LICENSE is LGPL-2.1; publish=false makes it "private" so deny skips license checks on our own source. - AGENTS.md: document ./harness deny. Verified: cargo deny check passes (advisories/licenses/sources/bans), negative check fails when MPL-2.0 is dropped, ./harness ci green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
cargo auditonly checked RustSec advisories. For a binary we ship to customers via npm + pip, that left three supply-chain dimensions untested:cargo denycovers all three plus advisories from the same RustSec DB — a strict superset ofcargo audit. One supply-chain tool, no redundant RustSec fetch.Changes
deny.toml(new) —version = 2schema. advisories: deny vuln/unmaintained/unsound/yanked. licenses: permissive allowlist +option-ext's file-level MPL-2.0 (transitive viadirs). bans: warn on duplicate versions / wildcards. sources: lock to crates.io (unknown-registry/unknown-git= deny).harness—cmd_audit/_cmd_audit_inner→cmd_deny/_cmd_deny_inner;cmd_ci, dispatch, header, and help updated. Local stays lenient (skips with install hint if cargo-deny absent), CI stays strict..github/workflows/test.yml— installcargo-denyinstead ofcargo-audit.Cargo.toml— markcorgeapublish = false.AGENTS.md— document./harness deny.Note: plan assumption corrected
The plan assumed the root
corgeacrate had no license and thatprivate = { ignore = true }alone would skip it. In reality:LICENSEfile is GNU LGPL-2.1, which cargo-deny reads as the crate's license (LGPL-2.1-or-later) — so it was rejected, not "no license".private.ignoreonly skips crates markedpublish = false, whichcorgeawas not.Fix: added
publish = falsetoCargo.toml. It's factually correct —corgeaships via maturin (npm + pip), nevercargo published to crates.io — and it makesprivate.ignorefire so our own LGPL source is exempt from the dependency-license rules. (This does not weaken the policy for actual dependencies.)Verification
cargo deny check→ all four checks pass (advisories / licenses / sources / bans; duplicates are warn-only)../harness deny→ green ✓../harness ci→ green ✓ (clippy strict, fmt, deny, tests + coverage, 35 passed).MPL-2.0from the allowlist →option-ext v0.2.0rejected,licenses FAILED(exit 4). The policy bites.