use std::path::PathBuf;
use clap::{Parser, Subcommand};
use crate::{
FileTree, RotoError, RotoReport, Runtime, runtime::OptCtx,
tools::print::print_highlighted,
};
#[derive(Parser)]
#[command(version, about, long_about = None)]
#[command(propagate_version = true)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Doc {
#[arg()]
path: PathBuf,
},
Check {
#[arg()]
file: PathBuf,
},
Test {
#[arg()]
file: PathBuf,
},
Run {
#[arg()]
file: PathBuf,
#[arg(default_value = "main")]
function: String,
},
Print {
#[arg()]
file: PathBuf,
},
}
pub fn cli(rt: &Runtime<impl OptCtx>) -> ! {
match cli_inner(rt) {
Ok(()) => std::process::exit(0),
Err(err) => {
eprintln!("{err}");
std::process::exit(1);
}
}
}
fn cli_inner(rt: &Runtime<impl OptCtx>) -> Result<(), RotoReport> {
let cli = Cli::parse();
match &cli.command {
Command::Doc { path } => {
rt.rt.print_documentation(path).unwrap();
}
Command::Check { file } => {
FileTree::read(file)?.parse()?.typecheck(rt)?;
println!("All ok!")
}
Command::Test { file } => {
let Some(rt) = rt.clone().try_without_ctx() else {
eprintln!("Can only run tests on a Runtime without Context");
return Err(RotoReport {
errors: vec![RotoError::TestsFailed()],
..Default::default()
});
};
let mut p = FileTree::read(file)?
.parse()?
.typecheck(&rt)?
.lower_to_mir()
.lower_to_lir()
.codegen();
if let Err(()) = p.run_tests() {
return Err(RotoReport {
errors: vec![RotoError::TestsFailed()],
..Default::default()
});
}
}
Command::Run { file, function } => {
let Some(rt) = rt.clone().try_without_ctx() else {
return Err(RotoReport {
errors: vec![RotoError::Custom("Can only run a script with a Runtime without Context".into())],
..Default::default()
});
};
let mut p = FileTree::read(file)?
.parse()?
.typecheck(&rt)?
.lower_to_mir()
.lower_to_lir()
.codegen();
let f =
p.get_function::<fn()>(function).map_err(|e| RotoReport {
errors: vec![RotoError::CouldNotRetrieveFunction(e)],
..Default::default()
})?;
f.call()
}
Command::Print { file } => {
let s = std::fs::read_to_string(file).unwrap();
print_highlighted(&s);
}
}
Ok(())
}