mirror of
https://github.com/2e3s/awatcher.git
synced 2025-06-07 12:05:49 +00:00
Fix custom config file and add test
This commit is contained in:
parent
d6e762630e
commit
ca72df7e6e
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3873,6 +3873,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_default",
|
"serde_default",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml 0.7.5",
|
"toml 0.7.5",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
|
@ -111,15 +111,11 @@ pub fn from_cli() -> anyhow::Result<RunnerConfig> {
|
|||||||
pub fn new_with_cli(matches: &ArgMatches) -> anyhow::Result<FileConfig> {
|
pub fn new_with_cli(matches: &ArgMatches) -> anyhow::Result<FileConfig> {
|
||||||
let mut config_path = None;
|
let mut config_path = None;
|
||||||
if matches.contains_id("config") {
|
if matches.contains_id("config") {
|
||||||
let config_file = matches.get_one::<String>("config");
|
let config_file = matches.get_one::<PathBuf>("config");
|
||||||
if let Some(path) = config_file {
|
if let Some(path) = config_file {
|
||||||
if let Err(e) = std::fs::metadata(path) {
|
|
||||||
warn!("Invalid config filename, using the default config: {e}");
|
|
||||||
} else {
|
|
||||||
config_path = Some(Path::new(path).to_path_buf());
|
config_path = Some(Path::new(path).to_path_buf());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
let mut config = FileConfig::new(config_path)?;
|
let mut config = FileConfig::new(config_path)?;
|
||||||
|
|
||||||
merge_cli(&mut config, matches);
|
merge_cli(&mut config, matches);
|
||||||
|
@ -11,6 +11,7 @@ path = "src/lib.rs"
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rstest = "0.17.0"
|
rstest = "0.17.0"
|
||||||
|
tempfile = "3.5.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aw-client-rust = { git = "https://github.com/2e3s/aw-server-rust", rev = "81db4c8" }
|
aw-client-rust = { git = "https://github.com/2e3s/aw-server-rust", rev = "81db4c8" }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde_default::DefaultFromSerde;
|
use serde_default::DefaultFromSerde;
|
||||||
use std::{io::ErrorKind, path::PathBuf, time::Duration};
|
use std::{fs, io::ErrorKind, path::PathBuf, time::Duration};
|
||||||
|
|
||||||
use crate::config::defaults;
|
use crate::config::defaults;
|
||||||
|
|
||||||
@ -97,8 +97,15 @@ pub struct FileConfig {
|
|||||||
|
|
||||||
impl FileConfig {
|
impl FileConfig {
|
||||||
pub fn new(config_override: Option<PathBuf>) -> anyhow::Result<Self> {
|
pub fn new(config_override: Option<PathBuf>) -> anyhow::Result<Self> {
|
||||||
|
let is_config_overridden = config_override.is_some();
|
||||||
let config_path = if let Some(config_override) = config_override {
|
let config_path = if let Some(config_override) = config_override {
|
||||||
|
if config_override.starts_with("~/") {
|
||||||
|
dirs::home_dir()
|
||||||
|
.ok_or(anyhow!("Home directory is not found"))?
|
||||||
|
.join(config_override.strip_prefix("~").unwrap())
|
||||||
|
} else {
|
||||||
config_override
|
config_override
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut system_config_path: PathBuf =
|
let mut system_config_path: PathBuf =
|
||||||
dirs::config_dir().ok_or(anyhow!("Config directory is unknown"))?;
|
dirs::config_dir().ok_or(anyhow!("Config directory is unknown"))?;
|
||||||
@ -108,7 +115,7 @@ impl FileConfig {
|
|||||||
system_config_path
|
system_config_path
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut config = if config_path.exists() {
|
let mut config = if fs::metadata(&config_path).is_ok() {
|
||||||
debug!("Reading config at {}", config_path.display());
|
debug!("Reading config at {}", config_path.display());
|
||||||
let config_content = std::fs::read_to_string(&config_path).with_context(|| {
|
let config_content = std::fs::read_to_string(&config_path).with_context(|| {
|
||||||
format!("Impossible to read config file {}", config_path.display())
|
format!("Impossible to read config file {}", config_path.display())
|
||||||
@ -116,6 +123,9 @@ impl FileConfig {
|
|||||||
|
|
||||||
toml::from_str(&config_content)?
|
toml::from_str(&config_content)?
|
||||||
} else {
|
} else {
|
||||||
|
if is_config_overridden {
|
||||||
|
anyhow::bail!("Config file is not accessible at {}", config_path.display());
|
||||||
|
}
|
||||||
let config = default_config();
|
let config = default_config();
|
||||||
let error = std::fs::create_dir(config_path.parent().unwrap());
|
let error = std::fs::create_dir(config_path.parent().unwrap());
|
||||||
if let Err(e) = error {
|
if let Err(e) = error {
|
||||||
@ -133,3 +143,102 @@ impl FileConfig {
|
|||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use rstest::rstest;
|
||||||
|
use std::io::Write;
|
||||||
|
use tempfile::NamedTempFile;
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
fn all() {
|
||||||
|
let mut file = NamedTempFile::new().unwrap();
|
||||||
|
write!(
|
||||||
|
file,
|
||||||
|
r#"
|
||||||
|
[server]
|
||||||
|
port = 1234
|
||||||
|
host = "http://address.com"
|
||||||
|
|
||||||
|
[awatcher]
|
||||||
|
idle-timeout-seconds=14
|
||||||
|
poll-time-idle-seconds=13
|
||||||
|
poll-time-window-seconds=12
|
||||||
|
|
||||||
|
# Add as many filters as needed.
|
||||||
|
# There should be at least 1 match field, and at least 1 replace field.
|
||||||
|
[[awatcher.filters]]
|
||||||
|
match-app-id = "firefox"
|
||||||
|
replace-title = "Unknown"
|
||||||
|
|
||||||
|
[[awatcher.filters]]
|
||||||
|
match-app-id = "code"
|
||||||
|
match-title = "title"
|
||||||
|
replace-app-id = "VSCode"
|
||||||
|
replace-title = "Title"
|
||||||
|
"#
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let config = FileConfig::new(Some(file.path().to_path_buf())).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(1234, config.server.port);
|
||||||
|
assert_eq!("http://address.com", config.server.host);
|
||||||
|
|
||||||
|
assert_eq!(14, config.client.idle_timeout_seconds);
|
||||||
|
assert_eq!(13, config.client.poll_time_idle_seconds);
|
||||||
|
assert_eq!(12, config.client.poll_time_window_seconds);
|
||||||
|
|
||||||
|
assert_eq!(2, config.client.filters.len());
|
||||||
|
let replacement1 = config.client.filters[0]
|
||||||
|
.replacement("firefox", "any")
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(None, replacement1.replace_app_id);
|
||||||
|
assert_eq!(Some("Unknown".to_string()), replacement1.replace_title);
|
||||||
|
let replacement2 = config.client.filters[1]
|
||||||
|
.replacement("code", "title")
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(Some("VSCode".to_string()), replacement2.replace_app_id);
|
||||||
|
assert_eq!(Some("Title".to_string()), replacement2.replace_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
fn empty() {
|
||||||
|
let mut file = NamedTempFile::new().unwrap();
|
||||||
|
write!(file, "[awatcher]").unwrap();
|
||||||
|
|
||||||
|
let config = FileConfig::new(Some(file.path().to_path_buf())).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(defaults::port(), config.server.port);
|
||||||
|
assert_eq!(defaults::host(), config.server.host);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
defaults::idle_timeout_seconds(),
|
||||||
|
config.client.idle_timeout_seconds
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
defaults::poll_time_idle_seconds(),
|
||||||
|
config.client.poll_time_idle_seconds
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
defaults::poll_time_window_seconds(),
|
||||||
|
config.client.poll_time_window_seconds
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(0, config.client.filters.len());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
fn wrong_file() {
|
||||||
|
let file = PathBuf::new();
|
||||||
|
|
||||||
|
let config = FileConfig::new(Some(file));
|
||||||
|
|
||||||
|
assert!(config.is_err());
|
||||||
|
assert_eq!(
|
||||||
|
"Config file is not accessible at ",
|
||||||
|
config.err().unwrap().to_string()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user