Change default config structure

This commit is contained in:
Federico Terzi 2019-09-23 23:34:55 +02:00
parent a0b0842273
commit efc6a9c860
4 changed files with 139 additions and 116 deletions

View File

@ -37,6 +37,8 @@ pub(crate) mod runtime;
const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("../res/config.yml"); const DEFAULT_CONFIG_FILE_CONTENT : &str = include_str!("../res/config.yml");
const DEFAULT_CONFIG_FILE_NAME : &str = "default.yml"; const DEFAULT_CONFIG_FILE_NAME : &str = "default.yml";
const USER_CONFIGS_FOLDER_NAME: &str = "user";
const PACKAGES_FOLDER_NAME : &str = "packages";
// Default values for primitives // Default values for primitives
fn default_name() -> String{ "default".to_owned() } fn default_name() -> String{ "default".to_owned() }
@ -119,10 +121,10 @@ macro_rules! validate_field {
impl Configs { impl Configs {
/* /*
* Validate the Config instance. * Validate the Config instance.
* It makes sure that app-specific config instances do not define * It makes sure that user defined config instances do not define
* attributes reserved to the default config. * attributes reserved to the default config.
*/ */
fn validate_specific_config(&self) -> bool { fn validate_user_defined_config(&self) -> bool {
let mut result = true; let mut result = true;
validate_field!(result, self.config_caching_interval, default_config_caching_interval()); validate_field!(result, self.config_caching_interval, default_config_caching_interval());
@ -185,76 +187,79 @@ impl ConfigSet {
return Err(ConfigLoadError::InvalidConfigDirectory) return Err(ConfigLoadError::InvalidConfigDirectory)
} }
// Load default configuration
let default_file = dir_path.join(DEFAULT_CONFIG_FILE_NAME); let default_file = dir_path.join(DEFAULT_CONFIG_FILE_NAME);
let default = Configs::load_config(default_file.as_path())?; let default = Configs::load_config(default_file.as_path())?;
// Load user defined configurations
// TODO: loading with parent merging
let mut specific = Vec::new(); let mut specific = Vec::new();
// Used to make sure no duplicates are present let specific_dir = dir_path.join(USER_CONFIGS_FOLDER_NAME);
let mut name_set = HashSet::new(); if specific_dir.exists() {
// Used to make sure no duplicates are present
let mut name_set = HashSet::new(); // TODO: think about integration with packages
let dir_entry = fs::read_dir(dir_path); let dir_entry = fs::read_dir(specific_dir);
if dir_entry.is_err() { if dir_entry.is_err() {
return Err(ConfigLoadError::UnableToReadFile) return Err(ConfigLoadError::UnableToReadFile)
} }
let dir_entry = dir_entry.unwrap(); let dir_entry = dir_entry.unwrap();
for entry in dir_entry { for entry in dir_entry {
let entry = entry; let entry = entry;
if let Ok(entry) = entry { if let Ok(entry) = entry {
let path = entry.path(); let path = entry.path();
// Skip the default one, already loaded // Skip non-yaml config files
if path.file_name().unwrap_or("".as_ref()) == "default.yml" { if path.extension().unwrap_or_default().to_str().unwrap_or_default() != "yml" {
continue; continue;
}
let mut config = Configs::load_config(path.as_path())?;
if !config.validate_user_defined_config() {
return Err(ConfigLoadError::InvalidParameter(path.to_owned()))
}
if config.name == "default" {
return Err(ConfigLoadError::MissingName(path.to_owned()));
}
if name_set.contains(&config.name) {
return Err(ConfigLoadError::NameDuplicate(path.to_owned()));
}
// Compute new match set, merging the parent's matches.
// Note: if an app-specific redefines a trigger already present in the
// default config, the latter gets overwritten.
if !config.exclude_parent_matches {
let mut merged_matches = config.matches.clone();
let mut trigger_set = HashSet::new();
merged_matches.iter().for_each(|m| {
trigger_set.insert(m.trigger.clone());
});
let parent_matches : Vec<Match> = default.matches.iter().filter(|&m| {
!trigger_set.contains(&m.trigger)
}).map(|m| m.clone()).collect();
merged_matches.extend(parent_matches);
config.matches = merged_matches;
}
// TODO: check if it contains at least a filter, and warn the user about the problem
name_set.insert(config.name.clone());
specific.push(config);
} }
// Skip non-yaml config files
if path.extension().unwrap_or_default().to_str().unwrap_or_default() != "yml" {
continue;
}
let mut config = Configs::load_config(path.as_path())?;
if !config.validate_specific_config() {
return Err(ConfigLoadError::InvalidParameter(path.to_owned()))
}
if config.name == "default" {
return Err(ConfigLoadError::MissingName(path.to_owned()));
}
if name_set.contains(&config.name) {
return Err(ConfigLoadError::NameDuplicate(path.to_owned()));
}
// Compute new match set, merging the parent's matches.
// Note: if an app-specific redefines a trigger already present in the
// default config, the latter gets overwritten.
if !config.exclude_parent_matches {
let mut merged_matches = config.matches.clone();
let mut trigger_set = HashSet::new();
merged_matches.iter().for_each(|m| {
trigger_set.insert(m.trigger.clone());
});
let parent_matches : Vec<Match> = default.matches.iter().filter(|&m| {
!trigger_set.contains(&m.trigger)
}).map(|m| m.clone()).collect();
merged_matches.extend(parent_matches);
config.matches = merged_matches;
}
// TODO: check if it contains at least a filter, and warn the user about the problem
name_set.insert(config.name.clone());
specific.push(config);
} }
} }
Ok(ConfigSet { Ok(ConfigSet {
default, default,
specific specific: specific
}) })
} }
@ -277,6 +282,24 @@ impl ConfigSet {
} }
} }
// Create auxiliary directories
let user_config_dir = espanso_dir.join(USER_CONFIGS_FOLDER_NAME);
if !user_config_dir.exists() {
let res = create_dir_all(user_config_dir.as_path());
if res.is_err() {
return Err(ConfigLoadError::UnableToCreateDefaultConfig)
}
}
let packages_dir = espanso_dir.join(PACKAGES_FOLDER_NAME);
if !packages_dir.exists() {
let res = create_dir_all(packages_dir.as_path());
if res.is_err() {
return Err(ConfigLoadError::UnableToCreateDefaultConfig)
}
}
return ConfigSet::load(espanso_dir.as_path()) return ConfigSet::load(espanso_dir.as_path())
} }
} }
@ -311,8 +334,8 @@ impl fmt::Display for ConfigLoadError {
ConfigLoadError::UnableToReadFile => write!(f, "Unable to read config file"), ConfigLoadError::UnableToReadFile => write!(f, "Unable to read config file"),
ConfigLoadError::InvalidYAML(path, e) => write!(f, "Error parsing YAML file '{}', invalid syntax: {}", path.to_str().unwrap_or_default(), e), ConfigLoadError::InvalidYAML(path, e) => write!(f, "Error parsing YAML file '{}', invalid syntax: {}", path.to_str().unwrap_or_default(), e),
ConfigLoadError::InvalidConfigDirectory => write!(f, "Invalid config directory"), ConfigLoadError::InvalidConfigDirectory => write!(f, "Invalid config directory"),
ConfigLoadError::InvalidParameter(path) => write!(f, "Invalid parameter in '{}', use of reserved parameters in app-specific configs is not permitted", path.to_str().unwrap_or_default()), ConfigLoadError::InvalidParameter(path) => write!(f, "Invalid parameter in '{}', use of reserved parameters in used defined configs is not permitted", path.to_str().unwrap_or_default()),
ConfigLoadError::MissingName(path) => write!(f, "The 'name' field is required in app-specific configurations, but it's missing in '{}'", path.to_str().unwrap_or_default()), ConfigLoadError::MissingName(path) => write!(f, "The 'name' field is required in user defined configurations, but it's missing in '{}'", path.to_str().unwrap_or_default()),
ConfigLoadError::NameDuplicate(path) => write!(f, "Found duplicate 'name' in '{}', please use different names", path.to_str().unwrap_or_default()), ConfigLoadError::NameDuplicate(path) => write!(f, "Found duplicate 'name' in '{}', please use different names", path.to_str().unwrap_or_default()),
ConfigLoadError::UnableToCreateDefaultConfig => write!(f, "Could not generate default config file"), ConfigLoadError::UnableToCreateDefaultConfig => write!(f, "Could not generate default config file"),
} }
@ -326,8 +349,8 @@ impl Error for ConfigLoadError {
ConfigLoadError::UnableToReadFile => "Unable to read config file", ConfigLoadError::UnableToReadFile => "Unable to read config file",
ConfigLoadError::InvalidYAML(_, _) => "Error parsing YAML file, invalid syntax", ConfigLoadError::InvalidYAML(_, _) => "Error parsing YAML file, invalid syntax",
ConfigLoadError::InvalidConfigDirectory => "Invalid config directory", ConfigLoadError::InvalidConfigDirectory => "Invalid config directory",
ConfigLoadError::InvalidParameter(_) => "Invalid parameter, use of reserved parameters in app-specific configs is not permitted", ConfigLoadError::InvalidParameter(_) => "Invalid parameter, use of reserved parameters in user defined configs is not permitted",
ConfigLoadError::MissingName(_) => "The 'name' field is required in app-specific configurations, but it's missing", ConfigLoadError::MissingName(_) => "The 'name' field is required in user defined configurations, but it's missing",
ConfigLoadError::NameDuplicate(_) => "Found duplicate 'name' in some configurations, please use different names", ConfigLoadError::NameDuplicate(_) => "Found duplicate 'name' in some configurations, please use different names",
ConfigLoadError::UnableToCreateDefaultConfig => "Could not generate default config file", ConfigLoadError::UnableToCreateDefaultConfig => "Could not generate default config file",
} }
@ -397,18 +420,18 @@ mod tests {
} }
#[test] #[test]
fn test_specific_config_does_not_have_reserved_fields() { fn test_user_defined_config_does_not_have_reserved_fields() {
let working_config_file = create_tmp_file(r###" let working_config_file = create_tmp_file(r###"
backend: Clipboard backend: Clipboard
"###); "###);
let config = Configs::load_config(working_config_file.path()); let config = Configs::load_config(working_config_file.path());
assert_eq!(config.unwrap().validate_specific_config(), true); assert_eq!(config.unwrap().validate_user_defined_config(), true);
} }
#[test] #[test]
fn test_specific_config_has_reserved_fields_config_caching_interval() { fn test_user_defined_config_has_reserved_fields_config_caching_interval() {
let working_config_file = create_tmp_file(r###" let working_config_file = create_tmp_file(r###"
# This should not happen in an app-specific config # This should not happen in an app-specific config
@ -416,11 +439,11 @@ mod tests {
"###); "###);
let config = Configs::load_config(working_config_file.path()); let config = Configs::load_config(working_config_file.path());
assert_eq!(config.unwrap().validate_specific_config(), false); assert_eq!(config.unwrap().validate_user_defined_config(), false);
} }
#[test] #[test]
fn test_specific_config_has_reserved_fields_toggle_key() { fn test_user_defined_config_has_reserved_fields_toggle_key() {
let working_config_file = create_tmp_file(r###" let working_config_file = create_tmp_file(r###"
# This should not happen in an app-specific config # This should not happen in an app-specific config
@ -428,11 +451,11 @@ mod tests {
"###); "###);
let config = Configs::load_config(working_config_file.path()); let config = Configs::load_config(working_config_file.path());
assert_eq!(config.unwrap().validate_specific_config(), false); assert_eq!(config.unwrap().validate_user_defined_config(), false);
} }
#[test] #[test]
fn test_specific_config_has_reserved_fields_toggle_interval() { fn test_user_defined_config_has_reserved_fields_toggle_interval() {
let working_config_file = create_tmp_file(r###" let working_config_file = create_tmp_file(r###"
# This should not happen in an app-specific config # This should not happen in an app-specific config
@ -440,11 +463,11 @@ mod tests {
"###); "###);
let config = Configs::load_config(working_config_file.path()); let config = Configs::load_config(working_config_file.path());
assert_eq!(config.unwrap().validate_specific_config(), false); assert_eq!(config.unwrap().validate_user_defined_config(), false);
} }
#[test] #[test]
fn test_specific_config_has_reserved_fields_backspace_limit() { fn test_user_defined_config_has_reserved_fields_backspace_limit() {
let working_config_file = create_tmp_file(r###" let working_config_file = create_tmp_file(r###"
# This should not happen in an app-specific config # This should not happen in an app-specific config
@ -452,7 +475,7 @@ mod tests {
"###); "###);
let config = Configs::load_config(working_config_file.path()); let config = Configs::load_config(working_config_file.path());
assert_eq!(config.unwrap().validate_specific_config(), false); assert_eq!(config.unwrap().validate_user_defined_config(), false);
} }
#[test] #[test]
@ -516,15 +539,14 @@ mod tests {
let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME); let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME);
fs::write(default_path, DEFAULT_CONFIG_FILE_CONTENT); fs::write(default_path, DEFAULT_CONFIG_FILE_CONTENT);
let specific_path = tmp_dir.path().join("specific.yml"); let user_defined_path = create_user_config_file(tmp_dir.path(), "specific.yml", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
config_caching_interval: 10000 config_caching_interval: 10000
"###); "###);
let user_defined_path_copy = user_defined_path.clone();
let config_set = ConfigSet::load(tmp_dir.path()); let config_set = ConfigSet::load(tmp_dir.path());
assert!(config_set.is_err()); assert!(config_set.is_err());
assert_eq!(config_set.unwrap_err(), ConfigLoadError::InvalidParameter(specific_path_copy)) assert_eq!(config_set.unwrap_err(), ConfigLoadError::InvalidParameter(user_defined_path_copy))
} }
#[test] #[test]
@ -533,15 +555,14 @@ mod tests {
let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME); let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME);
fs::write(default_path, DEFAULT_CONFIG_FILE_CONTENT); fs::write(default_path, DEFAULT_CONFIG_FILE_CONTENT);
let specific_path = tmp_dir.path().join("specific.yml"); let user_defined_path = create_user_config_file(tmp_dir.path(), "specific.yml", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
backend: Clipboard backend: Clipboard
"###); "###);
let user_defined_path_copy = user_defined_path.clone();
let config_set = ConfigSet::load(tmp_dir.path()); let config_set = ConfigSet::load(tmp_dir.path());
assert!(config_set.is_err()); assert!(config_set.is_err());
assert_eq!(config_set.unwrap_err(), ConfigLoadError::MissingName(specific_path_copy)) assert_eq!(config_set.unwrap_err(), ConfigLoadError::MissingName(user_defined_path_copy))
} }
pub fn create_temp_espanso_directory() -> TempDir { pub fn create_temp_espanso_directory() -> TempDir {
@ -552,23 +573,32 @@ mod tests {
tmp_dir tmp_dir
} }
pub fn create_temp_file_in_dir(tmp_dir: &TempDir, name: &str, content: &str) -> PathBuf { pub fn create_temp_file_in_dir(tmp_dir: &PathBuf, name: &str, content: &str) -> PathBuf {
let specific_path = tmp_dir.path().join(name); let user_defined_path = tmp_dir.join(name);
let specific_path_copy = specific_path.clone(); let user_defined_path_copy = user_defined_path.clone();
fs::write(specific_path, content); fs::write(user_defined_path, content);
specific_path_copy user_defined_path_copy
}
pub fn create_user_config_file(tmp_dir: &Path, name: &str, content: &str) -> PathBuf {
let user_config_dir = tmp_dir.join(USER_CONFIGS_FOLDER_NAME);
if !user_config_dir.exists() {
create_dir_all(&user_config_dir);
}
create_temp_file_in_dir(&user_config_dir, name, content)
} }
#[test] #[test]
fn test_config_set_specific_file_duplicate_name() { fn test_config_set_specific_file_duplicate_name() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let user_defined_path = create_user_config_file(tmp_dir.path(), "specific.yml", r###"
name: specific1 name: specific1
"###); "###);
let specific_path2 = create_temp_file_in_dir(&tmp_dir, "specific2.yml", r###" let user_defined_path2 = create_user_config_file(tmp_dir.path(), "specific2.yml", r###"
name: specific1 name: specific1
"###); "###);
@ -578,7 +608,7 @@ mod tests {
} }
#[test] #[test]
fn test_specific_config_set_merge_with_parent_matches() { fn test_user_defined_config_set_merge_with_parent_matches() {
let tmp_dir = TempDir::new().expect("unable to create temp directory"); let tmp_dir = TempDir::new().expect("unable to create temp directory");
let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME); let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME);
fs::write(default_path, r###" fs::write(default_path, r###"
@ -589,9 +619,7 @@ mod tests {
replace: "Bob" replace: "Bob"
"###); "###);
let specific_path = tmp_dir.path().join("specific.yml"); let user_defined_path = create_user_config_file(tmp_dir.path(), "specific1.yml", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
name: specific1 name: specific1
matches: matches:
@ -609,7 +637,7 @@ mod tests {
} }
#[test] #[test]
fn test_specific_config_set_merge_with_parent_matches_child_priority() { fn test_user_defined_config_set_merge_with_parent_matches_child_priority() {
let tmp_dir = TempDir::new().expect("unable to create temp directory"); let tmp_dir = TempDir::new().expect("unable to create temp directory");
let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME); let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME);
fs::write(default_path, r###" fs::write(default_path, r###"
@ -620,9 +648,7 @@ mod tests {
replace: "Bob" replace: "Bob"
"###); "###);
let specific_path = tmp_dir.path().join("specific.yml"); let user_defined_path2 = create_user_config_file(tmp_dir.path(), "specific2.yml", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
name: specific1 name: specific1
matches: matches:
@ -639,7 +665,7 @@ mod tests {
} }
#[test] #[test]
fn test_specific_config_set_exclude_merge_with_parent_matches() { fn test_user_defined_config_set_exclude_merge_with_parent_matches() {
let tmp_dir = TempDir::new().expect("unable to create temp directory"); let tmp_dir = TempDir::new().expect("unable to create temp directory");
let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME); let default_path = tmp_dir.path().join(DEFAULT_CONFIG_FILE_NAME);
fs::write(default_path, r###" fs::write(default_path, r###"
@ -650,9 +676,7 @@ mod tests {
replace: "Bob" replace: "Bob"
"###); "###);
let specific_path = tmp_dir.path().join("specific.yml"); let user_defined_path2 = create_user_config_file(tmp_dir.path(), "specific2.yml", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
name: specific1 name: specific1
exclude_parent_matches: true exclude_parent_matches: true
@ -681,9 +705,7 @@ mod tests {
replace: "Bob" replace: "Bob"
"###); "###);
let specific_path = tmp_dir.path().join("specific.zzz"); let user_defined_path2 = create_user_config_file(tmp_dir.path(), "specific.zzz", r###"
let specific_path_copy = specific_path.clone();
fs::write(specific_path, r###"
name: specific1 name: specific1
exclude_parent_matches: true exclude_parent_matches: true

View File

@ -210,7 +210,7 @@ mod tests {
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use crate::config::ConfigManager; use crate::config::ConfigManager;
use crate::config::tests::{create_temp_espanso_directory, create_temp_file_in_dir}; use crate::config::tests::{create_temp_espanso_directory, create_temp_file_in_dir, create_user_config_file};
struct DummySystemManager { struct DummySystemManager {
title: RefCell<String>, title: RefCell<String>,
@ -252,18 +252,18 @@ mod tests {
fn test_runtime_constructor_regex_load_correctly() { fn test_runtime_constructor_regex_load_correctly() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: myname1 name: myname1
filter_exec: "Title" filter_exec: "Title"
"###); "###);
let specific_path2 = create_temp_file_in_dir(&tmp_dir, "specific2.yml", r###" let specific_path2 = create_user_config_file(&tmp_dir.path(), "specific2.yml", r###"
name: myname2 name: myname2
filter_title: "Yeah" filter_title: "Yeah"
filter_class: "Car" filter_class: "Car"
"###); "###);
let specific_path3 = create_temp_file_in_dir(&tmp_dir, "specific3.yml", r###" let specific_path3 = create_user_config_file(&tmp_dir.path(), "specific3.yml", r###"
name: myname3 name: myname3
filter_title: "Nice" filter_title: "Nice"
"###); "###);
@ -303,18 +303,18 @@ mod tests {
fn test_runtime_constructor_malformed_regexes_are_ignored() { fn test_runtime_constructor_malformed_regexes_are_ignored() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: myname1 name: myname1
filter_exec: "[`-_]" filter_exec: "[`-_]"
"###); "###);
let specific_path2 = create_temp_file_in_dir(&tmp_dir, "specific2.yml", r###" let specific_path2 = create_user_config_file(&tmp_dir.path(), "specific2.yml", r###"
name: myname2 name: myname2
filter_title: "[`-_]" filter_title: "[`-_]"
filter_class: "Car" filter_class: "Car"
"###); "###);
let specific_path3 = create_temp_file_in_dir(&tmp_dir, "specific3.yml", r###" let specific_path3 = create_user_config_file(&tmp_dir.path(), "specific3.yml", r###"
name: myname3 name: myname3
filter_title: "Nice" filter_title: "Nice"
"###); "###);
@ -354,7 +354,7 @@ mod tests {
fn test_runtime_calculate_active_config_specific_title_match() { fn test_runtime_calculate_active_config_specific_title_match() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: chrome name: chrome
filter_title: "Chrome" filter_title: "Chrome"
"###); "###);
@ -372,7 +372,7 @@ mod tests {
fn test_runtime_calculate_active_config_specific_class_match() { fn test_runtime_calculate_active_config_specific_class_match() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: chrome name: chrome
filter_class: "Chrome" filter_class: "Chrome"
"###); "###);
@ -390,7 +390,7 @@ mod tests {
fn test_runtime_calculate_active_config_specific_exec_match() { fn test_runtime_calculate_active_config_specific_exec_match() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: chrome name: chrome
filter_exec: "chrome.exe" filter_exec: "chrome.exe"
"###); "###);
@ -408,7 +408,7 @@ mod tests {
fn test_runtime_calculate_active_config_specific_multi_filter_match() { fn test_runtime_calculate_active_config_specific_multi_filter_match() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: chrome name: chrome
filter_class: Browser filter_class: Browser
filter_exec: "firefox.exe" filter_exec: "firefox.exe"
@ -428,7 +428,7 @@ mod tests {
fn test_runtime_calculate_active_config_no_match() { fn test_runtime_calculate_active_config_no_match() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: firefox name: firefox
filter_title: "Firefox" filter_title: "Firefox"
"###); "###);
@ -447,7 +447,7 @@ mod tests {
fn test_runtime_active_config_cache() { fn test_runtime_active_config_cache() {
let tmp_dir = create_temp_espanso_directory(); let tmp_dir = create_temp_espanso_directory();
let specific_path = create_temp_file_in_dir(&tmp_dir, "specific.yml", r###" let specific_path = create_user_config_file(&tmp_dir.path(), "specific.yml", r###"
name: firefox name: firefox
filter_title: "Firefox" filter_title: "Firefox"
"###); "###);

View File

@ -51,13 +51,14 @@ mod bridge;
mod engine; mod engine;
mod config; mod config;
mod system; mod system;
mod sysdaemon;
mod context; mod context;
mod matcher; mod matcher;
mod package;
mod keyboard; mod keyboard;
mod protocol; mod protocol;
mod clipboard; mod clipboard;
mod extension; mod extension;
mod sysdaemon;
const VERSION: &'static str = env!("CARGO_PKG_VERSION"); const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const LOG_FILE: &str = "espanso.log"; const LOG_FILE: &str = "espanso.log";

0
src/package/mod.rs Normal file
View File