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 foundry_cli::opts::GlobalArgs::check_markdown_help::<Forge>();
17
18 let args = Forge::parse();
19 args.global.init()?;
20
21 run_command(args)
22}
23
24pub fn setup() -> Result<()> {
26 utils::common_setup();
27 utils::subscriber();
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 let global = &args.global;
53
54 match args.cmd {
56 ForgeSubcommand::Test(cmd) => {
57 if cmd.is_watch() {
58 global.block_on(watch::watch_test(cmd))
59 } else {
60 let silent = cmd.junit || shell::is_json();
61 let outcome = global.block_on(cmd.run())?;
62 outcome.ensure_ok(silent)
63 }
64 }
65 ForgeSubcommand::Script(cmd) => global.block_on(cmd.run_script()),
66 ForgeSubcommand::Coverage(cmd) => {
67 if cmd.is_watch() {
68 global.block_on(watch::watch_coverage(cmd))
69 } else {
70 global.block_on(cmd.run())
71 }
72 }
73 ForgeSubcommand::Bind(cmd) => cmd.run(),
74 ForgeSubcommand::Build(cmd) => {
75 if cmd.is_watch() {
76 global.block_on(watch::watch_build(cmd))
77 } else {
78 global.block_on(cmd.run()).map(drop)
79 }
80 }
81 ForgeSubcommand::VerifyContract(args) => global.block_on(args.run()),
82 ForgeSubcommand::VerifyCheck(args) => global.block_on(args.run()),
83 ForgeSubcommand::VerifyBytecode(cmd) => global.block_on(cmd.run()),
84 ForgeSubcommand::Clone(cmd) => global.block_on(cmd.run()),
85 ForgeSubcommand::Cache(cmd) => match cmd.sub {
86 CacheSubcommands::Clean(cmd) => cmd.run(),
87 CacheSubcommands::Ls(cmd) => cmd.run(),
88 },
89 ForgeSubcommand::Create(cmd) => global.block_on(cmd.run()),
90 ForgeSubcommand::Update(cmd) => cmd.run(),
91 ForgeSubcommand::Install(cmd) => global.block_on(cmd.run()),
92 ForgeSubcommand::Remove(cmd) => cmd.run(),
93 ForgeSubcommand::Remappings(cmd) => cmd.run(),
94 ForgeSubcommand::Init(cmd) => global.block_on(cmd.run()),
95 ForgeSubcommand::Completions { shell } => {
96 generate(shell, &mut Forge::command(), "forge", &mut std::io::stdout());
97 Ok(())
98 }
99 ForgeSubcommand::Clean { root } => {
100 let config = utils::load_config_with_root(root.as_deref())?;
101 let project = config.project()?;
102 config.cleanup(&project)?;
103 Ok(())
104 }
105 ForgeSubcommand::Snapshot(cmd) => {
106 if cmd.is_watch() {
107 global.block_on(watch::watch_gas_snapshot(cmd))
108 } else {
109 global.block_on(cmd.run())
110 }
111 }
112 ForgeSubcommand::Fmt(cmd) => {
113 if cmd.is_watch() {
114 global.block_on(watch::watch_fmt(cmd))
115 } else {
116 cmd.run()
117 }
118 }
119 ForgeSubcommand::Config(cmd) => cmd.run(),
120 ForgeSubcommand::Flatten(cmd) => cmd.run(),
121 ForgeSubcommand::Inspect(cmd) => cmd.run(),
122 ForgeSubcommand::Tree(cmd) => cmd.run(),
123 ForgeSubcommand::Geiger(cmd) => cmd.run(),
124 ForgeSubcommand::Doc(cmd) => {
125 if cmd.is_watch() {
126 global.block_on(watch::watch_doc(cmd))
127 } else {
128 global.block_on(cmd.run())?;
129 Ok(())
130 }
131 }
132 ForgeSubcommand::Selectors { command } => global.block_on(command.run()),
133 ForgeSubcommand::Generate(cmd) => match cmd.sub {
134 GenerateSubcommands::Test(cmd) => cmd.run(),
135 },
136 ForgeSubcommand::Compiler(cmd) => cmd.run(),
137 ForgeSubcommand::Soldeer(cmd) => global.block_on(cmd.run()),
138 ForgeSubcommand::Eip712(cmd) => cmd.run(),
139 ForgeSubcommand::BindJson(cmd) => cmd.run(),
140 ForgeSubcommand::Lint(cmd) => cmd.run(),
141 }
142}