mod build_cmd;
mod global_config;
mod new_cmd;
mod project_version;
mod setup;
mod sync_plugin;
mod templates;
mod upgrade_cmd;
use std::path::{Path, PathBuf};
use clap::{Parser, Subcommand};
use rusteal_codegen::config::find_project_root;
use project_version::Scope;
#[derive(Parser)]
#[command(name = "rusteal", about = "Rusteal CLI — Rust for Unreal Engine")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
New {
name: String,
#[arg(long, default_value = ".")]
dir: PathBuf,
#[arg(long)]
runtime_path: Option<PathBuf>,
#[arg(long)]
no_build: bool,
},
Setup {
project: PathBuf,
},
Build {
project: Option<PathBuf>,
#[arg(long)]
step: Option<u8>,
#[arg(long, default_value_t = 1)]
from: u8,
},
Generate {
project: Option<PathBuf>,
},
Upgrade {
project: Option<PathBuf>,
},
SyncPlugin,
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::New { name, dir, runtime_path, no_build } => {
let engine = global_config::engine_path();
new_cmd::run_new(&new_cmd::NewOptions {
name: &name,
parent: &dir,
engine: &engine,
runtime_path: runtime_path.as_deref(),
build: !no_build,
});
}
Commands::Setup { project } => {
if project.join("Rust/Cargo.toml").exists() {
check_version(&project, Scope::Pins);
}
let engine = global_config::engine_path();
setup::run_setup(&project, &engine);
}
Commands::Build { project, step, from } => {
let root = project_root(project.as_deref());
check_version(&root, Scope::PinsAndPlugins);
let engine = global_config::engine_path();
build_cmd::run_build(&root, &engine, step, from);
}
Commands::Generate { project } => {
let root = project_root(project.as_deref());
check_version(&root, Scope::PinsAndPlugins);
rusteal_codegen::run_generate(&root);
}
Commands::Upgrade { project } => {
let root = project_root(project.as_deref());
upgrade_cmd::run_upgrade(&root);
}
Commands::SyncPlugin => {
sync_plugin::run_sync();
}
}
}
fn check_version(root: &Path, scope: Scope) {
if let Err(message) = project_version::check(root, scope) {
eprintln!("Error: {message}");
std::process::exit(1);
}
}
fn project_root(given: Option<&Path>) -> PathBuf {
let start = given
.map(Path::to_path_buf)
.unwrap_or_else(|| std::env::current_dir().expect("current directory"));
find_project_root(&start).unwrap_or_else(|| {
eprintln!(
"Error: no .uproject in {} or its parents. Pass the project directory.",
start.display()
);
std::process::exit(1);
})
}