diff --git a/arangod/RestServer/CheckVersionFeature.cpp b/arangod/RestServer/CheckVersionFeature.cpp index f74784f1db..5f84a7e1d3 100644 --- a/arangod/RestServer/CheckVersionFeature.cpp +++ b/arangod/RestServer/CheckVersionFeature.cpp @@ -54,6 +54,8 @@ CheckVersionFeature::CheckVersionFeature( void CheckVersionFeature::collectOptions( std::shared_ptr options) { options->addSection("database", "Configure the database"); + + options->addOldOption("check-version", "database.check-version"); options->addHiddenOption("--database.check-version", "checks the versions of the database and exit", diff --git a/arangod/RestServer/DatabaseFeature.cpp b/arangod/RestServer/DatabaseFeature.cpp index 189141c9ea..b87380929f 100644 --- a/arangod/RestServer/DatabaseFeature.cpp +++ b/arangod/RestServer/DatabaseFeature.cpp @@ -69,6 +69,8 @@ DatabaseFeature::DatabaseFeature(ApplicationServer* server) void DatabaseFeature::collectOptions(std::shared_ptr options) { options->addSection("database", "Configure the database"); + + options->addOldOption("server.disable-replication-applier", "database.replication-applier"); options->addOption("--database.directory", "path to the database directory", new StringParameter(&_directory)); diff --git a/arangod/RestServer/EndpointFeature.cpp b/arangod/RestServer/EndpointFeature.cpp index 529be0cb8c..17c90afcd1 100644 --- a/arangod/RestServer/EndpointFeature.cpp +++ b/arangod/RestServer/EndpointFeature.cpp @@ -51,6 +51,9 @@ EndpointFeature::EndpointFeature( } void EndpointFeature::collectOptions(std::shared_ptr options) { + options->addOldOption("server.backlog-size", "tcp.backlog-size"); + options->addOldOption("server.reuse-address", "tcp.reuse-address"); + options->addSection("server", "Server features"); options->addOption("--server.endpoint", diff --git a/arangod/RestServer/QueryRegistryFeature.cpp b/arangod/RestServer/QueryRegistryFeature.cpp index 8f343a2a63..ffd0cf1a3b 100644 --- a/arangod/RestServer/QueryRegistryFeature.cpp +++ b/arangod/RestServer/QueryRegistryFeature.cpp @@ -46,6 +46,10 @@ QueryRegistryFeature::QueryRegistryFeature(ApplicationServer* server) void QueryRegistryFeature::collectOptions( std::shared_ptr options) { options->addSection("query", "Configure queries"); + + options->addOldOption("database.query-cache-mode", "query.cache-mode"); + options->addOldOption("database.query-cache-max-results", "query.cache-entries"); + options->addOldOption("database.disable-query-tracking", "query.tracking"); options->addOption("--query.tracking", "whether to track queries", new BooleanParameter(&_queryTracking)); diff --git a/arangod/RestServer/RestServerFeature.cpp b/arangod/RestServer/RestServerFeature.cpp index 8e23f1bdf0..cf50d3ebef 100644 --- a/arangod/RestServer/RestServerFeature.cpp +++ b/arangod/RestServer/RestServerFeature.cpp @@ -108,6 +108,14 @@ void RestServerFeature::collectOptions( std::shared_ptr options) { options->addSection("server", "Server features"); + options->addOldOption("server.disable-authentication", "server.authentication"); + options->addOldOption("server.disable-authentication-unix-sockets", "server.authentication-unix-sockets"); + options->addOldOption("server.authenticate-system-only", "server.authentication-system-only"); + options->addOldOption("server.allow-method-override", "http.allow-method-override"); + options->addOldOption("server.hide-product-header", "http.hide-product-header"); + options->addOldOption("server.keep-alive-timeout", "http.keep-alive-timeout"); + options->addOldOption("server.default-api-compatibility", ""); + options->addOption("--server.authentication", "enable or disable authentication for ALL client requests", new BooleanParameter(&_authentication)); diff --git a/arangod/RestServer/UpgradeFeature.cpp b/arangod/RestServer/UpgradeFeature.cpp index c2897a7efe..7c1bd35bd9 100644 --- a/arangod/RestServer/UpgradeFeature.cpp +++ b/arangod/RestServer/UpgradeFeature.cpp @@ -58,6 +58,8 @@ UpgradeFeature::UpgradeFeature( void UpgradeFeature::collectOptions(std::shared_ptr options) { options->addSection("database", "Configure the database"); + + options->addOldOption("upgrade", "--database.auto-upgrade"); options->addOption("--database.auto-upgrade", "perform a database upgrade if necessary", diff --git a/arangod/Statistics/StatisticsFeature.cpp b/arangod/Statistics/StatisticsFeature.cpp index 73f0f6ce88..959cc795cb 100644 --- a/arangod/Statistics/StatisticsFeature.cpp +++ b/arangod/Statistics/StatisticsFeature.cpp @@ -39,6 +39,8 @@ StatisticsFeature::StatisticsFeature(application_features::ApplicationServer* se } void StatisticsFeature::collectOptions(std::shared_ptr options) { + options->addOldOption("server.disable-statistics", "server.statistics"); + options->addSection("server", "Server features"); options->addHiddenOption( diff --git a/arangod/V8Server/FoxxQueuesFeature.cpp b/arangod/V8Server/FoxxQueuesFeature.cpp index 5db3011d0b..342eecd901 100644 --- a/arangod/V8Server/FoxxQueuesFeature.cpp +++ b/arangod/V8Server/FoxxQueuesFeature.cpp @@ -40,6 +40,9 @@ FoxxQueuesFeature::FoxxQueuesFeature( void FoxxQueuesFeature::collectOptions(std::shared_ptr options) { options->addSection("foxx", "Configure Foxx"); + + options->addOldOption("server.foxx-queues", "foxx.queues"); + options->addOldOption("server.foxx-queues-poll-interval", "foxx.queues-poll-interval"); options->addOption( "--foxx.queues", diff --git a/lib/ApplicationFeatures/TempFeature.cpp b/lib/ApplicationFeatures/TempFeature.cpp index d6db0e94b6..2ee0a1d8da 100644 --- a/lib/ApplicationFeatures/TempFeature.cpp +++ b/lib/ApplicationFeatures/TempFeature.cpp @@ -41,6 +41,8 @@ TempFeature::TempFeature(application_features::ApplicationServer* server, } void TempFeature::collectOptions(std::shared_ptr options) { + options->addOldOption("temp-path", "temp.path"); + options->addSection("temp", "Configure the temporary files"); options->addOption("--temp.path", "path for temporary files", diff --git a/lib/Logger/LoggerFeature.cpp b/lib/Logger/LoggerFeature.cpp index a790163b29..2feb29d9a3 100644 --- a/lib/Logger/LoggerFeature.cpp +++ b/lib/Logger/LoggerFeature.cpp @@ -64,6 +64,12 @@ LoggerFeature::LoggerFeature(application_features::ApplicationServer* server, } void LoggerFeature::collectOptions(std::shared_ptr options) { + options->addOldOption("log.tty", "log.foreground-tty"); + options->addOldOption("log.content-filter", ""); + options->addOldOption("log.source-filter", ""); + options->addOldOption("log.application", ""); + options->addOldOption("log.facility", ""); + options->addHiddenOption("--log", "the global or topic-specific log level", new VectorParameter(&_levels)); diff --git a/lib/ProgramOptions/ProgramOptions.h b/lib/ProgramOptions/ProgramOptions.h index e1fe412b9a..4172c8dcde 100644 --- a/lib/ProgramOptions/ProgramOptions.h +++ b/lib/ProgramOptions/ProgramOptions.h @@ -141,6 +141,16 @@ class ProgramOptions { // set context for error reporting void setContext(std::string const& value) { _context = value; } + // sets the old options map + void setOldOptions(std::unordered_map const& old) { + _oldOptions = old; + } + + // sets a single old option and its replacement name + void addOldOption(std::string const& old, std::string const& replacement) { + _oldOptions[old] = replacement; + } + // adds a section to the options void addSection(Section const& section) { checkIfSealed(); @@ -364,7 +374,7 @@ class ProgramOptions { return (*it2).second.parameter->requiresValue(); } - // returns a pointer to an option, specified by option name + // returns a pointer to an option value, specified by option name // returns a nullptr if the option is unknown template T* get(std::string const& name) { @@ -385,20 +395,83 @@ class ProgramOptions { return dynamic_cast(option.parameter.get()); } + + // returns an option description + std::string getDescription(std::string const& name) { + auto parts = Option::splitName(name); + auto it = _sections.find(parts.first); + + if (it == _sections.end()) { + return ""; + } + + auto it2 = (*it).second.options.find(parts.second); + + if (it2 == (*it).second.options.end()) { + return ""; + } + + return (*it2).second.description; + } // handle an unknown option bool unknownOption(std::string const& name) { - fail("unknown option '--" + name + "'"); + char const* colorStart; + char const* colorEnd; + + if (isatty(STDERR_FILENO)) { + colorStart = TRI_SHELL_COLOR_BRIGHT; + colorEnd = TRI_SHELL_COLOR_RESET; + } else { + colorStart = colorEnd = ""; + } + + fail(std::string("unknown option '") + colorStart + "--" + name + colorEnd + "'"); auto similarOptions = similar(name, 8, 4); if (!similarOptions.empty()) { - std::cerr << "Did you mean one of these?" << std::endl; + if (similarOptions.size() == 1) { + std::cerr << "Did you mean this?" << std::endl; + } else { + std::cerr << "Did you mean one of these?" << std::endl; + } + // determine maximum width + size_t maxWidth = 0; for (auto const& it : similarOptions) { - std::cerr << " " << it << std::endl; + maxWidth = (std::max)(maxWidth, it.size()); + } + + for (auto const& it : similarOptions) { + std::cerr << " " << colorStart << Option::pad(it, maxWidth) << colorEnd + << " " << getDescription(it) + << std::endl; } std::cerr << std::endl; } - std::cerr << "Use --help or --help-all to get an overview of available options" + + auto it = _oldOptions.find(name); + if (it != _oldOptions.end()) { + // a now removed or renamed option was specified... + auto& now = (*it).second; + if (now.empty()) { + std::cerr << "Please note that the specified option '" + << colorStart << "--" << name << colorEnd + << "' has been removed in this ArangoDB version"; + } else { + std::cerr << "Please note that the specified option '" + << colorStart << "--" << name << colorEnd + << "' has been renamed to '--" << colorStart + << now << colorEnd << "' in this ArangoDB version"; + } + + std::cerr << std::endl + << "Please be sure to read the manual section about changed options" + << std::endl << std::endl; + } + + std::cerr << "Use " << colorStart << "--help" << colorEnd + << " or " << colorStart << "--help-all" << colorEnd + << " to get an overview of available options" << std::endl << std::endl; return false; @@ -507,6 +580,9 @@ class ProgramOptions { // shorthands for options, translating from short options to long option names // e.g. "-c" to "--configuration" std::unordered_map _shorthands; + // map with old options and their new equivalents, used for printing more + // meaningful error messages when an invalid (but once valid) option was used + std::unordered_map _oldOptions; // callback function for determining the terminal width TerminalWidthFuncType _terminalWidth; // callback function for determining the similarity between two option names diff --git a/lib/Ssl/SslServerFeature.cpp b/lib/Ssl/SslServerFeature.cpp index 3675e14bf3..89d939c500 100644 --- a/lib/Ssl/SslServerFeature.cpp +++ b/lib/Ssl/SslServerFeature.cpp @@ -52,6 +52,13 @@ SslServerFeature::SslServerFeature(application_features::ApplicationServer* serv } void SslServerFeature::collectOptions(std::shared_ptr options) { + options->addOldOption("server.cafile", "ssl.cafile"); + options->addOldOption("server.keyfile", "ssl.keyfile"); + options->addOldOption("server.ssl-cache", "ssl.session-cache"); + options->addOldOption("server.ssl-cipher-list", "ssl.cipher-list"); + options->addOldOption("server.ssl-options", "ssl.options"); + options->addOldOption("server.ssl-protocol", "ssl.protocol"); + options->addSection("ssl", "Configure SSL communication"); options->addOption("--ssl.cafile", "ca file used for secure connections",