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
12pub fn run() -> Result<()> {
14 setup()?;
15
16 let args = Forge::parse();
17 args.global.init()?;
18
19 run_command(args)
20}
21
22pub fn setup() -> Result<()> {
24 handler::install();
25 utils::load_dotenv();
26 utils::subscriber();
27 utils::enable_paint();
28
29 Ok(())
30}
31
32pub fn run_command(args: Forge) -> Result<()> {
34 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 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}