diff --git a/Cargo.lock b/Cargo.lock index 0d197f6..1e2782b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -502,6 +502,19 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cliclack" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4febf49beeedc40528e4956995631f1bbdb4d8804ef940b44351f393a996c739" +dependencies = [ + "console", + "indicatif", + "once_cell", + "textwrap", + "zeroize", +] + [[package]] name = "color-eyre" version = "0.6.3" @@ -577,6 +590,19 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + [[package]] name = "const-random" version = "0.1.18" @@ -751,6 +777,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.33" @@ -1273,6 +1305,19 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "indoc" version = "2.0.5" @@ -1645,6 +1690,12 @@ dependencies = [ "libc", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "object" version = "0.32.2" @@ -1918,6 +1969,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2486,6 +2543,12 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "socket2" version = "0.4.10" @@ -2623,6 +2686,7 @@ dependencies = [ "chrono-humanize", "clap", "clap_derive", + "cliclack", "color-eyre", "config", "crossterm", @@ -2641,9 +2705,11 @@ dependencies = [ "signal-hook-tokio", "sled", "tokio", + "toml", "tracing", "tracing-appender", "tracing-subscriber", + "url", "xdg", ] @@ -2659,6 +2725,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.56" @@ -2994,6 +3071,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.23" @@ -3464,6 +3547,26 @@ dependencies = [ "syn 2.0.53", ] +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "zvariant" version = "3.15.2" diff --git a/Cargo.toml b/Cargo.toml index a81f22c..ee87f7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ chrono = { version = "0.4.35", features = ["serde"] } chrono-humanize = "0.2.3" clap = { version = "4.5.4", features = ["derive"] } clap_derive = "4.5.4" +cliclack = "0.2.5" color-eyre = "0.6.3" config = "0.14.0" crossterm = "0.27.0" @@ -27,9 +28,11 @@ signal-hook = "0.3.17" signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"] } sled = "0.34.7" tokio = { version = "1.36.0", features = ["full"] } +toml = "0.8.12" tracing = "0.1.40" tracing-appender = "0.2.3" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +url = "2.5.0" xdg = "2.5.2" [profile.dev] diff --git a/src/cli/config.rs b/src/cli/config.rs index 3d1d629..c0a8f80 100644 --- a/src/cli/config.rs +++ b/src/cli/config.rs @@ -1,3 +1,7 @@ +use std::{fs::File, io::Write}; + +use cliclack::input; + use crate::cli::prelude::*; #[derive(Subcommand)] @@ -20,8 +24,52 @@ impl Command { } pub async fn setup(&self, tasks: SharedTasks) -> Result<()> { + use cliclack::{intro, outro}; + + // TODO: maybe use the normal builder + + intro("Configure taskr")?; + + // let gitlab_url: String = input("What is your GitLab URL?") + // .placeholder("https://gitlab.com") + // .validate_interactively(|input: &String| match url::Url::parse(input) { + // Ok(_) => Ok(()), + // Err(_) => Err("Must be a URL"), + // }) + // .interact()?; + + // let jira_url: String = input("What is your Jira URL?") + // .placeholder("https://company.atlassian.net") + // .validate_interactively(|input: &String| match url::Url::parse(input) { + // Ok(_) => Ok(()), + // Err(_) => Err("Must be a URL"), + // }) + // .interact()?; + + let gitlab_url = "https://gitlab.com"; + let jira_url = "https://jira.com"; + + let config_builder = Config::default_builder()? + .set_override("gitlab.url", gitlab_url)? + .set_override("jira.url", jira_url)? + .set_override("secrets.gitlab_token", gitlab_url)? + .set_override("secrets.jira_token", jira_url)?; + + let config_result = config_builder.build()?.try_deserialize(); + dbg!(&config_result); + if let Err(err) = &config_result { + match err { + config::ConfigError::Type { origin, unexpected, expected, key } => println!("Type Error at key {key:#?} expected {expected:#?} from origin {origin:#?} (unexpected: {unexpected:#?})"), +config::ConfigError::Message(str) => println!("Message {err:#?} {str}"), + _ => println!("I dunno. {err:#?}"), + } + } + let config = config_result?; + let mut file = File::create(&tasks.config_file_path)?; + file.write_all(toml::to_string(&config)?.as_bytes())?; + // TODO: initialize known keyring values/entries - println!("You're all set!"); + outro("All set! Try `taskr list --sync` now!")?; Ok(()) } } diff --git a/src/config.rs b/src/config.rs index 77309c4..d722952 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,9 @@ use crate::prelude::*; -use std::{fmt::Debug, path::Path}; +use std::{collections::HashMap, fmt::Debug, path::Path}; use color_eyre::{eyre::Context, Section}; -use config::{builder::DefaultState, Config as CConfig, ConfigBuilder}; +use config::{builder::DefaultState, Config as CConfig, ConfigBuilder, Value}; use serde::{Deserialize, Serialize}; const CURRENT_VERSION: u64 = 1; @@ -63,7 +63,11 @@ where { } pub fn default_builder() -> Result> { - Ok(CConfig::builder().set_default("version", CURRENT_VERSION)?) + Ok(CConfig::builder() + .set_default("version", CURRENT_VERSION)? + .set_default("secrets", HashMap::::new())? + .set_default("jira", HashMap::::new())? + .set_default("gitlab", HashMap::::new())?) } #[allow(dead_code)] diff --git a/src/tasks.rs b/src/tasks.rs index d2e5e0b..1a3cad0 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -19,8 +19,8 @@ use crate::{gitlab::GitLab, jira::Jira, result::Result}; pub type Db = sled::Db; pub struct Tasks { - data_dir: PathBuf, - config_file_path: PathBuf, + pub data_dir: PathBuf, + pub config_file_path: PathBuf, config: OnceLock, gitlab: OnceLock,