159 lines
4.5 KiB
Rust
159 lines
4.5 KiB
Rust
use clap::{Parser, Subcommand};
|
|
use std::env;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
/// PROMETEU Dispatcher (CLI).
|
|
///
|
|
/// The main entry point for the user. This binary does not implement
|
|
/// compilation or execution logic itself; instead, it acts as a smart
|
|
/// front-end that locates and dispatches commands to specialized
|
|
/// components like `prometeu-runtime` or `prometeuc`.
|
|
#[derive(Parser)]
|
|
#[command(name = "prometeu")]
|
|
#[command(about = "Dispatcher for the Prometeu ecosystem", long_about = None)]
|
|
struct Cli {
|
|
#[command(subcommand)]
|
|
command: Option<Commands>,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum Commands {
|
|
/// Executes a cartridge using the available runtime.
|
|
Run {
|
|
/// Path to the cartridge (directory or .pmc file).
|
|
cart: String,
|
|
},
|
|
/// Executes a cartridge in Assisted Mode (Debug).
|
|
/// The runtime will wait for a DevTools connection before starting.
|
|
Debug {
|
|
/// Path to the cartridge.
|
|
cart: String,
|
|
/// TCP port for the DevTools server (default: 7777).
|
|
#[arg(long, default_value_t = 7777)]
|
|
port: u16,
|
|
},
|
|
/// Compiles a source project into a cartridge (PBC).
|
|
Build {
|
|
/// Project source directory.
|
|
project_dir: String,
|
|
},
|
|
/// Packages a cartridge directory into a distributable .pmc file.
|
|
Pack {
|
|
/// Cartridge directory.
|
|
cart_dir: String,
|
|
},
|
|
/// Diagnostic commands to verify project or cartridge integrity.
|
|
Verify {
|
|
#[command(subcommand)]
|
|
target: VerifyCommands,
|
|
},
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum VerifyCommands {
|
|
/// Verifies a project
|
|
C {
|
|
/// Project directory
|
|
project_dir: String,
|
|
},
|
|
/// Verifies a cartridge or PMC file
|
|
P {
|
|
/// Path to the cartridge or PMC
|
|
cart_or_pmc: String,
|
|
},
|
|
}
|
|
|
|
fn main() {
|
|
let cli = Cli::parse();
|
|
|
|
let exe_dir = match env::current_exe() {
|
|
Ok(exe_path) => exe_path.parent().unwrap_or_else(|| Path::new(".")).to_path_buf(),
|
|
Err(e) => {
|
|
eprintln!("Error obtaining executable path: {}", e);
|
|
std::process::exit(1);
|
|
}
|
|
};
|
|
|
|
match cli.command {
|
|
Some(Commands::Run { cart }) => {
|
|
dispatch(&exe_dir, "prometeu-runtime", &["--run", &cart]);
|
|
}
|
|
Some(Commands::Debug { cart, port }) => {
|
|
dispatch(
|
|
&exe_dir,
|
|
"prometeu-runtime",
|
|
&["--debug", &cart, "--port", &port.to_string()],
|
|
);
|
|
}
|
|
Some(Commands::Build { .. }) => {
|
|
not_implemented("build", "prometeuc");
|
|
}
|
|
Some(Commands::Pack { .. }) => {
|
|
not_implemented("pack", "prometeup");
|
|
}
|
|
Some(Commands::Verify { target }) => match target {
|
|
VerifyCommands::C { .. } => not_implemented("verify c", "prometeuc"),
|
|
VerifyCommands::P { .. } => not_implemented("verify p", "prometeup"),
|
|
},
|
|
None => {
|
|
use clap::CommandFactory;
|
|
Cli::command().print_help().unwrap();
|
|
println!();
|
|
}
|
|
}
|
|
}
|
|
|
|
fn get_binary_path(dir: &Path, name: &str) -> PathBuf {
|
|
let mut path = dir.join(name);
|
|
if cfg!(target_os = "windows") {
|
|
path.set_extension("exe");
|
|
}
|
|
path
|
|
}
|
|
|
|
fn dispatch(exe_dir: &Path, bin_name: &str, args: &[&str]) {
|
|
let bin_path = get_binary_path(exe_dir, bin_name);
|
|
|
|
if !bin_path.exists() {
|
|
eprintln!(
|
|
"prometeu: command '{}' is not yet available in this distribution",
|
|
match bin_name {
|
|
"prometeu-runtime" => "run/debug",
|
|
"prometeuc" => "build/verify c",
|
|
"prometeup" => "pack/verify p",
|
|
_ => bin_name,
|
|
}
|
|
);
|
|
std::process::exit(1);
|
|
}
|
|
execute_bin(&bin_path, args);
|
|
}
|
|
|
|
fn execute_bin(bin_path: &Path, args: &[&str]) {
|
|
let status = Command::new(bin_path)
|
|
.args(args)
|
|
.stdin(std::process::Stdio::inherit())
|
|
.stdout(std::process::Stdio::inherit())
|
|
.stderr(std::process::Stdio::inherit())
|
|
.status();
|
|
|
|
match status {
|
|
Ok(status) => {
|
|
std::process::exit(status.code().unwrap_or(0));
|
|
}
|
|
Err(e) => {
|
|
eprintln!("Error executing {}: {}", bin_path.display(), e);
|
|
std::process::exit(1);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn not_implemented(cmd: &str, _bin_name: &str) {
|
|
eprintln!(
|
|
"prometeu: command '{}' is not yet available in this distribution",
|
|
cmd
|
|
);
|
|
std::process::exit(1);
|
|
}
|