zachery.lol/crates/cli/src/main.rs

180 lines
5.5 KiB
Rust
Raw Normal View History

2025-11-17 22:21:49 +00:00
use clap::{Parser, Subcommand};
2025-11-18 02:22:05 +00:00
use std::{os::unix::process::ExitStatusExt, process::{Command, ExitStatus}};
const WEB_BUILD_DIR: &str = "web-build";
2025-11-17 22:21:49 +00:00
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
/// Builds the website and server, including wasm files
Build,
2025-11-18 02:22:05 +00:00
/// Runs the server locally
Start {
/// Whether to build again or not
#[arg(long)]
rebuild: bool,
},
2025-11-17 22:21:49 +00:00
/// Generates new encryption keys
GenKeys {
/// How many keypairs to generate
#[arg(short, long, default_value = "100")]
2025-11-18 02:22:05 +00:00
number: usize,
/// Directory to put the generated secret key files
#[arg(short, long, default_value = ".local/secrets.json")]
sk_out_dir: String,
/// Directory to put the generated pubklic key pool
#[arg(long, default_value = "target/public_keys.json")]
pk_out_dir: String,
2025-11-17 22:21:49 +00:00
},
/// Reads fetched messages
ReadMessages {
2025-11-18 02:22:05 +00:00
/// Source file path
#[arg(short, long, default_value = ".local/messages")]
source: String,
2025-11-17 22:21:49 +00:00
2025-11-18 02:22:05 +00:00
/// Optional output file path for decoded messages
/// Default: stdout
2025-11-17 22:21:49 +00:00
#[arg(short, long)]
out_dir: Option<String>,
},
}
fn main() {
let cli = Cli::parse();
match &cli.command {
Commands::Build => {
println!("Executing build command...");
build();
}
2025-11-18 02:22:05 +00:00
Commands::Start { rebuild } => {
println!("Starting server...");
if *rebuild {
println!("Rebuilding web pages...");
build();
} // Change the current working directory of the running Rust program
println!("Changing directory to {WEB_BUILD_DIR}...");
let cd_result = std::env::set_current_dir(WEB_BUILD_DIR);
// Use the existing helper to check the result
handle_command_status(
cd_result.map(|_| std::process::ExitStatus::from_raw(0)),
"cd build dir",
);
println!("Running server executable...");
// Now run the server executable from within the new current directory
handle_command_status(Command::new("./server").status(), "run server");
2025-11-17 22:21:49 +00:00
}
2025-11-18 02:22:05 +00:00
Commands::GenKeys {
number,
sk_out_dir,
pk_out_dir,
} => {
2025-11-17 22:21:49 +00:00
println!("Executing gen-keys command...");
2025-11-18 02:22:05 +00:00
message_tools::gen_keys::generate_keys_to_file(pk_out_dir, sk_out_dir, *number)
.expect("write key files");
2025-11-17 22:21:49 +00:00
}
2025-11-18 02:22:05 +00:00
Commands::ReadMessages { .. } => {
2025-11-17 22:21:49 +00:00
println!("Executing read-messages command...");
// Add your message reading logic here
}
}
}
2025-11-18 02:22:05 +00:00
// A helper function to process the Result<ExitStatus, io::Error>
fn handle_command_status(status_result: std::io::Result<ExitStatus>, command_name: &str) {
match status_result {
Ok(exit_status) => {
if !exit_status.success() {
eprintln!(
"\nCommand '{}' failed with exit code: {:?}",
command_name,
exit_status.code()
);
std::process::exit(exit_status.code().unwrap_or(1));
}
}
Err(e) => {
eprintln!("\nFailed to execute command '{}': {}", command_name, e);
std::process::exit(1); // Exit with an error code
}
}
}
2025-11-17 22:21:49 +00:00
fn build() {
2025-11-18 02:22:05 +00:00
println!("Building wasm package...");
// build the wasm package
2025-11-17 22:21:49 +00:00
let status = Command::new("wasm-pack")
.arg("build")
.arg("--out-dir")
.arg("../../routes/contact/pkg")
.arg("crates/message-tools")
.arg("--target")
.arg("no-modules")
.status();
2025-11-18 02:22:05 +00:00
handle_command_status(status, "wasm-pack build");
2025-11-17 22:21:49 +00:00
2025-11-18 02:22:05 +00:00
println!("Building server executable...");
// build the server executable
let status = Command::new("cargo")
.arg("build")
.arg("--release")
.args(["-p", "server"])
.args(["--target", "x86_64-unknown-linux-musl"])
.status();
handle_command_status(status, "cargo build server");
let server_bin = "target/x86_64-unknown-linux-musl/release/server";
println!("Creating build directory...");
// make webpage build directory if it doesn't already exist
let status = Command::new("mkdir").args(["-p", WEB_BUILD_DIR]).status();
handle_command_status(status, "mkdir web-build");
println!("Copying files...");
// copy relevant files
let status = Command::new("cp")
.args(["-R", "routes"])
.arg(format!("{WEB_BUILD_DIR}/routes"))
.status();
handle_command_status(status, "cp routes");
let status = Command::new("cp")
.arg(server_bin)
.arg(format!("{WEB_BUILD_DIR}"))
.status();
handle_command_status(status, "cp server bin");
let pubkey_file = "target/public_keys.json";
if !std::path::Path::new(pubkey_file).exists() {
panic!("No public key file. Please generate keys first.");
2025-11-17 22:21:49 +00:00
}
2025-11-18 02:22:05 +00:00
let status = Command::new("mkdir")
.args(["-p", &format!("{WEB_BUILD_DIR}/pubkeys")])
.status();
handle_command_status(status, "mkdir web-build");
let status = Command::new("cp")
.arg("target/public_keys.json")
.arg(format!("{WEB_BUILD_DIR}/pubkeys/"))
.status();
handle_command_status(status, "cp pubkeys");
println!("\nBuild successful!");
2025-11-17 22:21:49 +00:00
}