mod build;
use std::path::PathBuf;
use anyhow::Context;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "oj", version, about = "A Rust-native build tool for React apps")]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Dev {
root: Option<PathBuf>,
#[arg(long, default_value_t = 5199)]
port: u16,
#[arg(long)]
bundle: bool,
},
Compile {
file: PathBuf,
#[arg(long)]
prod: bool,
},
Build {
root: Option<PathBuf>,
#[arg(long, default_value = "dist")]
out: PathBuf,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
match Cli::parse().command {
Command::Dev { root, port, bundle } => {
let root = root.unwrap_or_else(|| {
let playground = PathBuf::from("playground");
if playground.join("index.html").is_file() { playground } else { PathBuf::from(".") }
});
oj_server::DevServer { root, port, bundle }.run().await
}
Command::Compile { file, prod } => {
let source = std::fs::read_to_string(&file)
.with_context(|| format!("cannot read {}", file.display()))?;
let opts = if prod {
oj_compiler::CompileOptions::prod()
} else {
oj_compiler::CompileOptions::dev()
};
let output = oj_compiler::compile(&file, &source, &opts)?;
println!("{}", output.code);
Ok(())
}
Command::Build { root, out } => {
let root = root.unwrap_or_else(|| {
let playground = PathBuf::from("playground");
if playground.join("index.html").is_file() { playground } else { PathBuf::from(".") }
});
build::build(root, out).await
}
}
}