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