From 8e8577cd7b5c15b27b9570be5633d908348f795b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20J=C3=B6hnk?= Date: Fri, 11 Dec 2020 13:03:45 +0100 Subject: [PATCH] feat(config): add cli parameter to specify config file path or load from platform config dir --- Cargo.lock | 116 ++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 2 + src/config.rs | 34 +++++++++++++++ src/main.rs | 28 +++++++++--- src/options.rs | 14 ++++++ 5 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/options.rs diff --git a/Cargo.lock b/Cargo.lock index b2cb706..49628e3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -24,6 +24,18 @@ version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4" +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "atty" version = "0.2.14" @@ -35,6 +47,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "base64" version = "0.10.1" @@ -44,12 +62,29 @@ dependencies = [ "byteorder", ] +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "bumpalo" version = "3.4.0" @@ -111,11 +146,29 @@ dependencies = [ "vec_map", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + [[package]] name = "desktop2mqtt" version = "0.1.0" dependencies = [ "anyhow", + "directories", "env_logger", "futures-util", "log", @@ -123,10 +176,31 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "structopt", "tokio", "xidlehook-core", ] +[[package]] +name = "directories" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fed639d60b58d0f53498ab13d26f621fd77569cc6edb031f4cc36a2ad9da0f" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + [[package]] name = "dtoa" version = "0.4.6" @@ -211,6 +285,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.3.1" @@ -536,6 +621,17 @@ version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" +[[package]] +name = "redox_users" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +dependencies = [ + "getrandom", + "redox_syscall", + "rust-argon2", +] + [[package]] name = "regex" version = "1.4.2" @@ -569,13 +665,25 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64 0.13.0", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils", +] + [[package]] name = "rustls" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" dependencies = [ - "base64", + "base64 0.10.1", "log", "ring", "sct", @@ -831,6 +939,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasm-bindgen" version = "0.2.69" diff --git a/Cargo.toml b/Cargo.toml index 1a4908d..dcc1faf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,8 @@ serde_json = "1" serde_yaml = "0.8" anyhow = "1" futures-util = "0.3" +structopt = "0.3" +directories = "3" [package.metadata.deb] section = "utility" diff --git a/src/config.rs b/src/config.rs index 4856972..b5e631d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,8 @@ +use crate::options::CliOptions; +use directories::ProjectDirs; use serde::Deserialize; +use std::fs::File; +use std::path::{Path, PathBuf}; const DEFAULT_POLL_RATE: u64 = 5; @@ -41,3 +45,33 @@ impl Default for BacklightProvider { fn default_poll_rate() -> u64 { DEFAULT_POLL_RATE } + +pub(crate) fn get_config(options: &CliOptions) -> anyhow::Result { + let path = get_config_file_path(options); + log::debug!("Loading config file from {:?}", &path); + let config_file = File::open(path)?; + let config: Config = serde_yaml::from_reader(&config_file)?; + + Ok(config) +} + +fn get_config_file_path(options: &CliOptions) -> PathBuf { + let default_file = Path::new("config.yml"); + let user_dir_file = get_user_dir_path(); + + match (&options.config, default_file, user_dir_file) { + (Some(config), _, _) => config.clone(), + (None, config, _) if config.exists() => config.to_path_buf(), + (None, _, Some(config)) if config.exists() => config, + _ => panic!("No config file found"), + } +} + +fn get_user_dir_path() -> Option { + if let Some(project_dirs) = ProjectDirs::from("me", "maxjoehnk", "desktop2mqtt") { + let config_dir = project_dirs.config_dir(); + Some(config_dir.join("config.yml")) + } else { + None + } +} diff --git a/src/main.rs b/src/main.rs index 5c05121..63231f7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,20 @@ mod config; mod modules; +mod options; -use crate::config::Config; +use crate::config::get_config; use crate::modules::*; -use std::fs::File; +use crate::options::CliOptions; +use log::LevelFilter; +use structopt::StructOpt; use tokio::sync::{broadcast, mpsc}; #[tokio::main] async fn main() -> anyhow::Result<()> { - env_logger::init(); - let config_file = File::open("config.yml")?; - let config: Config = serde_yaml::from_reader(&config_file)?; + let options = CliOptions::from_args(); + setup_logging(options.verbose); + + let config = get_config(&options)?; let (mqtt_sender, mqtt_receiver) = mpsc::unbounded_channel(); let (mqtt_event_sender, mqtt_event_receiver) = broadcast::channel(10); @@ -23,6 +27,8 @@ async fn main() -> anyhow::Result<()> { let mut backlight_module = get_backlight_module(state_sender, mqtt_event_receiver, config.backlight); + log::info!("Starting desktop2mqtt..."); + tokio::try_join!( mqtt_module.run(&config), hass_discovery_module.run(&config), @@ -33,3 +39,15 @@ async fn main() -> anyhow::Result<()> { Ok(()) } + +fn setup_logging(verbose: u8) { + let log_level = match verbose { + 0 => LevelFilter::Info, + 1 => LevelFilter::Debug, + _ => LevelFilter::Trace, + }; + + env_logger::Builder::from_default_env() + .filter(None, log_level) + .init(); +} diff --git a/src/options.rs b/src/options.rs new file mode 100644 index 0000000..532fd4c --- /dev/null +++ b/src/options.rs @@ -0,0 +1,14 @@ +use std::path::PathBuf; + +use structopt::StructOpt; + +#[derive(StructOpt, Debug)] +pub(crate) struct CliOptions { + /// Verbosity (-v = debug, -vv = trace) + #[structopt(short, long, parse(from_occurrences))] + pub(crate) verbose: u8, + + /// Config file + #[structopt(short, long, parse(from_os_str))] + pub(crate) config: Option, +}