1
//!
2
//! `xtask` is a crate that can be used to enable `make`-like commands in cargo. These commands are then implemented in Rust.
3
//!
4

            
5
#![forbid(unsafe_code)]
6

            
7
use std::error::Error;
8
use std::process::ExitCode;
9

            
10
use clap::Parser;
11
use clap::Subcommand;
12
use std::path::PathBuf;
13

            
14
mod coverage;
15
mod discover_tests;
16
mod package;
17
mod publish;
18
mod sanitizer;
19
mod tool_testing;
20

            
21
#[derive(Parser)]
22
#[command(name = "xtask")]
23
struct Cli {
24
    #[command(subcommand)]
25
    command: Commands,
26
}
27

            
28
#[derive(Subcommand)]
29
enum Commands {
30
    /// Generates a code coverage report using grcov.
31
    Coverage {
32
        #[clap(trailing_var_arg = true)]
33
        args: Vec<String>,
34
    },
35
    /// Runs the given cargo command with AddressSanitizer enabled.
36
    AddressSanitizer {
37
        #[clap(trailing_var_arg = true)]
38
        args: Vec<String>,
39
    },
40
    /// Runs the given cargo command with ThreadSanitizer enabled.
41
    ThreadSanitizer {
42
        #[clap(trailing_var_arg = true)]
43
        args: Vec<String>,
44
    },
45
    /// Discovers tests from the examples folder, and prints them as a `#[test_case]` annotation.
46
    DiscoverTests,
47
    /// Builds and packages the binaries for release.
48
    Package,
49
    /// Publishes the crates to crates.io.
50
    Publish,
51
    TestTools {
52
        directory: PathBuf,
53
    },
54
}
55

            
56
fn main() -> Result<ExitCode, Box<dyn Error>> {
57
    let cli = Cli::parse();
58

            
59
    match cli.command {
60
        Commands::Coverage { args } => coverage::coverage(args)?,
61
        Commands::AddressSanitizer { args } => sanitizer::address_sanitizer(args)?,
62
        Commands::ThreadSanitizer { args } => sanitizer::thread_sanitizer(args)?,
63
        Commands::DiscoverTests => discover_tests::discover_tests()?,
64
        Commands::Package => package::package()?,
65
        Commands::Publish => publish::publish_crates(),
66
        Commands::TestTools { directory } => tool_testing::test_tools(directory.as_path())?,
67
    }
68

            
69
    Ok(ExitCode::SUCCESS)
70
}