From 9e0bf8c8c45ce42e7e48e2d1922d400728249e4d Mon Sep 17 00:00:00 2001 From: Leonard Steppy Date: Wed, 11 Dec 2024 14:13:32 +0100 Subject: [PATCH] Refactor cli --- src/main.rs | 98 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1a0433e..214e672 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,34 +1,57 @@ -use clap::Parser; +use clap::builder::Str; +use clap::{Parser, Subcommand, ValueEnum}; use std::env; use std::path::PathBuf; -const SERVERS_ENV_VAR: &str = "PLUGIN_UPLOADER_SERVERS"; +const SERVERS_ENV_VAR: &str = "MSSH_SERVERS"; -//TODO add upload and command subcommands - -/// Uploads a plugin to one or multiple configured servers. +/// Uploads a file or executes a command on multiple configured servers /// -/// By default, older versions of the plugin will be deleted. +/// Servers must either be configured via environment variable or denote their server directory with +/// a double colon: crea:home/crea. /// -/// --- Server configuration --- +/// --- Configuration via environment variable --- /// -/// Servers can be configured via environment variable `PLUGIN_UPLOADER_SERVERS`. -/// The value should be a string which contains the ssh name and the server directory path. -/// -/// --- Example --- -/// -/// export PLUGIN_UPLOADER_SERVERS="crea:server/creative2,city:city2,lobby:" +/// Use MSSH_SERVERS="crea:home/crea,sky:sky,lobby:,city:city2" to configure servers. #[derive(Parser, Debug)] #[command(version, about, long_about)] struct Args { - /// The plugin file to upload - plugin: PathBuf, - /// The ssh names of the servers to upload to + /// The action to perform + #[command(subcommand)] + command: Command, + /// The ssh names and optionally home directories of the servers to perform the action on #[arg(num_args = 1..)] - servers: Vec, - /// Whether not to delete, but to rename the previous plugin - #[arg(short, long, value_name = "archive", default_value = "false", default_missing_values = ["true"])] - archive_old_versions: bool, + servers: Vec, //TODO directly parse servers and their directories +} + +#[derive(Subcommand, Debug)] +enum Command { + /// Upload a file to the servers + #[command(visible_short_flag_alias = 'u')] + Upload { + /// The file to upload + file: PathBuf, + /// How to handle older versions of the file + #[arg(short = 'a', long, default_value = "delete", default_missing_value = "archive", num_args = 0..1)] + old_version_policy: OldVersionPolicy, + }, + /// Execute a command on the servers + #[command(visible_short_flag_alias = 'c')] + Command { + /// The command to execute + command: String, + }, +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default, ValueEnum)] +enum OldVersionPolicy { + /// Ignore the existence of older versions + Ignore, + /// Rename older versions: foo.jar -> foo.jarr + Archive, + /// Delete older versions + #[default] + Delete, } #[derive(Debug, Clone, Eq, PartialEq, Hash)] @@ -49,7 +72,7 @@ fn main() -> Result<(), String> { let configured_servers = parse_server_configuration_from_env()?; dbg!(&configured_servers); - + let servers = args .servers .iter() @@ -57,16 +80,12 @@ fn main() -> Result<(), String> { configured_servers .iter() .find(|server| server.ssh_name == *server_name) - .ok_or(format!("no server with the name '{server_name}' has been configured")) + .ok_or(format!( + "no server with the name '{server_name}' has been configured" + )) }) .collect::, _>>()?; - if !args.plugin.is_file() { - return Err("plugin is not a file".to_string()) - } - - //args.plugin.canonicalize() - Ok(()) } @@ -93,13 +112,20 @@ mod test { #[test] fn test_parse_server_configuration() { - let servers = parse_server_configuration("foo:bar,fizz:buzz/bizz").expect("valid server configuration"); - assert_eq!(vec![Server { - ssh_name: "foo".to_string(), - server_directory_path: PathBuf::from("bar"), - }, Server { - ssh_name: "fizz".to_string(), - server_directory_path: PathBuf::from("buzz/bizz"), - }], servers); + let servers = + parse_server_configuration("foo:bar,fizz:buzz/bizz").expect("valid server configuration"); + assert_eq!( + vec![ + Server { + ssh_name: "foo".to_string(), + server_directory_path: PathBuf::from("bar"), + }, + Server { + ssh_name: "fizz".to_string(), + server_directory_path: PathBuf::from("buzz/bizz"), + } + ], + servers + ); } }