diff --git a/.gitignore b/.gitignore index 5e8a4a5..eb5a316 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -.token target - diff --git a/.token.keep b/.token.keep deleted file mode 100644 index 2ea7cab..0000000 --- a/.token.keep +++ /dev/null @@ -1 +0,0 @@ -RSLACK_TOKEN=your-token diff --git a/Cargo.lock b/Cargo.lock index 7675a31..564c1d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,6 +142,26 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "dirs" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +dependencies = [ + "libc", + "redox_users", + "windows-sys 0.45.0", +] + [[package]] name = "encoding_rs" version = "0.8.30" @@ -728,9 +748,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] @@ -744,6 +764,17 @@ dependencies = [ "redox_syscall", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.7.3" @@ -812,6 +843,7 @@ name = "rslack" version = "0.2.8" dependencies = [ "anyhow", + "dirs", "libc", "mockito", "reqwest", @@ -1062,6 +1094,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.3", +] + [[package]] name = "tinyvec" version = "1.5.1" diff --git a/Cargo.toml b/Cargo.toml index df33be6..57ff9b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ categories = ["command-line-utilities"] [dependencies] anyhow = "1.0.70" +dirs = "5.0" libc = "0.2" reqwest = { version = "0.11.16", features = ["json"] } serde = { version = "1.0.160", features = ["derive"] } diff --git a/README.md b/README.md index b74a47c..894f8a2 100644 --- a/README.md +++ b/README.md @@ -27,28 +27,24 @@ # Install brew install kohbis/rslack/rslack -# Set token +# Configuration +# If both are set, use the value of `.rslack export RSLACK_TOKEN=your-token +# or +echo "RSLACK_TOKEN=your-token" > ${HOME}/.rslack rslack ``` ### Local Build -If you want by local build. - ```bash -export RSLACK_TOKEN=your-token -# or -mv .token.keep .token -echo "RSLACK_TOKEN=your-token" > .token - -# If both are set, use the value of `.token` - +# Configuration +# and cargo run ``` -If you want to run on Docker, exec the following command. +If you want to run on Docker, please execute the following command. ```bash docker build -t rslack . diff --git a/src/bin/rslack.rs b/src/bin/rslack.rs index b66ddbc..eeecd5b 100644 --- a/src/bin/rslack.rs +++ b/src/bin/rslack.rs @@ -11,7 +11,6 @@ use rslack::option::Opt; use rslack::slack; const SLACK_URL: &'static str = "https://slack.com"; -const TOKEN_FILE: &'static str = ".token"; const USAGE_MESSAGES: &'static str = "(post: ctrl-p / exit: ctrl-c)"; #[tokio::main] @@ -20,7 +19,7 @@ async fn main() { let mut channel = opts.channel; let mut message = opts.message; - let config = match Config::new(TOKEN_FILE) { + let config = match Config::new(None) { Ok(config) => config, Err(err) => return eprintln!("{}", err), }; diff --git a/src/config/mod.rs b/src/config/mod.rs index 5e3f290..688159e 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,10 +1,12 @@ use anyhow::{anyhow, Result}; +use dirs; use std::env; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::path::Path; +use std::path::{Path, PathBuf}; -const RSLACK_TOKEN: &str = "RSLACK_TOKEN"; +const RSLACK_TOKEN: &'static str = "RSLACK_TOKEN"; +const CONFIG_FILE: &'static str = ".rslack"; #[derive(Debug, PartialEq)] pub struct Config { @@ -12,15 +14,19 @@ pub struct Config { } impl Config { - pub fn new(filename: &str) -> Result { + pub fn new(config_path: Option) -> Result { let mut config = Self { token: String::new(), }; config.read_from_env()?; - if Path::new(filename).exists() { - config.read_from_file(filename)?; + if let Some(path) = config_path { + config.read_from_file(&path).ok(); + } else { + let home = dirs::home_dir().ok_or(anyhow!("Home directory not found."))?; + let path = home.join(CONFIG_FILE); + config.read_from_file(&path).ok(); } config.validate()?; @@ -39,8 +45,8 @@ impl Config { } #[allow(clippy::single_match)] - fn read_from_file(&mut self, filename: &str) -> Result<&Self> { - let file = match File::open(filename) { + fn read_from_file(&mut self, path: &Path) -> Result<&Self> { + let file = match File::open(path) { Ok(file) => file, Err(err) => return Err(anyhow!(err)), }; @@ -85,7 +91,9 @@ mod tests { #[serial] fn initialize_with_valid_file() { setup(); - let actual = Config::new("tests/fixtures/config/token.test.valid").unwrap(); + + let config_path = PathBuf::from("tests/fixtures/config/config.test.valid"); + let actual = Config::new(Some(config_path)).unwrap(); let expected = Config { token: String::from("token-from-file-123"), }; @@ -97,7 +105,9 @@ mod tests { #[should_panic] fn initialize_with_invalid_file() { setup(); - Config::new("tests/token.test.invalid").unwrap(); + + let config_path = PathBuf::from("tests/config.test.invalid"); + Config::new(Some(config_path)).unwrap(); } #[test] @@ -105,7 +115,9 @@ mod tests { fn initialize_with_env() { setup(); env::set_var(RSLACK_TOKEN, "token-from-env-123"); - let actual = Config::new("no_file").unwrap(); + + let config_path = PathBuf::from("no_file"); + let actual = Config::new(Some(config_path)).unwrap(); let expected = Config { token: String::from("token-from-env-123"), }; @@ -118,7 +130,9 @@ mod tests { fn initialize_with_empty_env() { setup(); env::set_var(RSLACK_TOKEN, ""); - Config::new("no_file").unwrap(); + + let config_path = PathBuf::from("no_file"); + Config::new(Some(config_path)).unwrap(); } #[test] @@ -126,10 +140,12 @@ mod tests { fn initialize_with_env_and_file() { setup(); env::set_var(RSLACK_TOKEN, "token-from-env-123"); + let expected = Config { token: String::from("token-from-file-123"), }; - let actual = Config::new("tests/fixtures/config/token.test.valid").unwrap(); + let config_path = PathBuf::from("tests/fixtures/config/config.test.valid"); + let actual = Config::new(Some(config_path)).unwrap(); assert_eq!(actual, expected); } diff --git a/tests/fixtures/config/token.test.invalid b/tests/fixtures/config/config.test.invalid similarity index 100% rename from tests/fixtures/config/token.test.invalid rename to tests/fixtures/config/config.test.invalid diff --git a/tests/fixtures/config/token.test.valid b/tests/fixtures/config/config.test.valid similarity index 100% rename from tests/fixtures/config/token.test.valid rename to tests/fixtures/config/config.test.valid