TEST(ProgramOptions, ParseErrors) { ProgramOptions po; ProgramOptions::Option& help = po.add("help").mnemonic('?'); ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue("INPUT"); ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue("OUTPUT"); const char* argv1[] = { "program.exe", "--input" }; EXPECT_THROW(po.parse(2, argv1), ProgramOptionNeedsValue); const char* argv2[] = { "program.exe", "-i" }; EXPECT_THROW(po.parse(2, argv2), ProgramOptionNeedsValue); const char* argv3[] = { "program.exe", "--test" }; EXPECT_THROW(po.parse(2, argv3), InvalidProgramOption); const char* argv4[] = { "program.exe", "-?a" }; po.reset(); EXPECT_FALSE(help.enabled()); EXPECT_THROW(po.parse(2, argv4), InvalidProgramOption); EXPECT_TRUE(help.enabled()); // -? is parsed anyway, -a is the invalid option const char* argv5[] = { "program.exe", "-io", "input-and-output.txt" }; po.reset(); EXPECT_THROW(po.parse(2, argv5), ProgramOptionNeedsValue); po.reset(); EXPECT_THROW(po.parse(3, argv5), InvalidProgramOptionsCombination); EXPECT_TRUE(input.enabled()); EXPECT_TRUE(output.enabled()); EXPECT_EQ("input-and-output.txt", input.value()); EXPECT_EQ("", output.value()); }
TEST(ProgramOptions, Parse) { ProgramOptions po; ProgramOptions::Option& help = po.add("help").mnemonic('?'); ProgramOptions::Option& input = po.add("input").mnemonic('i').requiresValue("INPUT"); ProgramOptions::Option& output = po.add("output").mnemonic('o').requiresValue("OUTPUT"); const char* argv1[] = { "program.exe", "-?" }; po.parse(2, argv1); EXPECT_TRUE(help.enabled()); const char* argv2[] = { "program.exe", "--help" }; po.reset(); po.parse(2, argv2); EXPECT_TRUE(help.enabled()); const char* argv3[] = { "program.exe", "--input", "hello.cpp", "--output", "hello.exe" }; po.reset(); po.parse(5, argv3); EXPECT_FALSE(help.enabled()); EXPECT_TRUE(input.enabled()); EXPECT_TRUE(output.enabled()); EXPECT_EQ("hello.cpp", input.value()); EXPECT_EQ("hello.exe", output.value()); const char* argv4[] = { "program.exe", "--input=hi.c", "--output=out.exe" }; po.reset(); po.parse(3, argv4); EXPECT_FALSE(help.enabled()); EXPECT_TRUE(input.enabled()); EXPECT_TRUE(output.enabled()); EXPECT_EQ("hi.c", input.value()); EXPECT_EQ("out.exe", output.value()); const char* argv5[] = { "program.exe", "-?i", "input.md", "-o", "output.html", "extra-file.txt" }; po.reset(); po.parse(6, argv5); EXPECT_TRUE(help.enabled()); EXPECT_TRUE(input.enabled()); EXPECT_TRUE(output.enabled()); EXPECT_EQ("input.md", input.value()); EXPECT_EQ("output.html", output.value()); ASSERT_EQ(1, po.values().size()); EXPECT_EQ("extra-file.txt", po.values()[0]); const char* argv6[] = { "program.exe", "value1", "value2", "-o", "output", "value3", "--input=input", "value4" }; po.reset(); po.parse(8, argv6); ASSERT_EQ(4, po.values().size()); EXPECT_EQ("value1", po.values()[0]); EXPECT_EQ("value2", po.values()[1]); EXPECT_EQ("value3", po.values()[2]); EXPECT_EQ("value4", po.values()[3]); }
TEST(ProgramOptions, Reset) { ProgramOptions po; ProgramOptions::Option& help = po.add("help"); ProgramOptions::Option& file = po.add("file").requiresValue("FILE"); EXPECT_FALSE(help.enabled()); EXPECT_FALSE(file.enabled()); EXPECT_EQ("", file.value()); const char* argv[] = { "program.exe", "--help", "--file=readme.txt" }; po.parse(3, argv); EXPECT_TRUE(help.enabled()); EXPECT_TRUE(file.enabled()); EXPECT_EQ("readme.txt", file.value()); po.reset(); EXPECT_FALSE(help.enabled()); EXPECT_FALSE(file.enabled()); EXPECT_EQ("", file.value()); }
static void ParseProgramOptions (int argc, char* argv[]) { string level = "info"; ProgramOptionsDescription description("STANDARD options"); ProgramOptionsDescription hidden("HIDDEN options"); hidden ("colors", "activate color support") ("no-pretty-print", "disable pretty printting") ("auto-complete", "enable auto completion, use no-auto-complete to disable") ; description ("help,h", "help message") ("quite,s", "no banner") ("log.level,l", &level, "log level") ("server", &ServerAddressPort, "server address and port") ("startup.directory", &StartupPath, "startup paths containing the Ruby files; multiple directories can be separated by cola") ("startup.modules-path", &StartupModules, "one or more directories separated by cola") ("pager", &OutputPager, "output pager") ("use-pager", "use pager") ("pretty-print", "pretty print values") ("no-colors", "deactivate color support") ("no-auto-complete", "disable auto completion") // ("unit-tests", &UnitTests, "do not start as shell, run unit tests instead") (hidden, true) ; ProgramOptions options; if (! options.parse(description, argc, argv)) { cerr << options.lastError() << "\n"; exit(EXIT_FAILURE); } // check for help set<string> help = options.needHelp("help"); if (! help.empty()) { cout << description.usage(help) << endl; exit(EXIT_SUCCESS); } // set the logging TRI_SetLogLevelLogging(level.c_str()); TRI_CreateLogAppenderFile("-"); // set colors if (options.has("colors")) { NoColors = false; } if (options.has("no-colors")) { NoColors = true; } if (options.has("auto-complete")) { NoAutoComplete = false; } if (options.has("no-auto-complete")) { NoAutoComplete = true; } if (options.has("pretty-print")) { PrettyPrint = true; } if (options.has("no-pretty-print")) { PrettyPrint = false; } if (options.has("use-pager")) { UsePager = true; } if (options.has("quite")) { Quite = true; } }
int main(int argc, const char* argv[]) { ProgramOptions opts; if( opts.parse(argc, argv) ) { return 1; } { Debug_DisablePhase("Load Repository"); Debug_DisablePhase("Load Root"); Debug_DisablePhase("Load Dependencies"); Debug_DisablePhase("Enumerate Build"); Debug_DisablePhase("Run Build"); if( const char* e = getenv("MINICARGO_DEBUG") ) { while( *e ) { const char* colon = ::std::strchr(e, ':'); size_t len = colon ? colon - e : ::std::strlen(e); Debug_EnablePhase(::std::string(e, len).c_str()); if( colon ) e = colon + 1; else e = e + len; } } } try { Debug_SetPhase("Load Repository"); // Load package database Repository repo; // TODO: load repository from a local cache if( opts.vendor_dir ) { repo.load_vendored(opts.vendor_dir); } auto bs_override_dir = opts.override_directory ? ::helpers::path(opts.override_directory) : ::helpers::path(); // 1. Load the Cargo.toml file from the passed directory Debug_SetPhase("Load Root"); auto dir = ::helpers::path(opts.directory ? opts.directory : "."); auto m = PackageManifest::load_from_toml( dir / "Cargo.toml" ); // 2. Load all dependencies Debug_SetPhase("Load Dependencies"); m.load_dependencies(repo, !bs_override_dir.is_valid()); // 3. Build dependency tree and build program. BuildOptions build_opts; build_opts.build_script_overrides = ::std::move(bs_override_dir); build_opts.output_dir = opts.output_directory ? ::helpers::path(opts.output_directory) : ::helpers::path("output"); build_opts.lib_search_dirs.reserve(opts.lib_search_dirs.size()); build_opts.emit_mmir = opts.emit_mmir; build_opts.target_name = opts.target; for(const auto* d : opts.lib_search_dirs) build_opts.lib_search_dirs.push_back( ::helpers::path(d) ); Debug_SetPhase("Enumerate Build"); auto build_list = BuildList(m, build_opts); Debug_SetPhase("Run Build"); if( !build_list.build(::std::move(build_opts), opts.build_jobs) ) { ::std::cerr << "BUILD FAILED" << ::std::endl; if(opts.pause_before_quit) { ::std::cout << "Press enter to exit..." << ::std::endl; ::std::cin.get(); } return 1; } } catch(const ::std::exception& e) { ::std::cerr << "EXCEPTION: " << e.what() << ::std::endl; if(opts.pause_before_quit) { ::std::cout << "Press enter to exit..." << ::std::endl; ::std::cin.get(); } return 1; } if(opts.pause_before_quit) { ::std::cout << "Press enter to exit..." << ::std::endl; ::std::cin.get(); } return 0; }
void ArangoClient::parse (ProgramOptions& options, ProgramOptionsDescription& description, string const& example, int argc, char* argv[], string const& initFilename) { // if options are invalid, exit directly if (! options.parse(description, argc, argv)) { LOG_FATAL_AND_EXIT("%s", options.lastError().c_str()); } // setup the logging TRI_SetLogLevelLogging(_logLevel.c_str()); TRI_CreateLogAppenderFile("-", 0, TRI_LOG_SEVERITY_UNKNOWN, false); TRI_SetLineNumberLogging(false); TRI_SetThreadIdentifierLogging(false); // parse config file string configFile = ""; bool allowLocal = false; if (! _configFile.empty()) { if (StringUtils::tolower(_configFile) == string("none")) { LOG_DEBUG("using no init file at all"); } else { configFile = _configFile; } } else { char* d = TRI_LocateConfigDirectory(); if (d != 0) { string sysDir = string(d) + initFilename; TRI_FreeString(TRI_CORE_MEM_ZONE, d); if (FileUtils::exists(sysDir)) { configFile = sysDir; allowLocal = true; } else { LOG_DEBUG("no system init file '%s'", sysDir.c_str()); } } } if (! configFile.empty()) { if (allowLocal) { string localConfigFile = configFile + ".local"; if (FileUtils::exists(localConfigFile)) { LOG_DEBUG("using init override file '%s'", localConfigFile.c_str()); if (! options.parse(description, localConfigFile)) { LOG_FATAL_AND_EXIT("cannot parse config file '%s': %s", localConfigFile.c_str(), options.lastError().c_str()); } } } LOG_DEBUG("using init file '%s'", configFile.c_str()); if (! options.parse(description, configFile)) { LOG_FATAL_AND_EXIT("cannot parse config file '%s': %s", configFile.c_str(), options.lastError().c_str()); } } // configuration is parsed and valid if we got to this point // check for --help set<string> help = options.needHelp("help"); if (! help.empty()) { if (! example.empty()) { cout << "USAGE: " << argv[0] << " " << example << endl << endl; } cout << description.usage(help) << endl; // --help always returns success TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL); } // set temp path if (options.has("temp-path")) { TRI_SetUserTempPath((char*) _tempPath.c_str()); } if (options.has("server.username")) { // if a username is specified explicitly, assume authentication is desired _disableAuthentication = false; } // check if have a password _hasPassword = options.has("server.password") || _disableAuthentication || options.has("jslint") || options.has("javascript.unit-tests"); // set colors if (options.has("colors")) { _noColors = false; } if (options.has("no-colors")) { _noColors = true; } // set auto-completion if (options.has("auto-complete")) { _noAutoComplete = false; } if (options.has("no-auto-complete")) { _noAutoComplete = true; } // set pretty print if (options.has("pretty-print")) { _prettyPrint = true; } if (options.has("no-pretty-print")) { _prettyPrint = false; } // set pager if (options.has("use-pager")) { _usePager = true; } // set quiet if (options.has("quiet")) { _quiet = true; } // ............................................................................. // server options // ............................................................................. if (_serverOptions) { // check connection args if (_connectTimeout <= 0) { LOG_FATAL_AND_EXIT("invalid value for --server.connect-timeout, must be positive"); } if (_requestTimeout <= 0) { LOG_FATAL_AND_EXIT("invalid value for --server.request-timeout, must be positive"); } // must specify a user name if (_username.size() == 0) { LOG_FATAL_AND_EXIT("no value specified for --server.username"); } // no password given on command-line if (! _hasPassword) { usleep(10 * 1000); printContinuous("Please specify a password: "******""); } } }
void ArangoClient::parse (ProgramOptions& options, ProgramOptionsDescription& description, int argc, char* argv[], string const& initFilename) { if (! options.parse(description, argc, argv)) { LOGGER_FATAL_AND_EXIT(options.lastError()); } // check for help set<string> help = options.needHelp("help"); if (! help.empty()) { cout << description.usage(help) << endl; TRI_EXIT_FUNCTION(EXIT_SUCCESS, NULL); } // setup the logging TRI_SetLogLevelLogging(_logLevel.c_str()); TRI_CreateLogAppenderFile("-", 0, TRI_LOG_SEVERITY_UNKNOWN, false); TRI_SetLineNumberLogging(false); TRI_SetThreadIdentifierLogging(false); // parse config file string configFile = ""; if (! _configFile.empty()) { if (StringUtils::tolower(_configFile) == string("none")) { LOGGER_DEBUG("using no init file at all"); } else { configFile = _configFile; } } #ifdef _SYSCONFDIR_ else { // use packaged config file from etc/relative string sysDir = string(_SYSCONFDIR_); string systemConfigFile = initFilename; if (! sysDir.empty()) { if (sysDir[sysDir.size() - 1] != TRI_DIR_SEPARATOR_CHAR) { sysDir += TRI_DIR_SEPARATOR_CHAR + systemConfigFile; } else { sysDir += systemConfigFile; } if (FileUtils::exists(sysDir)) { configFile = sysDir; } else { LOGGER_DEBUG("no system init file '" << sysDir << "'"); } } } #endif if (! configFile.empty()) { LOGGER_DEBUG("using init file '" << configFile << "'"); if (! options.parse(description, configFile)) { LOGGER_FATAL_AND_EXIT("cannot parse config file '" << configFile << "': " << options.lastError()); } } // set temp path if (options.has("temp-path")) { TRI_SetUserTempPath((char*) _tempPath.c_str()); } // check if have a password _hasPassword = options.has("server.password") || _disableAuthentication || options.has("jslint") || options.has("javascript.unit-tests"); // set colors if (options.has("colors")) { _noColors = false; } if (options.has("no-colors")) { _noColors = true; } // set auto-completion if (options.has("auto-complete")) { _noAutoComplete = false; } if (options.has("no-auto-complete")) { _noAutoComplete = true; } // set pretty print if (options.has("pretty-print")) { _prettyPrint = true; } if (options.has("no-pretty-print")) { _prettyPrint = false; } // set pager if (options.has("use-pager")) { _usePager = true; } // set quiet if (options.has("quiet")) { _quiet = true; } // ............................................................................. // server options // ............................................................................. if (_serverOptions) { // check connection args if (_connectTimeout <= 0) { LOGGER_FATAL_AND_EXIT("invalid value for --server.connect-timeout, must be positive"); } if (_requestTimeout <= 0) { LOGGER_FATAL_AND_EXIT("invalid value for --server.request-timeout, must be positive"); } // must specify a user name if (_username.size() == 0) { LOGGER_FATAL_AND_EXIT("no value specified for --server.username"); } // no password given on command-line if (! _hasPassword) { usleep(10 * 1000); printContinuous("Please specify a password: "******""); } } }
void ArangoClient::parse (ProgramOptions& options, ProgramOptionsDescription& description, int argc, char* argv[], string const& initFilename) { if (! options.parse(description, argc, argv)) { cerr << options.lastError() << "\n"; exit(EXIT_FAILURE); } // check for help set<string> help = options.needHelp("help"); if (! help.empty()) { cout << description.usage(help) << endl; exit(EXIT_SUCCESS); } // setup the logging TRI_SetLogLevelLogging(_logLevel.c_str()); TRI_CreateLogAppenderFile("-"); TRI_SetLineNumberLogging(false); TRI_SetThreadIdentifierLogging(false); // parse config file string configFile = ""; if (! _configFile.empty()) { if (StringUtils::tolower(_configFile) == string("none")) { LOGGER_INFO << "using no init file at all"; } else { configFile = _configFile; } } #ifdef _SYSCONFDIR_ else { string sysDir = string(_SYSCONFDIR_); string systemConfigFile = initFilename; if (! sysDir.empty()) { if (sysDir[sysDir.size() - 1] != '/') { sysDir += "/" + systemConfigFile; } else { sysDir += systemConfigFile; } if (FileUtils::exists(sysDir)) { configFile = sysDir; } else { LOGGER_DEBUG << "no system init file '" << sysDir << "'"; } } } #endif if (! configFile.empty()) { LOGGER_DEBUG << "using init file '" << configFile << "'"; if (! options.parse(description, configFile)) { cout << "cannot parse config file '" << configFile << "': " << options.lastError() << endl; exit(EXIT_FAILURE); } } // check if have a password _hasPassword = options.has("server.password") || options.has("server.disable-authentication"); // set colors if (options.has("colors")) { _noColors = false; } if (options.has("no-colors")) { _noColors = true; } // set auto-completion if (options.has("auto-complete")) { _noAutoComplete = false; } if (options.has("no-auto-complete")) { _noAutoComplete = true; } // set pretty print if (options.has("pretty-print")) { _prettyPrint = true; } if (options.has("no-pretty-print")) { _prettyPrint = false; } // set pager if (options.has("use-pager")) { _usePager = true; } // set quiet if (options.has("quiet")) { _quiet = true; } // ............................................................................. // server options // ............................................................................. if (_serverOptions) { // check connection args if (_connectTimeout <= 0) { cerr << "invalid value for --server.connect-timeout, must be positive" << endl; exit(EXIT_FAILURE); } if (_requestTimeout <= 0) { cerr << "invalid value for --server.request-timeout, must be positive" << endl; exit(EXIT_FAILURE); } // must specify a user name if (_username.size() == 0) { cerr << "no value specified for --server.username" << endl; exit(EXIT_FAILURE); } // no password given on command-line if (! _hasPassword) { cout << "Please specify a password: " << flush; // now prompt for it #ifdef TRI_HAVE_TERMIOS_H TRI_SetStdinVisibility(false); getline(cin, _password); TRI_SetStdinVisibility(true); #else getline(cin, _password); #endif } } }