forge/
args.rs

1use crate::{
2    cmd::{cache::CacheSubcommands, generate::GenerateSubcommands, watch},
3    opts::{Forge, ForgeSubcommand},
4};
5use clap::{CommandFactory, Parser};
6use clap_complete::generate;
7use eyre::Result;
8use foundry_cli::{handler, utils};
9use foundry_common::shell;
10use foundry_evm::inspectors::cheatcodes::{set_execution_context, ForgeContext};
11
12/// Run the `forge` command line interface.
13pub fn run() -> Result<()> {
14    setup()?;
15
16    let args = Forge::parse();
17    args.global.init()?;
18
19    run_command(args)
20}
21
22/// Setup the global logger and other utilities.
23pub fn setup() -> Result<()> {
24    handler::install();
25    utils::load_dotenv();
26    utils::subscriber();
27    utils::enable_paint();
28
29    Ok(())
30}
31
32/// Run the subcommand.
33pub fn run_command(args: Forge) -> Result<()> {
34    // Set the execution context based on the subcommand.
35    let context = match &args.cmd {
36        ForgeSubcommand::Test(_) => ForgeContext::Test,
37        ForgeSubcommand::Coverage(_) => ForgeContext::Coverage,
38        ForgeSubcommand::Snapshot(_) => ForgeContext::Snapshot,
39        ForgeSubcommand::Script(cmd) => {
40            if cmd.broadcast {
41                ForgeContext::ScriptBroadcast
42            } else if cmd.resume {
43                ForgeContext::ScriptResume
44            } else {
45                ForgeContext::ScriptDryRun
46            }
47        }
48        _ => ForgeContext::Unknown,
49    };
50    set_execution_context(context);
51
52    // Run the subcommand.
53    match args.cmd {
54        ForgeSubcommand::Test(cmd) => {
55            if cmd.is_watch() {
56                utils::block_on(watch::watch_test(cmd))
57            } else {
58                let silent = cmd.junit || shell::is_json();
59                let outcome = utils::block_on(cmd.run())?;
60                outcome.ensure_ok(silent)
61            }
62        }
63        ForgeSubcommand::Script(cmd) => utils::block_on(cmd.run_script()),
64        ForgeSubcommand::Coverage(cmd) => {
65            if cmd.is_watch() {
66                utils::block_on(watch::watch_coverage(cmd))
67            } else {
68                utils::block_on(cmd.run())
69            }
70        }
71        ForgeSubcommand::Bind(cmd) => cmd.run(),
72        ForgeSubcommand::Build(cmd) => {
73            if cmd.is_watch() {
74                utils::block_on(watch::watch_build(cmd))
75            } else {
76                cmd.run().map(drop)
77            }
78        }
79        ForgeSubcommand::VerifyContract(args) => utils::block_on(args.run()),
80        ForgeSubcommand::VerifyCheck(args) => utils::block_on(args.run()),
81        ForgeSubcommand::VerifyBytecode(cmd) => utils::block_on(cmd.run()),
82        ForgeSubcommand::Clone(cmd) => utils::block_on(cmd.run()),
83        ForgeSubcommand::Cache(cmd) => match cmd.sub {
84            CacheSubcommands::Clean(cmd) => cmd.run(),
85            CacheSubcommands::Ls(cmd) => cmd.run(),
86        },
87        ForgeSubcommand::Create(cmd) => utils::block_on(cmd.run()),
88        ForgeSubcommand::Update(cmd) => cmd.run(),
89        ForgeSubcommand::Install(cmd) => cmd.run(),
90        ForgeSubcommand::Remove(cmd) => cmd.run(),
91        ForgeSubcommand::Remappings(cmd) => cmd.run(),
92        ForgeSubcommand::Init(cmd) => cmd.run(),
93        ForgeSubcommand::Completions { shell } => {
94            generate(shell, &mut Forge::command(), "forge", &mut std::io::stdout());
95            Ok(())
96        }
97        ForgeSubcommand::GenerateFigSpec => {
98            clap_complete::generate(
99                clap_complete_fig::Fig,
100                &mut Forge::command(),
101                "forge",
102                &mut std::io::stdout(),
103            );
104            Ok(())
105        }
106        ForgeSubcommand::Clean { root } => {
107            let config = utils::load_config_with_root(root.as_deref())?;
108            let project = config.project()?;
109            config.cleanup(&project)?;
110            Ok(())
111        }
112        ForgeSubcommand::Snapshot(cmd) => {
113            if cmd.is_watch() {
114                utils::block_on(watch::watch_gas_snapshot(cmd))
115            } else {
116                utils::block_on(cmd.run())
117            }
118        }
119        ForgeSubcommand::Fmt(cmd) => {
120            if cmd.is_watch() {
121                utils::block_on(watch::watch_fmt(cmd))
122            } else {
123                cmd.run()
124            }
125        }
126        ForgeSubcommand::Config(cmd) => cmd.run(),
127        ForgeSubcommand::Flatten(cmd) => cmd.run(),
128        ForgeSubcommand::Inspect(cmd) => cmd.run(),
129        ForgeSubcommand::Tree(cmd) => cmd.run(),
130        ForgeSubcommand::Geiger(cmd) => {
131            let n = cmd.run()?;
132            if n > 0 {
133                std::process::exit(n as i32);
134            }
135            Ok(())
136        }
137        ForgeSubcommand::Doc(cmd) => {
138            if cmd.is_watch() {
139                utils::block_on(watch::watch_doc(cmd))
140            } else {
141                utils::block_on(cmd.run())?;
142                Ok(())
143            }
144        }
145        ForgeSubcommand::Selectors { command } => utils::block_on(command.run()),
146        ForgeSubcommand::Generate(cmd) => match cmd.sub {
147            GenerateSubcommands::Test(cmd) => cmd.run(),
148        },
149        ForgeSubcommand::Compiler(cmd) => cmd.run(),
150        ForgeSubcommand::Soldeer(cmd) => utils::block_on(cmd.run()),
151        ForgeSubcommand::Eip712(cmd) => cmd.run(),
152        ForgeSubcommand::BindJson(cmd) => cmd.run(),
153    }
154}