diff --git a/Cargo.lock b/Cargo.lock index 2f0a10e..33197a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,55 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.89" @@ -225,6 +274,46 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "clap" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + [[package]] name = "clipboard-win" version = "5.4.0" @@ -234,6 +323,12 @@ dependencies = [ "error-code", ] +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + [[package]] name = "compact_str" version = "0.8.0" @@ -458,6 +553,7 @@ dependencies = [ "anyhow", "arboard", "async-trait", + "clap", "crossterm", "dirs-next", "edc-connector-client", @@ -999,6 +1095,12 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.13.0" @@ -1522,9 +1624,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "png" @@ -2387,6 +2489,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.10.0" diff --git a/edc-connector-tui/Cargo.toml b/edc-connector-tui/Cargo.toml index 2f19667..7bd52eb 100644 --- a/edc-connector-tui/Cargo.toml +++ b/edc-connector-tui/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" crossterm = "0.28.1" ratatui = "0.28.1" tui-textarea = "0.6" +clap = { version = "4.5.18", features = ["derive"] } anyhow = "1.0.89" dirs-next = "2.0.0" toml = "0.8.12" diff --git a/edc-connector-tui/src/app.rs b/edc-connector-tui/src/app.rs index f4707f9..cdaef66 100644 --- a/edc-connector-tui/src/app.rs +++ b/edc-connector-tui/src/app.rs @@ -78,12 +78,7 @@ impl App { Connector::new(cfg, client, status) } - pub fn init(cfg: Config) -> App { - let connectors = cfg - .connectors - .into_iter() - .map(App::init_connector) - .collect(); + pub fn init_with_connectors(connectors: Vec) -> App { let connectors = ConnectorsComponent::new(connectors); let sheet = connectors.info_sheet().merge(Self::info_sheet()); @@ -106,6 +101,16 @@ impl App { } } + pub fn init(cfg: Config) -> App { + let connectors = cfg + .connectors + .into_iter() + .map(App::init_connector) + .collect(); + + Self::init_with_connectors(connectors) + } + pub fn info_sheet() -> InfoSheet { InfoSheet::default() .key_binding("", "Switch menu") diff --git a/edc-connector-tui/src/components/connectors.rs b/edc-connector-tui/src/components/connectors.rs index 1f061a6..add092a 100644 --- a/edc-connector-tui/src/components/connectors.rs +++ b/edc-connector-tui/src/components/connectors.rs @@ -79,6 +79,7 @@ impl Component for ConnectorsComponent { impl ConnectorsComponent { pub fn new(connectors: Vec) -> Self { + let selected = connectors.first().cloned(); Self { table: ConnectorsTable::with_elements( "Connectors".to_string(), @@ -86,7 +87,7 @@ impl ConnectorsComponent { true, ) .on_select(|connector| Box::new(ConnectorsMsg::ConnectorSelected(connector.0.clone()))), - selected: None, + selected, } } diff --git a/edc-connector-tui/src/config.rs b/edc-connector-tui/src/config.rs index 80a1507..d8cffbd 100644 --- a/edc-connector-tui/src/config.rs +++ b/edc-connector-tui/src/config.rs @@ -14,7 +14,7 @@ pub fn get_app_config_path() -> anyhow::Result { } .ok_or_else(|| anyhow::anyhow!("failed to find os config dir."))?; - path.push("edc-tui"); + path.push("edc-connector-tui"); std::fs::create_dir_all(&path)?; Ok(path) } @@ -72,6 +72,14 @@ impl AuthKind { } impl ConnectorConfig { + pub fn new(name: String, address: String, auth: AuthKind) -> Self { + Self { + name, + address, + auth, + } + } + pub fn name(&self) -> &str { &self.name } diff --git a/edc-connector-tui/src/main.rs b/edc-connector-tui/src/main.rs index 09e04ef..28b5cde 100644 --- a/edc-connector-tui/src/main.rs +++ b/edc-connector-tui/src/main.rs @@ -1,8 +1,10 @@ use app::App; -use config::{default_file, Config}; +use clap::{Parser, Subcommand}; +use config::{default_file, Config, ConnectorConfig}; +use edc_connector_client::{Auth, EdcConnectorClient}; use runner::Runner; -use std::time::Duration; - +use std::{path::PathBuf, time::Duration}; +use types::connector::{Connector, ConnectorStatus}; mod app; mod components; mod config; @@ -11,10 +13,37 @@ mod types; #[tokio::main] async fn main() -> anyhow::Result<()> { - let config = Config::parse(&default_file()?)?; + let cli = Cli::parse(); tui::install_panic_hook(); let terminal = tui::init_terminal()?; - let mut runner = Runner::new(Duration::from_millis(250), App::init(config)); + + let app = match cli.mode { + Some(Commands::Connector { url, name, token }) => { + let auth = token.map(Auth::api_token).unwrap_or_else(|| Auth::NoAuth); + let client = EdcConnectorClient::builder() + .management_url(url.clone()) + .with_auth(auth) + .build() + .unwrap(); + + let cfg = ConnectorConfig::new( + name.unwrap_or_else(|| url.clone()), + url, + config::AuthKind::Token { + token_alias: "unknown".to_string(), + }, + ); + + let connector = Connector::new(cfg, client, ConnectorStatus::Connected); + + App::init_with_connectors(vec![connector]) + } + None => { + let config = Config::parse(&cli.config.map(Ok).unwrap_or_else(default_file)?)?; + App::init(config) + } + }; + let mut runner = Runner::new(Duration::from_millis(250), app); runner.run(terminal).await?; tui::restore_terminal()?; Ok(()) @@ -53,3 +82,25 @@ mod tui { })); } } + +#[derive(Parser)] +#[command(version, about, long_about = None)] +struct Cli { + /// Sets a custom config file + #[arg(short, long, value_name = "FILE")] + config: Option, + #[command(subcommand)] + mode: Option, +} + +#[derive(Subcommand)] +pub enum Commands { + Connector { + #[arg(short, long)] + name: Option, + #[arg(short, long)] + url: String, + #[arg(short, long)] + token: Option, + }, +}