trident_cli/
lib.rs

1use anyhow::Error;
2use clap::Parser;
3use clap::Subcommand;
4
5use fehler::throws;
6
7mod command;
8
9use crate::command::FuzzCommand;
10
11#[derive(Parser)]
12#[command(
13    name = "Trident",
14    about = "Trident is Rust based fuzzer for Solana programs written using Anchor framework."
15)]
16struct Cli {
17    #[clap(subcommand)]
18    command: Command,
19}
20
21#[derive(Subcommand)]
22enum Command {
23    #[command(about = "Show the HowTo message.")]
24    How,
25    #[command(
26        about = "Initialize Trident in the current Anchor workspace.",
27        override_usage = "\nTrident will skip initialization if Trident.toml already exists."
28    )]
29    Init {
30        #[arg(
31            short,
32            long,
33            required = false,
34            help = "Force Trident initialization. Trident dependencies will be updated based on the version of Trident CLI."
35        )]
36        force: bool,
37        #[arg(
38            short,
39            long,
40            required = false,
41            help = "Skip building the program before initializing Trident."
42        )]
43        skip_build: bool,
44        #[arg(
45            short,
46            long,
47            required = false,
48            help = "Specify the name of the program for which fuzz test will be generated.",
49            value_name = "FILE"
50        )]
51        program_name: Option<String>,
52        #[arg(
53            short,
54            long,
55            required = false,
56            help = "Name of the fuzz test to initialize.",
57            value_name = "NAME"
58        )]
59        test_name: Option<String>,
60    },
61    #[command(
62        about = "Run fuzz subcommands.",
63        override_usage = "With fuzz subcommands you can add new fuzz test \
64        template or you can run fuzz test on already initialzied one.\
65        \n\n\x1b[1m\x1b[4mEXAMPLE:\x1b[0m\
66        \n    trident add\
67        \n    trident fuzz run fuzz_0\
68        \n    trident fuzz debug \x1b[92m<FUZZ_TARGET>\x1b[0m \x1b[92m<SEED>\x1b[0m"
69    )]
70    Fuzz {
71        #[clap(subcommand)]
72        subcmd: FuzzCommand,
73    },
74    #[command(about = "Clean build target, additionally perform `anchor clean`")]
75    Clean,
76}
77
78#[throws]
79pub async fn start() {
80    let cli = Cli::parse();
81
82    match cli.command {
83        Command::How => command::howto()?,
84        Command::Fuzz { subcmd } => command::fuzz(subcmd).await?,
85        Command::Init {
86            force,
87            skip_build,
88            program_name,
89            test_name,
90        } => command::init(force, skip_build, program_name, test_name).await?,
91        Command::Clean => command::clean().await?,
92    }
93}