Support parsing value from ENV variable
This commit is contained in:
parent
b0f67a06de
commit
5c9d507930
@ -153,6 +153,14 @@ completely replaced by calling `options.custom_help`. Note that you might
|
||||
also want to override the positional help by calling `options.positional_help`.
|
||||
|
||||
|
||||
## Value from ENV variable
|
||||
|
||||
When parameter is not set, value will be fetched from an environment variable (if such variable is defined).
|
||||
|
||||
```cpp
|
||||
cxxopts::value<int>()->env("MY_VAR")
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
Putting all together:
|
||||
|
||||
@ -314,6 +314,15 @@ namespace cxxopts
|
||||
virtual std::shared_ptr<Value>
|
||||
implicit_value(const std::string& value) = 0;
|
||||
|
||||
virtual std::shared_ptr<Value>
|
||||
env(const std::string& var) = 0;
|
||||
|
||||
virtual bool
|
||||
has_env() const = 0;
|
||||
|
||||
virtual std::string
|
||||
get_env_var() const = 0;
|
||||
|
||||
virtual std::shared_ptr<Value>
|
||||
no_implicit_value() = 0;
|
||||
|
||||
@ -888,6 +897,26 @@ namespace cxxopts
|
||||
return m_implicit_value;
|
||||
}
|
||||
|
||||
std::shared_ptr<Value>
|
||||
env(const std::string& var)
|
||||
{
|
||||
m_env = true;
|
||||
m_env_var = var;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
bool
|
||||
has_env() const
|
||||
{
|
||||
return m_env;
|
||||
}
|
||||
|
||||
std::string
|
||||
get_env_var() const
|
||||
{
|
||||
return m_env_var;
|
||||
}
|
||||
|
||||
bool
|
||||
is_boolean() const
|
||||
{
|
||||
@ -913,9 +942,11 @@ namespace cxxopts
|
||||
|
||||
bool m_default = false;
|
||||
bool m_implicit = false;
|
||||
bool m_env = false;
|
||||
|
||||
std::string m_default_value;
|
||||
std::string m_implicit_value;
|
||||
std::string m_env_var;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -1961,6 +1992,15 @@ ParseResult::parse(int& argc, char**& argv)
|
||||
if(value.has_default() && !store.count() && !store.has_default()){
|
||||
parse_default(detail);
|
||||
}
|
||||
|
||||
if(value.has_env() && store.count() < 1){
|
||||
const char* env = std::getenv(value.get_env_var().c_str());
|
||||
if(env){
|
||||
std::string str(env);
|
||||
store.parse(detail, str);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (consume_remaining)
|
||||
|
||||
@ -774,3 +774,39 @@ TEST_CASE("Option add with add_option(string, Option)", "[options]") {
|
||||
CHECK(result["aggregate"].as<int>() == 4);
|
||||
CHECK(result["test"].as<int>() == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("Value from ENV variable", "[options]") {
|
||||
cxxopts::Options options("Reads value from ENV", " - if no parameter value is passed");
|
||||
|
||||
options.add_options("", {
|
||||
{"b,bar", "bar option", cxxopts::value<int>()->env("CXXOPTS_BAR")},
|
||||
{"f,foo", "foo option", cxxopts::value<int>()->env("CXXOPTS_FOO")},
|
||||
{"z,baz", "baz option", cxxopts::value<int>()->env("CXXOPTS_BAZ")->default_value("99")},
|
||||
{"e,empty", "empty option", cxxopts::value<int>()->env("CXXOPTS_EMPTY")->default_value("1")},
|
||||
});
|
||||
|
||||
putenv((char*)"CXXOPTS_FOO=7");
|
||||
putenv((char*)"CXXOPTS_BAR=8");
|
||||
putenv((char*)"CXXOPTS_BAZ=9");
|
||||
|
||||
Argv argv_({
|
||||
"test",
|
||||
"--foo",
|
||||
"5"
|
||||
});
|
||||
auto argc = argv_.argc();
|
||||
char** argv = argv_.argv();
|
||||
auto result = options.parse(argc, argv);
|
||||
|
||||
CHECK(result.arguments().size()==1);
|
||||
CHECK(options.groups().size() == 1);
|
||||
CHECK(result.count("foo") == 1);
|
||||
// value passed as an argument should take precedence
|
||||
CHECK(result["foo"].as<int>() == 5);
|
||||
// from ENV variable
|
||||
CHECK(result["bar"].as<int>() == 8);
|
||||
// from ENV variable
|
||||
CHECK(result["baz"].as<int>() == 9);
|
||||
// env not defined, should fallback to default value
|
||||
CHECK(result["empty"].as<int>() == 1);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user