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::{ForgeContext, set_execution_context};
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 utils::install_crypto_provider();
25 handler::install();
26 utils::load_dotenv();
27 utils::subscriber();
28 utils::enable_paint();
29
30 Ok(())
31}
32
33pub fn run_command(args: Forge) -> Result<()> {
35 let context = match &args.cmd {
37 ForgeSubcommand::Test(_) => ForgeContext::Test,
38 ForgeSubcommand::Coverage(_) => ForgeContext::Coverage,
39 ForgeSubcommand::Snapshot(_) => ForgeContext::Snapshot,
40 ForgeSubcommand::Script(cmd) => {
41 if cmd.broadcast {
42 ForgeContext::ScriptBroadcast
43 } else if cmd.resume {
44 ForgeContext::ScriptResume
45 } else {
46 ForgeContext::ScriptDryRun
47 }
48 }
49 _ => ForgeContext::Unknown,
50 };
51 set_execution_context(context);
52
53 let global = &args.global;
54
55 match args.cmd {
57 ForgeSubcommand::Test(cmd) => {
58 if cmd.is_watch() {
59 global.block_on(watch::watch_test(cmd))
60 } else {
61 let silent = cmd.junit || shell::is_json();
62 let outcome = global.block_on(cmd.run())?;
63 outcome.ensure_ok(silent)
64 }
65 }
66 ForgeSubcommand::Script(cmd) => global.block_on(cmd.run_script()),
67 ForgeSubcommand::Coverage(cmd) => {
68 if cmd.is_watch() {
69 global.block_on(watch::watch_coverage(cmd))
70 } else {
71 global.block_on(cmd.run())
72 }
73 }
74 ForgeSubcommand::Bind(cmd) => cmd.run(),
75 ForgeSubcommand::Build(cmd) => {
76 if cmd.is_watch() {
77 global.block_on(watch::watch_build(cmd))
78 } else {
79 cmd.run().map(drop)
80 }
81 }
82 ForgeSubcommand::VerifyContract(args) => global.block_on(args.run()),
83 ForgeSubcommand::VerifyCheck(args) => global.block_on(args.run()),
84 ForgeSubcommand::VerifyBytecode(cmd) => global.block_on(cmd.run()),
85 ForgeSubcommand::Clone(cmd) => global.block_on(cmd.run()),
86 ForgeSubcommand::Cache(cmd) => match cmd.sub {
87 CacheSubcommands::Clean(cmd) => cmd.run(),
88 CacheSubcommands::Ls(cmd) => cmd.run(),
89 },
90 ForgeSubcommand::Create(cmd) => global.block_on(cmd.run()),
91 ForgeSubcommand::Update(cmd) => cmd.run(),
92 ForgeSubcommand::Install(cmd) => cmd.run(),
93 ForgeSubcommand::Remove(cmd) => cmd.run(),
94 ForgeSubcommand::Remappings(cmd) => cmd.run(),
95 ForgeSubcommand::Init(cmd) => cmd.run(),
96 ForgeSubcommand::Completions { shell } => {
97 generate(shell, &mut Forge::command(), "forge", &mut std::io::stdout());
98 Ok(())
99 }
100 ForgeSubcommand::GenerateFigSpec => {
101 clap_complete::generate(
102 clap_complete_fig::Fig,
103 &mut Forge::command(),
104 "forge",
105 &mut std::io::stdout(),
106 );
107 Ok(())
108 }
109 ForgeSubcommand::Clean { root } => {
110 let config = utils::load_config_with_root(root.as_deref())?;
111 let project = config.project()?;
112 config.cleanup(&project)?;
113 Ok(())
114 }
115 ForgeSubcommand::Snapshot(cmd) => {
116 if cmd.is_watch() {
117 global.block_on(watch::watch_gas_snapshot(cmd))
118 } else {
119 global.block_on(cmd.run())
120 }
121 }
122 ForgeSubcommand::Fmt(cmd) => {
123 if cmd.is_watch() {
124 global.block_on(watch::watch_fmt(cmd))
125 } else {
126 cmd.run()
127 }
128 }
129 ForgeSubcommand::Config(cmd) => cmd.run(),
130 ForgeSubcommand::Flatten(cmd) => cmd.run(),
131 ForgeSubcommand::Inspect(cmd) => cmd.run(),
132 ForgeSubcommand::Tree(cmd) => cmd.run(),
133 ForgeSubcommand::Geiger(cmd) => {
134 let n = cmd.run()?;
135 if n > 0 {
136 std::process::exit(n as i32);
137 }
138 Ok(())
139 }
140 ForgeSubcommand::Doc(cmd) => {
141 if cmd.is_watch() {
142 global.block_on(watch::watch_doc(cmd))
143 } else {
144 global.block_on(cmd.run())?;
145 Ok(())
146 }
147 }
148 ForgeSubcommand::Selectors { command } => global.block_on(command.run()),
149 ForgeSubcommand::Generate(cmd) => match cmd.sub {
150 GenerateSubcommands::Test(cmd) => cmd.run(),
151 },
152 ForgeSubcommand::Compiler(cmd) => cmd.run(),
153 ForgeSubcommand::Soldeer(cmd) => global.block_on(cmd.run()),
154 ForgeSubcommand::Eip712(cmd) => cmd.run(),
155 ForgeSubcommand::BindJson(cmd) => cmd.run(),
156 ForgeSubcommand::Lint(cmd) => cmd.run(),
157 }
158}