mod args;
mod banner;
mod bench;
mod build;
mod check;
mod daemon;
mod manifold;
mod passthrough;
mod repl;
mod run;
mod script;
mod shim;
mod thrust;
mod version;
mod worker;
use anyhow::Result;
use clap::Parser;
pub use args::{Cli, Cmd, parse_mode};
pub use build::build_afterburner;
pub use manifold::{build_manifold, has_wildcard, is_implicit_open, parse_allow_list};
pub fn run() -> Result<()> {
let cli = Cli::parse();
dispatch(cli)
}
fn dispatch(mut cli: Cli) -> Result<()> {
let cmd = match cli.command.take() {
Some(c) => c,
None => {
if let Some(ref file) = cli.file {
match passthrough::detect(file) {
passthrough::Detected::KnownTarget(target) => {
return passthrough::dispatch(&mut cli, &target);
}
passthrough::Detected::PathTarget(target) if cli.eval_code.is_none() => {
return passthrough::dispatch(&mut cli, &target);
}
passthrough::Detected::Unknown(name) if cli.eval_code.is_none() => {
anyhow::bail!("burn: unknown command '{name}'");
}
_ => {}
}
}
if let Some(code) = cli.eval_code.clone() {
let mut rest = Vec::new();
if let Some(f) = cli.file.take() {
rest.push(f.to_string_lossy().into_owned());
}
rest.extend(std::mem::take(&mut cli.rest_args));
Cmd::Eval {
code,
rest_args: rest,
}
} else if let Some(file) = cli.file.clone() {
Cmd::Run {
file,
rest_args: std::mem::take(&mut cli.rest_args),
}
} else {
anyhow::bail!(
"usage: burn <command> | burn <file.js> [args…] | burn -e '<code>' [args…]\n\
run `burn --help` for subcommands"
);
}
}
};
if matches!(
cmd,
Cmd::Run { .. } | Cmd::Eval { .. } | Cmd::Thrust { .. } | Cmd::Bench { .. } | Cmd::Repl
) {
banner::maybe_show(&cli);
}
match cmd {
Cmd::Run { file, rest_args } => run::run_file(&cli, &file, &rest_args),
Cmd::Eval { code, rest_args } => run::run_source(&cli, &code, &rest_args),
Cmd::Thrust { file } => thrust::thrust_from_stdin(&cli, &file),
Cmd::Check { file } => check::check_file(&cli, &file),
Cmd::Bench {
file,
iters,
workers,
} => bench::bench(&cli, &file, iters, workers),
Cmd::Repl => repl::repl(&cli),
Cmd::Version => version::print_version(),
}
}