use self::commands::{
addr2line, build, check, clean, completions, contract_id, init, new, parse_bytecode, plugins,
predicate_root, template, test, update,
};
use addr2line::Command as Addr2LineCommand;
use anyhow::anyhow;
pub use build::Command as BuildCommand;
pub use check::Command as CheckCommand;
use clap::{Parser, Subcommand};
pub use clean::Command as CleanCommand;
pub use completions::Command as CompletionsCommand;
pub(crate) use contract_id::Command as ContractIdCommand;
use forc_tracing::{init_tracing_subscriber, TracingSubscriberOptions};
use forc_util::ForcResult;
pub use init::Command as InitCommand;
pub use new::Command as NewCommand;
use parse_bytecode::Command as ParseBytecodeCommand;
pub use plugins::Command as PluginsCommand;
pub(crate) use predicate_root::Command as PredicateRootCommand;
use std::str::FromStr;
pub use template::Command as TemplateCommand;
pub use test::Command as TestCommand;
use tracing::metadata::LevelFilter;
pub use update::Command as UpdateCommand;
mod commands;
mod plugin;
pub mod shared;
fn help() -> &'static str {
Box::leak(
format!(
"Examples:\n{}{}{}{}",
plugins::examples(),
test::examples(),
build::examples(),
check::examples(),
)
.trim_end()
.to_string()
.into_boxed_str(),
)
}
#[derive(Debug, Parser)]
#[clap(name = "forc", about = "Fuel Orchestrator", version, after_long_help = help())]
struct Opt {
#[clap(subcommand)]
command: Forc,
#[clap(short, long, action = clap::ArgAction::Count, global = true)]
verbose: u8,
#[clap(short, long, global = true)]
silent: bool,
#[clap(short='L', long, global = true, value_parser = LevelFilter::from_str)]
log_level: Option<LevelFilter>,
}
#[derive(Subcommand, Debug)]
enum Forc {
#[clap(name = "addr2line")]
Addr2Line(Addr2LineCommand),
#[clap(visible_alias = "b")]
Build(BuildCommand),
Check(CheckCommand),
Clean(CleanCommand),
Completions(CompletionsCommand),
New(NewCommand),
Init(InitCommand),
ParseBytecode(ParseBytecodeCommand),
#[clap(visible_alias = "t")]
Test(TestCommand),
Update(UpdateCommand),
Plugins(PluginsCommand),
Template(TemplateCommand),
ContractId(ContractIdCommand),
PredicateRoot(PredicateRootCommand),
#[clap(external_subcommand)]
Plugin(Vec<String>),
}
impl Forc {
#[allow(dead_code)]
pub fn possible_values() -> Vec<&'static str> {
vec![
"addr2line",
"build",
"check",
"clean",
"completions",
"init",
"new",
"parse-bytecode",
"plugins",
"test",
"update",
"template",
"contract-id",
"predicate-root",
]
}
}
pub async fn run_cli() -> ForcResult<()> {
let opt = Opt::parse();
let tracing_options = TracingSubscriberOptions {
verbosity: Some(opt.verbose),
silent: Some(opt.silent),
log_level: opt.log_level,
..Default::default()
};
init_tracing_subscriber(tracing_options);
match opt.command {
Forc::Addr2Line(command) => addr2line::exec(command),
Forc::Build(command) => build::exec(command),
Forc::Check(command) => check::exec(command),
Forc::Clean(command) => clean::exec(command),
Forc::Completions(command) => completions::exec(command),
Forc::Init(command) => init::exec(command),
Forc::New(command) => new::exec(command),
Forc::ParseBytecode(command) => parse_bytecode::exec(command),
Forc::Plugins(command) => plugins::exec(command),
Forc::Test(command) => test::exec(command),
Forc::Update(command) => update::exec(command),
Forc::Template(command) => template::exec(command),
Forc::ContractId(command) => contract_id::exec(command),
Forc::PredicateRoot(command) => predicate_root::exec(command),
Forc::Plugin(args) => {
let output = plugin::execute_external_subcommand(&args)?;
let code = output
.status
.code()
.ok_or_else(|| anyhow!("plugin exit status unknown"))?;
std::process::exit(code);
}
}
}