Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,18 @@ jobs:
uses: taiki-e/install-action@cargo-llvm-cov

- name: Generate lcov coverage
run: cargo llvm-cov --workspace --lcov --output-path lcov.info
# Ratchet, not the house 100% target. The uncovered remainder is the
# code that only runs against a real TTY: terminal.rs's crossterm
# impl, runtime.rs's run_interactive wiring, and lib.rs's call into
# it. None of it can execute under `cargo test`, so the gate holds the
# line where it actually is instead of asserting a number the suite
# cannot reach. Measured 96.40% lines / 83.24% functions, and stable
# to the digit across repeat runs, so these floors trip on a real
# regression rather than on noise. Raise them when coverage rises;
# never lower them.
run: >-
cargo llvm-cov --workspace --lcov --output-path lcov.info
--fail-under-lines 96 --fail-under-functions 83

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v7
Expand Down
14 changes: 13 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,24 @@ pub enum CliCommand {
}

/// Parse CLI arguments from an iterator (including argv0 as first item).
///
/// This is a thin generic shim so callers can pass `std::env::Args`, a
/// `Vec<String>`, or a literal array. All parsing lives in the non-generic
/// `parse_argv`: a generic body is monomorphized once per argument type, and
/// every copy carries its own counters, so the error paths that a given
/// call site never takes would each report as uncovered even though the
/// source line is exercised elsewhere. Keeping the body non-generic means the
/// logic is compiled, and counted, exactly once.
pub fn parse_args<I>(args: I) -> Result<CliCommand>
where
I: IntoIterator,
I::Item: Into<String>,
{
let mut args: Vec<String> = args.into_iter().map(Into::into).collect();
parse_argv(args.into_iter().map(Into::into).collect())
}

/// Parse an owned argv vector (including argv0 as first item).
fn parse_argv(mut args: Vec<String>) -> Result<CliCommand> {
if !args.is_empty() {
args.remove(0);
}
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod model;
pub mod process;
pub mod runtime;
pub mod signal;
pub mod terminal;
pub mod tree;
pub mod ui;

Expand Down
Loading
Loading