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
CLI Improvement #236
CLI Improvement #236
Conversation
6df6bab
to
c3641d3
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.
Right now the configuration of the node and SE works differently. I think we should make them more consistent.
I would suggest allowing the user to use all three methods: CLI arguments, a config file, and env vars. We could make it so you pass the path to the config file as a positional argument (interledger node ./path/to/config
) so that it doesn't conflict with the CLI arguments.
The main benefit I see of allowing all options to be passed in as CLI args is that you could get the explanation of all of them by running --help
let mut config = config::Config::new(); | ||
config.merge(self.clone()).unwrap(); | ||
config | ||
.merge(config::Environment::with_prefix("ILP")) |
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.
Should these be prefixed with ILP
or something Ethereum-related?
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 thought ILP
was required at least and adding ETH_SE
or something would be too much (it becomes like ILP_ETH_SE_ETHEREUM_ENDPOINT
), so... I think just ILP
is enough🤔
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 just left it as ILP
but if there are more suitable options, it would be easy to fix.
crates/interledger-settlement-engines/tests/eth_ledger_settlement.rs
Outdated
Show resolved
Hide resolved
I fixed some of the issues but I still have to fix documents. I'm working on this. The biggest changes are:
|
4557bf6
to
b5d75d3
Compare
I think I've addressed issues, if you have anything else, please tell me. |
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 direction looks good to me. The main points I'd make are that:
- configuration files should be passed in with
node config.yml
instead ofnode --config config.yml
- we should try to use the
required
flag on Clap so that the--help
prints correctly
Currently it accepts like this.
I've tried for several hours to hack this... but I couldn't come up with how to cleanly and entirely realize this... Anyway, let me try some more. |
The problem is that if we set
|
Refactored entirely.
|
945b207
to
942ec2a
Compare
Ok(path) | ||
} | ||
|
||
fn merge_args(config: &mut Config, matches: &ArgMatches) { |
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.
FYI, you get a lot of the logic being added here for free with Abscissa, which allows you to impl this trait to merge command-line options into the configuration:
https://docs.rs/abscissa_core/0.3.0/abscissa_core/config/trait.Override.html
let file_config = file_config.collect().unwrap(); | ||
|
||
// if the key is not defined in the given config already, set it to the config | ||
// because the original values override the ones from the 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.
Should the file take precedence over the CLI args or vice versa?
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 see the clear difference because, in either case, we can override it by environment variables. hmmm do you have a preference?
crates/interledger/src/main.rs
Outdated
("accounts", Some(node_accounts_matches)) => match node_accounts_matches.subcommand() { | ||
("add", Some(node_accounts_add_matches)) => { | ||
merge_args(&mut config, &node_accounts_add_matches); | ||
runner.run(get_or_error(config.try_into::<NodeAccountsAddOpt>())); |
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 think this code would be clearer without the Runner
thing. You could just copy that code into here, since it's not actually abstracting anything away
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 wanted to make it readable. In the original code, there were many lines between subcommand matches, so it looked hard to read for me. I think this is clearer than inserting the code here because we can understand it intuitively as:
- Here is to parse subcommands
- There are many subcommands and some of these also have its own subcommands
- Subcommands execute some logic using options
I think too long code is hard to understand. Isn't breaking the responsibility into some parts a good method? At least, I've believed so.
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.
ummm but it actually doesn't abstract. Don't you also want to make it just a fn
?
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.
Yeah I think it would be simpler to just use a fn
instead of the Runner
trait
@@ -47,7 +47,7 @@ fn three_nodes() { | |||
|
|||
let node1 = InterledgerNode { | |||
ilp_address: Address::from_str("example.one").unwrap(), | |||
default_spsp_account: Some(0), | |||
default_spsp_account: None, |
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.
Shouldn't this be set to one of the accounts?
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.
No need, all tests explicitly declare the accounts they're sending to - pushing a PR which requires this type to always be Username
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.
Thank you.
docs/operating-manuals/README.md
Outdated
|
||
- Environment variables | ||
- Configuration files | ||
- Command line arguments |
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.
It's slightly confusing that this list is in the opposite order as the one above. I would just write this list once and clarify there what the prioritization is
Feature request from: #108 (comment) We want to add an option to load config files from stdin, allowing a user to do |
Which format would you like to pass to STDIN? I'm asking because unfortunately |
8c55ac4
to
f55d3c4
Compare
So the config module understands which deserializer to use based on the config file extension ( Hacky idea (doesn't compile) let parsed = serde_yaml::from_str(&s);
if parsed.is_err() {
parsed = serde_json::from_str(&s);
} |
Since our CLI supports YAML, TOML, JSON, etc... thanks to Ok, I'll try. |
bf7f5f1
to
04adda5
Compare
FYI: I've tested encrypting a YAML configuration file with This looks good to me, do we need to add more things? |
Thank you @gakonst , unfortunately I found a bug. If it is run on Docker, it tries to read from STDIN which causes an IO-block. It is because I'm trying to fix this. |
^ was not a problem, just using |
1da19d8
to
c4b1c36
Compare
crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs
Outdated
Show resolved
Hide resolved
crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs
Outdated
Show resolved
Hide resolved
crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs
Outdated
Show resolved
Hide resolved
crates/interledger/src/main.rs
Outdated
("accounts", Some(node_accounts_matches)) => match node_accounts_matches.subcommand() { | ||
("add", Some(node_accounts_add_matches)) => { | ||
merge_args(&mut config, &node_accounts_add_matches); | ||
runner.run(get_or_error(config.try_into::<NodeAccountsAddOpt>())); |
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.
Yeah I think it would be simpler to just use a fn
instead of the Runner
trait
Thank you Evan for taking time, I'll check and fix. |
Fixed most points, I'm wondering just: #236 (comment) |
22d7463
to
1d0c8f4
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.
Looking good. Let's just change the parameter names and then get this merged in
crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs
Outdated
Show resolved
Hide resolved
crates/interledger-settlement-engines/src/engines/ethereum_ledger/eth_engine.rs
Outdated
Show resolved
Hide resolved
61ef567
to
f1f5b87
Compare
3e66dd8
to
d129e09
Compare
Every command accepts arguments, config file settings, env vars. `interledger` and `interledger-settlement-engines` are almost consistent. BREAKING CHANGE: Some arguments are now obsolete. On interledger package: server_secret -> secret_seed, btp_server -> btp_server_url, http_server -> http_server_url, redis_connection -> redis_url, http_address -> http_bind_address, settlement_address -> settlement_api_bind_address, btp_address -> btp_bind_address, btp_uri -> btp_server_url, http_url -> http_server_url. On interledger-settlement-engines package: http_address -> settlement_api_bind_address, ethereum_endpoint -> ethereum_url, redis_uri -> redis_url. Signed-off-by: Taiga Nakayama <dora@dora-gt.jp>
d129e09
to
7e2b46e
Compare
Merged in as #290 |
Usingstructopt
to reduce the complexity of the source.Using#[allow(clippy::large_enum_variant)]
because options of account add command are too many. It may be difficult to fix this unless we make a patch tostructopt
There is someone doing the sameBREAKING CHANGES
key
argument. Useprivate_key
instead.Ethereum settlement engine now doesn't acceptwatch_incoming
flag because it was a flag and default_value was true, which doesn't make sense andstructopt
considers it as an error. Instead I implementedwithout_incoming_watcher
flag which disables incoming watcher.structopt
:help: message: default_value is meaningless for bool
node
now doesn't acceptilp_address
argument. Insteadaddress
argument orILP_ADDRESS
env var will be accepted.