Change default config structure
This commit is contained in:
parent
a0b0842273
commit
efc6a9c860
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
"###);
|
"###);
|
||||||
|
|
|
@ -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
0
src/package/mod.rs
Normal file
Loading…
Reference in New Issue
Block a user