diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 107 |
1 files changed, 96 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs index ec8784e..5ee1f9e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,11 +16,13 @@ #![doc = "Rust commands for personal web infrastructure."] pub(crate) mod archive; +pub(crate) mod chat; pub(crate) mod files; pub(crate) mod images; pub(crate) mod process; pub(crate) mod project; pub(crate) mod release; +pub(crate) mod render; use std::path::{Path, PathBuf}; use std::process::ExitCode; @@ -49,10 +51,24 @@ struct Cli { #[derive(Debug, Subcommand)] enum Action { + #[command(about = "Run experimental local chat or administer its packaged deployment")] + Chat { + #[arg(long, conflicts_with_all = ["reset_owner", "owner_fingerprint"])] + init: bool, + #[arg( + long, + value_name = "FINGERPRINT", + conflicts_with = "owner_fingerprint", + help = "Permanently clear owner registration and chat history after key loss" + )] + reset_owner: Option<String>, + #[arg(long, help = "Print the registered owner's public fingerprint")] + owner_fingerprint: bool, + }, #[command(about = "Start the local development services")] Dev { - #[arg(long, default_value_t = 8080)] - port: u16, + #[arg(long)] + port: Option<u16>, }, #[command(about = "Start or update services in the selected mode")] Up { @@ -65,6 +81,15 @@ enum Action { #[arg(long)] online: bool, }, + #[command( + about = "Render public Caddy, website, and cgit configuration without starting services" + )] + Config { + #[arg(long)] + production: bool, + #[arg(long)] + port: Option<u16>, + }, #[command(about = "Show service status")] Status, #[command(about = "Stop services while retaining data")] @@ -74,8 +99,8 @@ enum Action { destination: Option<PathBuf>, #[arg(long)] include_images: bool, - #[arg(long, default_value = archive::RECIPIENT)] - recipient: String, + #[arg(long)] + recipient: Option<String>, #[arg(long)] key: Option<PathBuf>, }, @@ -127,12 +152,23 @@ fn execute(arguments: Cli) -> Result<()> { return archive::restore(&absolute(archive)?, &absolute(destination)?); } let project = Project::discover(arguments.root.as_deref())?; + if let Action::Chat { + init, + reset_owner, + owner_fingerprint, + } = arguments.command + { + return chat(&project, init, reset_owner.as_deref(), owner_fingerprint); + } + let _operation = project.lock()?; match arguments.command { Action::Dev { port } => { let mut settings = project.settings()?; settings.mode = Mode::Local; - settings.port = port; + if let Some(selected_port) = port { + settings.port = selected_port; + } images::prepare(&project, &mut settings)?; project.up(&settings) } @@ -158,6 +194,23 @@ fn execute(arguments: Cli) -> Result<()> { images::prepare(&project, &mut settings)?; project.up(&settings) } + Action::Config { production, port } => { + let mut settings = project.settings()?; + settings.mode = if production { + Mode::Production + } else { + Mode::Local + }; + if let Some(selected_port) = port { + settings.port = selected_port; + } + stack_config::initialize_public(&project.root)?; + render::prepare(&project, &settings)?; + process::line(format_args!( + "Public configuration: {}", + render::directory(&project, &settings).display() + )) + } Action::Status => project.status(&project.settings()?), Action::Down => project.down(&project.settings()?), Action::Backup { @@ -170,11 +223,14 @@ fn execute(arguments: Cli) -> Result<()> { || Ok(project.root.join("var/exports")), |path| absolute(&path), )?; + let configuration = stack_config::Config::load(&project.root)?; + let selected_recipient = + recipient.unwrap_or(configuration.value("BACKUP_RECIPIENT")?.to_owned()); archive::backup( &project, &output, include_images, - &recipient, + &selected_recipient, key.as_deref(), ) } @@ -186,10 +242,36 @@ fn execute(arguments: Cli) -> Result<()> { Action::Activate { archive } => release::activate(&absolute(&archive)?, &project), Action::Check => check(&project), Action::Licenses => licenses(&project), + Action::Chat { .. } => anyhow::bail!("Chat action was not handled"), Action::Restore { .. } => anyhow::bail!("Restore action was not handled"), } } +fn chat( + project: &Project, + init: bool, + reset_owner: Option<&str>, + owner_fingerprint: bool, +) -> Result<()> { + if project.settings()?.mode == Mode::Production { + return chat::admin(project, init, reset_owner, owner_fingerprint); + } + let mut command = project.command("cargo")?; + command + .args(["run", "--locked", "-p", "stack-chat-server", "--", "--root"]) + .arg(&project.root); + if init { + command.arg("--init"); + } + if let Some(fingerprint) = reset_owner { + command.arg("--reset-owner").arg(fingerprint); + } + if owner_fingerprint { + command.arg("--owner-fingerprint"); + } + process::run(&mut command) +} + fn absolute(path: &Path) -> Result<PathBuf> { Ok(if path.is_absolute() { path.to_path_buf() @@ -202,6 +284,8 @@ fn licenses(project: &Project) -> Result<()> { process::run(project.command("cargo")?.args([ "about", "generate", + "--workspace", + "--locked", "about.hbs", "--output-file", "web/THIRD-PARTY-LICENSES.html", @@ -243,10 +327,11 @@ fn check(project: &Project) -> Result<()> { "--document-private-items", ]), )?; - process::run( - project - .command("cargo")? - .args(["deny", "--all-features", "check"]), - )?; + process::run(project.command("cargo")?.args([ + "deny", + "--workspace", + "--all-features", + "check", + ]))?; licenses(project) } |
