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`.
|
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
|
## Example
|
||||||
|
|
||||||
Putting all together:
|
Putting all together:
|
||||||
|
|||||||
@ -314,6 +314,15 @@ namespace cxxopts
|
|||||||
virtual std::shared_ptr<Value>
|
virtual std::shared_ptr<Value>
|
||||||
implicit_value(const std::string& value) = 0;
|
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>
|
virtual std::shared_ptr<Value>
|
||||||
no_implicit_value() = 0;
|
no_implicit_value() = 0;
|
||||||
|
|
||||||
@ -888,6 +897,26 @@ namespace cxxopts
|
|||||||
return m_implicit_value;
|
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
|
bool
|
||||||
is_boolean() const
|
is_boolean() const
|
||||||
{
|
{
|
||||||
@ -913,9 +942,11 @@ namespace cxxopts
|
|||||||
|
|
||||||
bool m_default = false;
|
bool m_default = false;
|
||||||
bool m_implicit = false;
|
bool m_implicit = false;
|
||||||
|
bool m_env = false;
|
||||||
|
|
||||||
std::string m_default_value;
|
std::string m_default_value;
|
||||||
std::string m_implicit_value;
|
std::string m_implicit_value;
|
||||||
|
std::string m_env_var;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -1961,6 +1992,15 @@ ParseResult::parse(int& argc, char**& argv)
|
|||||||
if(value.has_default() && !store.count() && !store.has_default()){
|
if(value.has_default() && !store.count() && !store.has_default()){
|
||||||
parse_default(detail);
|
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)
|
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["aggregate"].as<int>() == 4);
|
||||||
CHECK(result["test"].as<int>() == 5);
|
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