Nilton Constantino 8bedb69ca4
add gist
2026-01-19 08:19:56 +00:00

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);
}