-
-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(WIP) Support configuration file #312
Conversation
@@ -28,7 +32,7 @@ pub struct Config { | |||
#[clap(long = "log", env = "RUST_LOG", default_value = "off")] | |||
pub(crate) env_filter: tracing_subscriber::EnvFilter, | |||
|
|||
#[clap(flatten)] | |||
#[clap(skip)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I skipped it:
- I don't know how to use default values from config files.
- If the parameter is enabled, I should implement that:
- If command-line options are given, then need to use them instead of the config file's value.
pub fn from_config() -> color_eyre::Result<Self> { | ||
let xdg_config_path = env::var_os("XDG_CONFIG_HOME").map(|mut base| { | ||
base.push("/tokio-console/console.toml"); | ||
base | ||
}); | ||
let xdg_view_opt = xdg_config_path.and_then(ViewOptions::from_config); | ||
let current_view_opt = ViewOptions::from_config("console.toml"); | ||
|
||
let config = Config::parse(); | ||
|
||
match xdg_view_opt.or(current_view_opt) { | ||
None => Ok(config), | ||
Some(view_opt) => Ok(Self { | ||
view_options: view_opt, | ||
..config | ||
}), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm worried:
- I don't know woking it on macOS or Windows.
- Some rules are broken.
- ex) it can use
--palette
and--colorterm
.
- ex) it can use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I don't know woking it on macOS or Windows.
I think we might want to look into using the dirs
crate for reading configs from the correct location on multiple platforms. That library has a config_dir
function that returns the correct operating-system-specific config file location.
On macOS, we might also want to additionally check for ~/.console.toml
(and maybe also ~/.config/console.toml
), which are both Linux style locations --- although Apple suggests the use of ~/Library/Application Support
for config files, a lot of people still like to put config files for command-like utilities in ~
or ~.config/
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
config_dir
is exactly what i have wanted. I'll use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good start. I left some suggestions inline.
One higher-level thought is that I'm not sure if it really makes sense to have one set of structs that implements both serde::Deserialize
and clap::Parser
. We might want to structure the command-line arguments and configuration files differently, so we may want to define separate types for reading configs from the command line and from a file, and then combine them into one internal config type that's used to actually configure the console.
On the other hand, it's possible that we can use #[clap(...)]
and #[serde(...)]
attributes to implement any differences between the structure of the command-line arguments and the config file. If this is practical, it might be a bit nicer to not have to convert between multiple structs! But, if the best solution requires us to have separate structs for the CLI and config file, I think that's fine.
no_colors = false | ||
lang = "en_us.UTF-8" | ||
ascii_only = true | ||
palette = "8" | ||
|
||
|
||
[toggles] | ||
color_durations = true | ||
color_terminated = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this checked in for testing purposes? Eventually, I think it could be good to have an example config file with the default options (and comments explaining them) checked into the repo, so that users can see how to configure the console. But, I don't know if it should be "live" --- it might be better to name the example something like "console.example.toml" or similar, so that running the console from the repo directory doesn't actually use those settings...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I added it unintentionally.
Eventually, I provide an example config file or add the explanation to README.
no_colors = false | ||
lang = "en_us.UTF-8" | ||
ascii_only = true | ||
palette = "8" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if it makes sense for the config file to have separate keys for no_colors
and palette
, if we can also write palette = "off"
to disable colors. i'd prefer to not have two separate ways to write the same thing in the config file.
no_colors = false | ||
lang = "en_us.UTF-8" | ||
ascii_only = true | ||
palette = "8" | ||
|
||
|
||
[toggles] | ||
color_durations = true | ||
color_terminated = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it makes sense to match the layout of the config structs exactly in the config file. instead, i think it might be good to group the different configurations into TOML tables, maybe something like this:
[charset]
lang = "en_us.UTF-8"
ascii_only = false
[colors]
enabled = true
palette = "8"
[colors.enable]
durations = true
terminated = true
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds good, I'll try it.
match xdg_view_opt.or(current_view_opt) { | ||
None => Ok(config), | ||
Some(view_opt) => Ok(Self { | ||
view_options: view_opt, | ||
..config | ||
}), | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eventually, I think what we'll want is a function on the Config
type to merge two Config
s, with one overriding the other. I think the behavior we actually want here is something like this:
- read the config file in the platform-specific config location (e.g.
XDG_CONFIG_HOME
) as the "base" config, or use the defaults if there is no config file there - if there is a config file in the current directory, any configs set in that config file override the settings in the "base" config
- any command-line arguments that are set override the configs from both the current directory and the base directory
does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that makes sense. Ok, I'll try it again.
pub fn from_config() -> color_eyre::Result<Self> { | ||
let xdg_config_path = env::var_os("XDG_CONFIG_HOME").map(|mut base| { | ||
base.push("/tokio-console/console.toml"); | ||
base | ||
}); | ||
let xdg_view_opt = xdg_config_path.and_then(ViewOptions::from_config); | ||
let current_view_opt = ViewOptions::from_config("console.toml"); | ||
|
||
let config = Config::parse(); | ||
|
||
match xdg_view_opt.or(current_view_opt) { | ||
None => Ok(config), | ||
Some(view_opt) => Ok(Self { | ||
view_options: view_opt, | ||
..config | ||
}), | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I don't know woking it on macOS or Windows.
I think we might want to look into using the dirs
crate for reading configs from the correct location on multiple platforms. That library has a config_dir
function that returns the correct operating-system-specific config file location.
On macOS, we might also want to additionally check for ~/.console.toml
(and maybe also ~/.config/console.toml
), which are both Linux style locations --- although Apple suggests the use of ~/Library/Application Support
for config files, a lot of people still like to put config files for command-like utilities in ~
or ~.config/
...
@hawkw Thank you for reviewing.
Your input has inspired me to change my implementation approach. I'll try as follows:
On the other hand, I have a problem.
I can implement the first and second points, but I am having difficulty with the third suggestion. Do you have any ideas in this regard? |
I'm trying to rewrite the config parser using clap Builder-API style. It will take some time because I'm doing it while checking to document it. Maybe I'll submit it as another Pull Request. (Should I close this PR?) |
I think the simplest solution would be to just change the structs that derive I don't think this will require the use of the |
That sounds great! I'll try your suggestion. |
Support config files as follows. - $XDG_CONFIG_HOME/tokio-console/console.toml - current configuration (`./console.toml`) ## Test Execute and check debug log. `env -u LANG -u COLORTERM RUST_LOG=debug cargo run` ### case1) no config files ``` DEBUG tokio_console: args.target_addr=http://127.0.0.1:6669/ args.view_options= ViewOptions { no_colors: None, lang: None, ascii_only: None, truecolor: None, palette: None, toggles: ColorToggles { color_durations: None, color_terminated: None } } ``` ### case2) current config file ```toml [charset] lang = "en_us.UTF-8" ascii_only = true [colors] enabled = true palette = "all" truecolor = true [colors.enable] durations = true terminated = true ``` ``` DEBUG tokio_console: args.target_addr=http://127.0.0.1:6669/ args.view_options= ViewOptions { no_colors: Some(false), lang: Some("en_us.UTF-8"), ascii_only: Some(true), truecolor: Some(true), palette: Some(All), toggles: ColorToggles { color_durations: Some(false), color_terminated: Some(false) } } ``` ### case3) XDG config file ```toml [charset] lang = "en_us.UTF-8" ascii_only = true [colors] enabled = true palette = "all" truecolor = true [colors.enable] durations = true terminated = true ``` ``` DEBUG tokio_console: args.target_addr=http://127.0.0.1:6669/ args.view_options= ViewOptions { no_colors: Some(false), lang: Some("en_us.UTF-8"), ascii_only: Some(true), truecolor: Some(true), palette: Some(All), toggles: ColorToggles { color_durations: Some(false), color_terminated: Some(false) } } ``` ### case4) XDG config file and current config file XDG_CONFIG/console.toml ```toml [charset] lang = "en_us.UTF-8" ascii_only = true [colors] enabled = true palette = "all" truecolor = true [colors.enable] durations = true terminated = true ``` ./console.toml ``` [charset] lang = "en_us.UTF-8" ascii_only = false ``` Override the current config file. ``` DEBUG tokio_console: args.target_addr=http://127.0.0.1:6669/ args.view_options= ViewOptions { no_colors: Some(false), lang: Some("en_us.UTF-8"), ascii_only: Some(false), <-- override truecolor: Some(true), palette: Some(All), toggles: ColorToggles { color_durations: Some(false), color_terminated: Some(false) } } ``` ### case5) XDG config file, current config file, and command-line option XDG_CONFIG/console.toml ```toml [charset] lang = "en_us.UTF-8" ascii_only = true [colors] enabled = true palette = "all" truecolor = true [colors.enable] durations = true terminated = true ``` ./console.toml ``` [charset] lang = "en_us.UTF-8" ascii_only = false ``` `env -u LANG -u COLORTERM RUST_LOG=debug cargo run -- --palette 8` Override the current config file and command-line option. ``` DEBUG tokio_console: args.target_addr=http://127.0.0.1:6669/ args.view_options= ViewOptions { no_colors: Some(false), lang: Some("en_us.UTF-8"), ascii_only: Some(false), <-- override truecolor: Some(true), palette: Some(Ansi8), <-- override toggles: ColorToggles { color_durations: Some(false), color_terminated: Some(false) } } ``` Relates to - #310 - #312 - #312 (comment) Closes #310
This pull request is a draft of the supporting configuration file.
I'm worried about implementations as follows.
$XDG_CONFIG_HOME/tokio-console/console.toml
./console.toml
)I want some advice about these implementations.
(Should I rewrite clap builder api style?)
Relates to #310