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::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::common_setup();
25 utils::subscriber();
26
27 Ok(())
28}
29
30pub fn run_command(args: Forge) -> Result<()> {
32 let context = match &args.cmd {
34 ForgeSubcommand::Test(_) => ForgeContext::Test,
35 ForgeSubcommand::Coverage(_) => ForgeContext::Coverage,
36 ForgeSubcommand::Snapshot(_) => ForgeContext::Snapshot,
37 ForgeSubcommand::Script(cmd) => {
38 if cmd.broadcast {
39 ForgeContext::ScriptBroadcast
40 } else if cmd.resume {
41 ForgeContext::ScriptResume
42 } else {
43 ForgeContext::ScriptDryRun
44 }
45 }
46 _ => ForgeContext::Unknown,
47 };
48 set_execution_context(context);
49
50 let global = &args.global;
51
52 match args.cmd {
54 ForgeSubcommand::Test(cmd) => {
55 if cmd.is_watch() {
56 global.block_on(watch::watch_test(cmd))
57 } else {
58 let silent = cmd.junit || shell::is_json();
59 let outcome = global.block_on(cmd.run())?;
60 outcome.ensure_ok(silent)
61 }
62 }
63 ForgeSubcommand::Script(cmd) => global.block_on(cmd.run_script()),
64 ForgeSubcommand::Coverage(cmd) => {
65 if cmd.is_watch() {
66 global.block_on(watch::watch_coverage(cmd))
67 } else {
68 global.block_on(cmd.run())
69 }
70 }
71 ForgeSubcommand::Bind(cmd) => cmd.run(),
72 ForgeSubcommand::Build(cmd) => {
73 if cmd.is_watch() {
74 global.block_on(watch::watch_build(cmd))
75 } else {
76 cmd.run().map(drop)
77 }
78 }
79 ForgeSubcommand::VerifyContract(args) => global.block_on(args.run()),
80 ForgeSubcommand::VerifyCheck(args) => global.block_on(args.run()),
81 ForgeSubcommand::VerifyBytecode(cmd) => global.block_on(cmd.run()),
82 ForgeSubcommand::Clone(cmd) => global.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) => global.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 global.block_on(watch::watch_gas_snapshot(cmd))
115 } else {
116 global.block_on(cmd.run())
117 }
118 }
119 ForgeSubcommand::Fmt(cmd) => {
120 if cmd.is_watch() {
121 global.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) => cmd.run(),
131 ForgeSubcommand::Doc(cmd) => {
132 if cmd.is_watch() {
133 global.block_on(watch::watch_doc(cmd))
134 } else {
135 global.block_on(cmd.run())?;
136 Ok(())
137 }
138 }
139 ForgeSubcommand::Selectors { command } => global.block_on(command.run()),
140 ForgeSubcommand::Generate(cmd) => match cmd.sub {
141 GenerateSubcommands::Test(cmd) => cmd.run(),
142 },
143 ForgeSubcommand::Compiler(cmd) => cmd.run(),
144 ForgeSubcommand::Soldeer(cmd) => global.block_on(cmd.run()),
145 ForgeSubcommand::Eip712(cmd) => cmd.run(),
146 ForgeSubcommand::BindJson(cmd) => cmd.run(),
147 ForgeSubcommand::Lint(cmd) => cmd.run(),
148 }
149}