From 4e83a992dc49eb411b35bd44096ad218433dc170 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Mon, 2 Oct 2023 14:53:08 +0300 Subject: [PATCH 1/4] Added support for dot config (.typstfmt.toml) --- src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 6261556..698fd47 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ use typstfmt_lib::{format, Config}; const VERSION: &str = env!("TYPSTFMT_VERSION"); const CONFIG_FILE_NAME: &str = "typstfmt.toml"; +const DOT_CONFIG_FILE_NAME: &str = ".typstfmt.toml"; const HELP: &str = r#"Format Typst code usage: typstfmt [options] [file...] @@ -191,7 +192,8 @@ fn main() -> Result<(), lexopt::Error> { } let config = { - if let Ok(mut f) = File::options().read(true).open(CONFIG_FILE_NAME) { + let open_config = |file_name| File::options().read(true).open(file_name); + if let Ok(mut f) = open_config(CONFIG_FILE_NAME).or(open_config(DOT_CONFIG_FILE_NAME)) { let mut buf = String::default(); f.read_to_string(&mut buf).unwrap_or_else(|err| { panic!("Failed to read config file {CONFIG_FILE_NAME:?}: {err}") From a4b82ee08328feb00d51b1a1cbec829397695184 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Sun, 29 Oct 2023 19:57:05 +0300 Subject: [PATCH 2/4] chore(config name): removed `DOT_CONFIG_FILE_NAME` Added explanation for the removal. --- src/main.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index 698fd47..ea7c2ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,8 +10,12 @@ use lexopt::prelude::*; use typstfmt_lib::{format, Config}; const VERSION: &str = env!("TYPSTFMT_VERSION"); +// Dot file is only used once when reading existing config file, therefore there +// is no need in creating a `const DOT_CONFIG_FILE_NAME`. And even if this +// constant was created, we would have to duplicate the whole string slice, +// because `format!(".{CONFIG_FILE_NAME}")` (non-const function) cannot be +// applied to `const` (or `static`) values in Rust (1.72.1). const CONFIG_FILE_NAME: &str = "typstfmt.toml"; -const DOT_CONFIG_FILE_NAME: &str = ".typstfmt.toml"; const HELP: &str = r#"Format Typst code usage: typstfmt [options] [file...] @@ -193,7 +197,9 @@ fn main() -> Result<(), lexopt::Error> { let config = { let open_config = |file_name| File::options().read(true).open(file_name); - if let Ok(mut f) = open_config(CONFIG_FILE_NAME).or(open_config(DOT_CONFIG_FILE_NAME)) { + if let Ok(mut f) = + open_config(CONFIG_FILE_NAME).or(open_config(&format!(".{CONFIG_FILE_NAME}"))) + { let mut buf = String::default(); f.read_to_string(&mut buf).unwrap_or_else(|err| { panic!("Failed to read config file {CONFIG_FILE_NAME:?}: {err}") From 449c484a5a6a92561dac8392673c8137b6c95ed6 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Sun, 29 Oct 2023 20:34:36 +0300 Subject: [PATCH 3/4] feat(config file): warn when multiple configs found --- src/main.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index ea7c2ab..9af873f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,11 +10,10 @@ use lexopt::prelude::*; use typstfmt_lib::{format, Config}; const VERSION: &str = env!("TYPSTFMT_VERSION"); -// Dot file is only used once when reading existing config file, therefore there -// is no need in creating a `const DOT_CONFIG_FILE_NAME`. And even if this -// constant was created, we would have to duplicate the whole string slice, -// because `format!(".{CONFIG_FILE_NAME}")` (non-const function) cannot be -// applied to `const` (or `static`) values in Rust (1.72.1). +// `DOT_CONFIG_FILE_NAME` is not created as a const due to the fact that we +// would have to duplicate the whole string slice, because +// `format!(".{CONFIG_FILE_NAME}")` (non-const function) cannot be applied to +// `const` (or `static`) values in Rust (1.72.1). const CONFIG_FILE_NAME: &str = "typstfmt.toml"; const HELP: &str = r#"Format Typst code @@ -197,9 +196,17 @@ fn main() -> Result<(), lexopt::Error> { let config = { let open_config = |file_name| File::options().read(true).open(file_name); - if let Ok(mut f) = - open_config(CONFIG_FILE_NAME).or(open_config(&format!(".{CONFIG_FILE_NAME}"))) - { + let config = open_config(CONFIG_FILE_NAME); + let dot_config_file_name = format!(".{CONFIG_FILE_NAME}"); + let dot_config = open_config(&dot_config_file_name); + if config.is_ok() && dot_config.is_ok() { + eprintln!( + "Warning! Both \"{first}\" and \"{second}\" are present. Using \"{first}\".", + first = CONFIG_FILE_NAME, + second = dot_config_file_name + ); + } + if let Ok(mut f) = config.or(dot_config) { let mut buf = String::default(); f.read_to_string(&mut buf).unwrap_or_else(|err| { panic!("Failed to read config file {CONFIG_FILE_NAME:?}: {err}") From 8e6081fea03a6b5f7cb714ddd617eae3254bfc93 Mon Sep 17 00:00:00 2001 From: Andrew Voynov Date: Tue, 31 Oct 2023 22:22:24 +0300 Subject: [PATCH 4/4] feat(UX): included config name into error messages Changed only error messages that are related to the reading/parsing of a config file. --- src/main.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index b5b1ebe..a09c4a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -222,19 +222,30 @@ fn main() -> Result<(), lexopt::Error> { let config = open_config(CONFIG_FILE_NAME); let dot_config_file_name = format!(".{CONFIG_FILE_NAME}"); let dot_config = open_config(&dot_config_file_name); - if config.is_ok() && dot_config.is_ok() { + let is_config_ok = config.is_ok(); + if is_config_ok && dot_config.is_ok() { eprintln!( - "Warning! Both \"{first}\" and \"{second}\" are present. Using \"{first}\".", + "Warning! Both {first:?} and {second:?} are present. Using {first:?}.", first = CONFIG_FILE_NAME, second = dot_config_file_name ); } if let Ok(mut f) = config.or(dot_config) { let mut buf = String::default(); + let used_config_file_name = if is_config_ok { + CONFIG_FILE_NAME + } else { + &dot_config_file_name + }; f.read_to_string(&mut buf).unwrap_or_else(|err| { - panic!("Failed to read config file {CONFIG_FILE_NAME:?}: {err}") + panic!("Failed to read config file {used_config_file_name:?}: {err}"); }); - Config::from_toml(&buf).unwrap_or_else(|e| panic!("Config file invalid: {e}.\nYou'll maybe have to delete it and use -C to create a default config file.")) + Config::from_toml(&buf).unwrap_or_else(|err| { + panic!( + "Config file {used_config_file_name:?} is invalid: {err}.\n{}", + "You'll maybe have to delete it and use -C to create a default config file." + ) + }) } else { let config_path = confy::get_configuration_file_path(APP_NAME, APP_NAME) .unwrap_or_else(|e| panic!("Error loading global configuration file: {e}"));