deflake-rs 0.1.0

cargo-deflake is a command that detects flaky tests based on what tests fail and what code has changed
use std::{num::NonZero, time::Duration};

use clap::{Parser, ValueEnum};

#[derive(Parser, ValueEnum, Default, Debug, Clone)]
pub enum Resolution {
    #[default]
    Function,
    Line,
}

#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Cli {
    // Needed to support running as cargo-deflake or cargo deflake without doing "cargo-deflake deflake ..."
    #[arg(value_parser = clap::builder::PossibleValuesParser::new(["deflake"]), default_value = "deflake")]
    command: String,

    #[arg(
        short,
        long = "commit",
        default_value = "HEAD~1",
        help = "the commit to compare changes starting from"
    )]
    pub commit: String,

    #[arg(
        long = "git-dir",
        default_value = ".",
        help = "the location of the git repository"
    )]
    pub git_dir: String,

    #[arg(
        short = 'r',
        long = "resolution",
        help = "if function or line coverage tracking should be used",
        value_enum,
        default_value_t = Resolution::Function,
    )]
    pub resolution: Resolution,

    #[arg(
        short = 'm',
        long = "mute",
        help = "paths or files to not warn when modifications made to",
        value_delimiter = ' ',
        num_args=1..
    )]
    pub ignore: Option<Vec<String>>,

    #[arg(
        long = "no-deflake",
        help = "only execute tests, don't detect flakiness",
        action
    )]
    pub no_deflake: bool,

    #[arg(long = "build-only", help = "only build tests", action)]
    pub build_only: bool,

    #[arg(
        long = "no-coverage",
        help = "don't build with coverage. Must be used with --no-deflake",
        action
    )]
    pub no_coverage: bool,

    #[arg(
        short = 'o',
        long = "output",
        help = "output tests results to this file"
    )]
    pub output: Option<String>,

    #[arg(long = "batch-size", help = "number of tests to execute concurrently")]
    pub batch_size: Option<NonZero<usize>>,

    #[arg(
        long = "timeout",
        help = "per test case timeout length (defaults to 60 seconds)",
        default_value_t = Duration::from_secs(60*10).as_secs(),
    )]
    pub timeout: u64,

    #[arg(long, value_delimiter = ',')]
    pub filter_binaries: Option<Vec<String>>,
}