diff --git a/package.json b/package.json index 486cc17..8bb7b8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "creddy", - "version": "0.5.2", + "version": "0.5.3", "scripts": { "dev": "vite", "build": "vite build", diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 5a2c599..5a6de83 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1196,7 +1196,7 @@ dependencies = [ [[package]] name = "creddy" -version = "0.5.2" +version = "0.5.3" dependencies = [ "argon2", "auto-launch", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 5948385..88f3924 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "creddy" -version = "0.5.2" +version = "0.5.3" description = "A friendly AWS credentials manager" authors = ["Joseph Montanaro"] license = "" diff --git a/src-tauri/src/bin/creddy_cli.rs b/src-tauri/src/bin/creddy_cli.rs index 59e4c4f..04a0b5a 100644 --- a/src-tauri/src/bin/creddy_cli.rs +++ b/src-tauri/src/bin/creddy_cli.rs @@ -11,13 +11,7 @@ use std::{ fn main() { - let args = cli::parser().get_matches(); - if let Some(true) = args.get_one::("help") { - cli::parser().print_help().unwrap(); // if we can't print help we can't print an error - process::exit(0); - } - - let res = match args.subcommand() { + let res = match cli::parser().get_matches().subcommand() { None | Some(("run", _)) => launch_gui(), Some(("get", m)) => cli::get(m), Some(("exec", m)) => cli::exec(m), @@ -35,7 +29,7 @@ fn main() { fn launch_gui() -> Result<(), CliError> { let mut path = env::current_exe()?; path.pop(); // bin dir - + // binaries are colocated in dev, but not in production #[cfg(not(debug_assertions))] path.pop(); // install dir diff --git a/src-tauri/src/cli.rs b/src-tauri/src/cli.rs index ce5cf60..aedd635 100644 --- a/src-tauri/src/cli.rs +++ b/src-tauri/src/cli.rs @@ -1,4 +1,5 @@ use std::ffi::OsString; +use std::path::PathBuf; use std::process::Command as ChildCommand; #[cfg(windows)] use std::time::Duration; @@ -9,6 +10,7 @@ use clap::{ ArgMatches, ArgAction, builder::PossibleValuesParser, + value_parser, }; use tokio::io::{AsyncReadExt, AsyncWriteExt}; @@ -37,6 +39,14 @@ pub fn parser() -> Command<'static> { Command::new("creddy") .version(env!("CARGO_PKG_VERSION")) .about("A friendly AWS credentials manager") + .arg( + Arg::new("server_addr") + .short('a') + .long("server-addr") + .takes_value(true) + .value_parser(value_parser!(PathBuf)) + .help("Connect to the main Creddy process at this address") + ) .subcommand( Command::new("run") .about("Launch Creddy") @@ -71,6 +81,7 @@ pub fn parser() -> Command<'static> { Arg::new("name") .short('n') .long("name") + .takes_value(true) .help("If unspecified, use default credentials") ) .arg( @@ -94,8 +105,9 @@ pub fn parser() -> Command<'static> { pub fn get(args: &ArgMatches) -> Result<(), CliError> { let name = args.get_one("name").cloned(); let base = *args.get_one("base").unwrap_or(&false); - - let output = match make_request(&Request::GetAwsCredentials { name, base })? { + let addr = args.get_one("server_addr").cloned(); + + let output = match make_request(addr, &Request::GetAwsCredentials { name, base })? { Response::AwsBase(creds) => serde_json::to_string(&creds).unwrap(), Response::AwsSession(creds) => serde_json::to_string(&creds).unwrap(), r => return Err(RequestError::Unexpected(r).into()), @@ -108,14 +120,15 @@ pub fn get(args: &ArgMatches) -> Result<(), CliError> { pub fn exec(args: &ArgMatches) -> Result<(), CliError> { let name = args.get_one("name").cloned(); let base = *args.get_one("base").unwrap_or(&false); + let addr = args.get_one("server_addr").cloned(); let mut cmd_line = args.get_many("command") .ok_or(ExecError::NoCommand)?; let cmd_name: &String = cmd_line.next().unwrap(); // Clap guarantees that there will be at least one let mut cmd = ChildCommand::new(cmd_name); cmd.args(cmd_line); - - match make_request(&Request::GetAwsCredentials { name, base })? { + + match make_request(addr, &Request::GetAwsCredentials { name, base })? { Response::AwsBase(creds) => { cmd.env("AWS_ACCESS_KEY_ID", creds.access_key_id); cmd.env("AWS_SECRET_ACCESS_KEY", creds.secret_access_key); @@ -160,6 +173,7 @@ pub fn exec(args: &ArgMatches) -> Result<(), CliError> { pub fn invoke_shortcut(args: &ArgMatches) -> Result<(), CliError> { + let addr = args.get_one("server_addr").cloned(); let action = match args.get_one::("action").map(|s| s.as_str()) { Some("show_window") => ShortcutAction::ShowWindow, Some("launch_terminal") => ShortcutAction::LaunchTerminal, @@ -167,7 +181,7 @@ pub fn invoke_shortcut(args: &ArgMatches) -> Result<(), CliError> { }; let req = Request::InvokeShortcut(action); - match make_request(&req) { + match make_request(addr, &req) { Ok(Response::Empty) => Ok(()), Ok(r) => Err(RequestError::Unexpected(r).into()), Err(e) => Err(e.into()), @@ -176,12 +190,12 @@ pub fn invoke_shortcut(args: &ArgMatches) -> Result<(), CliError> { #[tokio::main] -async fn make_request(req: &Request) -> Result { +async fn make_request(addr: Option, req: &Request) -> Result { let mut data = serde_json::to_string(req).unwrap(); // server expects newline marking end of request data.push('\n'); - let mut stream = connect().await?; + let mut stream = connect(addr).await?; stream.write_all(&data.as_bytes()).await?; let mut buf = Vec::with_capacity(1024); @@ -192,10 +206,10 @@ async fn make_request(req: &Request) -> Result { #[cfg(windows)] -async fn connect() -> Result { +async fn connect(addr: Option) -> Result { // apparently attempting to connect can fail if there's already a client connected loop { - let addr = srv::addr("creddy-server"); + let addr = addr.unwrap_or_else(|| srv::addr("creddy-server")); match ClientOptions::new().open(&addr) { Ok(stream) => return Ok(stream), Err(e) if e.raw_os_error() == Some(ERROR_PIPE_BUSY.0 as i32) => (), @@ -207,7 +221,7 @@ async fn connect() -> Result { #[cfg(unix)] -async fn connect() -> Result { - let path = srv::addr("creddy-server"); +async fn connect(addr: Option) -> Result { + let path = addr.unwrap_or_else(|| srv::addr("creddy-server")); UnixStream::connect(&path).await } diff --git a/src-tauri/src/srv/mod.rs b/src-tauri/src/srv/mod.rs index e5bdd40..83f3a61 100644 --- a/src-tauri/src/srv/mod.rs +++ b/src-tauri/src/srv/mod.rs @@ -20,7 +20,7 @@ pub use platform::addr; #[derive(Debug, Serialize, Deserialize)] pub enum Request { - GetAwsCredentials { + GetAwsCredentials { name: Option, base: bool, }, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index caa8b94..c17a103 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -50,7 +50,7 @@ } }, "productName": "creddy", - "version": "0.5.2", + "version": "0.5.3", "identifier": "creddy", "plugins": {}, "app": { @@ -85,4 +85,4 @@ } } } -} \ No newline at end of file +}