--- a/src/CLIParser.h Sat Jul 02 15:21:59 2022 +0200
+++ b/src/CLIParser.h Sat Jul 02 19:45:18 2022 +0200
@@ -32,6 +32,8 @@
class CLIParser {
private:
+ std::wstring_convert<std::codecvt_utf8<wchar_t>> convertor; // TODO: support also other encodings.
+
relpipe::reader::string_t readNext(const std::vector<relpipe::reader::string_t>& arguments, int& i) {
if (i < arguments.size()) return arguments[i++];
else throw relpipe::cli::RelpipeCLIException(L"Missing CLI argument" + (i > 0 ? (L" after " + arguments[i - 1]) : L""), relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
@@ -57,7 +59,7 @@
else if (value == L"false") return false;
else throw relpipe::cli::RelpipeCLIException(L"Unable to parse boolean value: " + value + L" (expecting true or false)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
-
+
Configuration::ColorScheme parseColorScheme(const relpipe::reader::string_t& value) {
if (value == L"greenish") return Configuration::ColorScheme::Greenish;
else if (value == L"amberish") return Configuration::ColorScheme::Amberish;
@@ -65,7 +67,7 @@
else if (value == L"midnight") return Configuration::ColorScheme::Midnight;
else throw relpipe::cli::RelpipeCLIException(L"Unable to parse ColorScheme value: " + value + L" (expecting greenish, amberish, midnight or black-and-white)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
-
+
Configuration::TableStyle parseTableStyle(const relpipe::reader::string_t& value) {
if (value == L"rounded") return Configuration::TableStyle::Rounded;
else if (value == L"sharp") return Configuration::TableStyle::Sharp;
@@ -75,6 +77,54 @@
else throw relpipe::cli::RelpipeCLIException(L"Unable to parse TableStyle value: " + value + L" (expecting rounded, sharp, ascii)", relpipe::cli::CLI::EXIT_CODE_BAD_CLI_ARGUMENTS);
}
+ /**
+ * TODO: move to common parent class in relpipe-lib-cli
+ *
+ * @param cliArguments original CLI arguments
+ * @param moduleName name of this program e.g. "relpipe-out-tabular"
+ * @param supportedOptions options that could be specified also as environmental variables, not only CLI arguments, including the "--" prefix e.g. "--color-scheme"
+ * @return defaults found in ENV + given CLI arguments
+ */
+ const std::vector<relpipe::reader::string_t> addEnvDefaults(const std::vector<relpipe::reader::string_t>& cliArguments, const relpipe::reader::string_t moduleName, const std::vector<relpipe::reader::string_t>& supportedOptions) {
+ std::vector<relpipe::reader::string_t> allArguments;
+
+ auto toEnv = [](char ch) {
+ return ch == '-' ? '_' : ::toupper(ch);
+ };
+
+ std::string envPrefix = convertor.to_bytes(moduleName);
+ transform(envPrefix.begin(), envPrefix.end(), envPrefix.begin(), toEnv);
+ envPrefix.append("_");
+
+ for (auto o : supportedOptions) {
+ if (o.substr(0, 2) == L"--") {
+ std::string option = convertor.to_bytes(o);
+ option.erase(0, 2);
+ transform(option.begin(), option.end(), option.begin(), toEnv);
+
+ // FIXME: check argument counts (should be specified alongside with supportedOptions) to avoid injection of unwanted options through ENV variables
+ // TODO: allow repeated options?
+ for (int i = -1; i < 10; i++) {
+ std::string envName = i == -1 ? envPrefix + option : envPrefix + option + "_" + std::to_string(i);
+ const char* value = std::getenv(envName.c_str());
+ if (value) {
+ if (i == -1 || i == 0) allArguments.push_back(o);
+ allArguments.push_back(convertor.from_bytes(value));
+ if (i == -1) break;
+ } else {
+ if (i > -1) break;
+ }
+ }
+ } else {
+ throw std::logic_error("supportedOptions must start with '--'");
+ }
+ }
+
+ for (auto a : cliArguments) allArguments.push_back(a);
+
+ return allArguments;
+ }
+
public:
static const relpipe::reader::string_t OPTION_RELATION;
@@ -84,10 +134,12 @@
static const relpipe::reader::string_t OPTION_COLOR_SCHEME;
static const relpipe::reader::string_t OPTION_TABLE_STYLE;
- Configuration parse(const std::vector<relpipe::reader::string_t>& arguments) {
+ Configuration parse(const std::vector<relpipe::reader::string_t>& cliArguments) {
Configuration c;
RelationConfiguration currentRelation;
-
+
+ const std::vector<relpipe::reader::string_t> arguments = addEnvDefaults(cliArguments, L"relpipe-out-tabular",{OPTION_COLOR_SCHEME, OPTION_TABLE_STYLE});
+
// TODO: global configuration of writeTypes, writeRelationName, writeRecordCount
for (int i = 0; i < arguments.size();) {