-
Notifications
You must be signed in to change notification settings - Fork 56
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
feat(node): load args from file #494
base: main
Are you sure you want to change the base?
Conversation
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.
A welcome change! This has been in the talks for a while but was never properly implemented, thanks a lot for this!
A few points still need clarifying / changing, see comments below.
README.md
Outdated
### Configuration files | ||
|
||
You can load the arguments directly from a file for ease of use. | ||
The supported file formats are `json`, `toml` and `yaml`. | ||
You can find examples on `configs/args`. |
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.
configs/args
should be a hyperlink to the related folder on the repo.
crates/madara/node/src/cli/mod.rs
Outdated
/// A path to a config file | ||
#[clap(env = "MADARA_CONFIG_FILE", long, value_name = "NAME")] | ||
pub config_file: Option<PathBuf>, |
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 about the ergonomics of this. I think we should keep this here, but also try and auto-detect a config file in known locations (such as the current working directory), and then this option can be used for unusual configurations. Also this needs more CLI-facing documentation, such as which formats are allowed.
crates/madara/node/src/main.rs
Outdated
let cli_args = RunCmd::parse().apply_arg_preset(); | ||
|
||
// Put values from config file if they don't already exist. | ||
if let Some(config_path) = cli_args.config_file.clone() { | ||
config = match config_path.extension() { | ||
None => bail!("Unsupported file type for config file."), | ||
Some(os_str) => match os_str.to_str() { | ||
Some("toml") => config.join(Toml::file(config_path)), | ||
Some("json") => config.join(Json::file(config_path)), | ||
Some("yaml") => config.join(Yaml::file(config_path)), | ||
_ => bail!("Unsupported file type for config file."), | ||
}, | ||
} | ||
} |
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.
As mentioned before, I feel like we should first check for config files in some known location and only if it is not found then refer to the cli args to potentially load an arg file. It feels a little un-ergonomic if I have to specify a cli arg in order to load an arg file in order not to use cli args 🤪
It might be worth adding a "default" config file to the repo as well, so users can just compile madara and run it with |
Good idea! I'll work on one right away. |
709cd3b
to
41983cf
Compare
@Trantorian1 I have run into an issue when doing the changes you requested. I thought that figment was correctly setting up the arguments in the priority defined in the issue, being cli > env > file. However, when setting up the default file, I realized I couldn't overwrite the values in no way. Searching online, I found the underlying issue and solution, but it's not flawless; it basically requires to have to identical structures, one with all options and one with definitive struct, which would make the whole cli very verbose. If you're curious, I found the information here. I tried another config layering crate twelf, but the documentation is outdated, the examples with clap are incomplete, and overall the experience was very poor. From my tests, I gathered the problem is it doesn't really like nested structures. When trying to deserialize, it kept complaining about missing certain fields. I tested clap-serde-derive, which is small and not very robust, and it also needs an additional structs and just didn't work as I expected, presenting several other problems I couldn't fix. Finally, config-rs is one of the most downloaded and used crates dealing with layering of configs, but it doesn't explicitly support clap and examples are not clear on how I could merge both. Any suggestions are deeply appreciated, as I don't see a clear and best way forward. Cheers! |
This is unfortunate :/ It's surprising that the ecosystem hasn't developed a crate with unified cli and file parsing yet. I guess this really just is an ergonomics problem, just having a config file is already a good starting point. Just a thought, but could we not first check if a config file exists in Anyway, thanks a lot for the deep investigation into this topic :) |
(Also this is more of a nitpick but please avoid force-pushing after a review since this makes it impossible to view "changes since last review" 😅) |
crates/madara/node/src/cli/mod.rs
Outdated
@@ -134,9 +134,15 @@ impl ArgsPresetParams { | |||
), | |||
)] | |||
pub struct RunCmd { | |||
/// A path to a config file. | |||
/// It builds the arguments from files, env and cli. |
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 second line feels a bit confusing in that it seems to depict arg parsing generally? Maybe we should just remove it and keep the last line.
The original idea is that if you had a file, but wanted to change one argument, you could do that through the cli; mix and match between different sources. Your solution works, but we make it exclusive, either we get all information from the file or through the cli. I'm going do your suggestion, but a little different: if there's any argument on the cli, we use all of the cli. This is so we can have the default So it'll be like this:
|
Okay got it, so we get file configuration but without CLI override. This makes sense. |
92678ab
to
e238c9b
Compare
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.
@GMKrieger looking good!
I would love to add something that test this in CI.
Maybe we can replicate the JS E2E test (they take very little to run) and re-execute with this?
cc @Trantorian1
I would generally be in agreement. We have already had regressions in the past where certain argument configurations no longer worked as expected after a merge since there was no test on this. Then again, this also feels like adding scope onto this PR |
aab9224
to
36ee253
Compare
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.
Lets fix CI, the rest LGTM!
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.
Actually Ill leave this with RFC until we fix CI
@GMKrieger
f69e27f
to
03e5690
Compare
03e5690
to
07d53f5
Compare
Pull Request type
What is the current behavior?
Currently, the node doesn't allow arguments to be loaded from a file.
Resolves: #285
What is the new behavior?
Does this introduce a breaking change?
No.
Other information
I used figment, as it was the crate that worked best, but I know there are others, mainly twelf and config. If someone has experience with them, please, let me know!