有没有办法让拍手使用文件中的默认值?
Is there a way to get clap to use default values from a file?
我正在使用 clap 编写一个 CLI 来解析我的参数。我想为选项提供默认值,但如果有配置文件,配置文件应该胜过默认值。
设置命令行参数的优先级高于默认值很容易,但我想要的优先级顺序为:
- 命令行参数
- 配置文件
- 默认值
如果配置文件不是由命令行选项设置的,设置它也很容易,只需在 运行 parse_args
之前解析配置文件并提供来自解析后的配置文件为 default_value
。问题是,如果您在命令行中指定配置文件,则只有在解析之后才能更改默认值。
我能想到的唯一方法是不设置 default_value
,然后在 value_of
中手动匹配 ""
。问题是,在那种情况下,clap 将无法构建有用的 --help
.
有没有办法让 clap 读取配置文件本身?
来自 clap 关于 default_value
的文档:
NOTE: If the user does not use this argument at runtime ArgMatches::is_present
will still return true. If you wish to determine whether the argument was used at runtime or not, consider ArgMatches::occurrences_of
which will return 0
if the argument was not used at runtime.
https://docs.rs/clap/2.32.0/clap/struct.Arg.html#method.default_value
这可用于获取您描述的行为:
extern crate clap;
use clap::{App, Arg};
use std::fs::File;
use std::io::prelude::*;
fn main() {
let matches = App::new("MyApp")
.version("0.1.0")
.about("Example for Whosebug")
.arg(
Arg::with_name("config")
.short("c")
.long("config")
.value_name("FILE")
.help("Sets a custom config file"),
)
.arg(
Arg::with_name("example")
.short("e")
.long("example")
.help("Sets an example parameter")
.default_value("default_value")
.takes_value(true),
)
.get_matches();
let mut value = String::new();
if let Some(c) = matches.value_of("config") {
let file = File::open(c);
match file {
Ok(mut f) => {
// Note: I have a file `config.txt` that has contents `file_value`
f.read_to_string(&mut value).expect("Error reading value");
}
Err(_) => println!("Error reading file"),
}
// Note: this lets us override the config file value with the
// cli argument, if provided
if matches.occurrences_of("example") > 0 {
value = matches.value_of("example").unwrap().to_string();
}
} else {
value = matches.value_of("example").unwrap().to_string();
}
println!("Value for config: {}", value);
}
// Code above licensed CC0
// https://creativecommons.org/share-your-work/public-domain/cc0/
导致行为:
./target/debug/example
Value for config: default_value
./target/debug/example --example cli_value
Value for config: cli_value
./target/debug/example --config config.txt
Value for config: file_value
./target/debug/example --example cli_value --config config.txt
Value for config: cli_value
我正在使用 clap 编写一个 CLI 来解析我的参数。我想为选项提供默认值,但如果有配置文件,配置文件应该胜过默认值。
设置命令行参数的优先级高于默认值很容易,但我想要的优先级顺序为:
- 命令行参数
- 配置文件
- 默认值
如果配置文件不是由命令行选项设置的,设置它也很容易,只需在 运行 parse_args
之前解析配置文件并提供来自解析后的配置文件为 default_value
。问题是,如果您在命令行中指定配置文件,则只有在解析之后才能更改默认值。
我能想到的唯一方法是不设置 default_value
,然后在 value_of
中手动匹配 ""
。问题是,在那种情况下,clap 将无法构建有用的 --help
.
有没有办法让 clap 读取配置文件本身?
来自 clap 关于 default_value
的文档:
NOTE: If the user does not use this argument at runtime
ArgMatches::is_present
will still return true. If you wish to determine whether the argument was used at runtime or not, considerArgMatches::occurrences_of
which will return0
if the argument was not used at runtime.https://docs.rs/clap/2.32.0/clap/struct.Arg.html#method.default_value
这可用于获取您描述的行为:
extern crate clap;
use clap::{App, Arg};
use std::fs::File;
use std::io::prelude::*;
fn main() {
let matches = App::new("MyApp")
.version("0.1.0")
.about("Example for Whosebug")
.arg(
Arg::with_name("config")
.short("c")
.long("config")
.value_name("FILE")
.help("Sets a custom config file"),
)
.arg(
Arg::with_name("example")
.short("e")
.long("example")
.help("Sets an example parameter")
.default_value("default_value")
.takes_value(true),
)
.get_matches();
let mut value = String::new();
if let Some(c) = matches.value_of("config") {
let file = File::open(c);
match file {
Ok(mut f) => {
// Note: I have a file `config.txt` that has contents `file_value`
f.read_to_string(&mut value).expect("Error reading value");
}
Err(_) => println!("Error reading file"),
}
// Note: this lets us override the config file value with the
// cli argument, if provided
if matches.occurrences_of("example") > 0 {
value = matches.value_of("example").unwrap().to_string();
}
} else {
value = matches.value_of("example").unwrap().to_string();
}
println!("Value for config: {}", value);
}
// Code above licensed CC0
// https://creativecommons.org/share-your-work/public-domain/cc0/
导致行为:
./target/debug/example
Value for config: default_value
./target/debug/example --example cli_value
Value for config: cli_value
./target/debug/example --config config.txt
Value for config: file_value
./target/debug/example --example cli_value --config config.txt
Value for config: cli_value