You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2015/06/02 01:00:12 UTC
[1/2] mesos git commit: Refactoring to use FlagsBase common
functionality.
Repository: mesos
Updated Branches:
refs/heads/master f855fb7f2 -> 4cc0ffc4e
Refactoring to use FlagsBase common functionality.
Jira: MESOS-2711
All the main() methods have been refactored to use the definition of
FlagsBase::help flag and FlagsBase::usage().
This CL also tries to bring some uniformity to the use of exit codes:
if this is deemed to be worth making it uniform, we can come up with
common rules and extend the changes here to be compliant.
This touches a lot of files, but keep scrolling, and you will see a
pattern emerge.
Review: https://reviews.apache.org/r/34195
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/4cc0ffc4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/4cc0ffc4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/4cc0ffc4
Branch: refs/heads/master
Commit: 4cc0ffc4e5198af8bec78dca892b021f6b07d908
Parents: 1694bda
Author: Marco Massenzio <ma...@mesosphere.io>
Authored: Mon Jun 1 10:53:59 2015 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Mon Jun 1 15:59:38 2015 -0700
----------------------------------------------------------------------
src/cli/execute.cpp | 66 +++++-------
src/cli/mesos.cpp | 10 +-
src/cli/resolve.cpp | 77 ++++----------
src/docker/executor.cpp | 57 ++++------
src/examples/load_generator_framework.cpp | 38 +++----
src/examples/low_level_scheduler_libprocess.cpp | 2 +-
src/examples/low_level_scheduler_pthread.cpp | 2 +-
src/examples/persistent_volume_framework.cpp | 31 ++----
src/health-check/main.cpp | 66 ++++++------
src/launcher/executor.cpp | 28 ++---
src/local/main.cpp | 35 ++-----
src/log/tool/benchmark.cpp | 51 ++++-----
src/log/tool/benchmark.hpp | 3 -
src/log/tool/initialize.cpp | 37 ++-----
src/log/tool/initialize.hpp | 3 -
src/log/tool/read.cpp | 35 ++-----
src/log/tool/read.hpp | 3 -
src/log/tool/replica.cpp | 40 +++----
src/log/tool/replica.hpp | 3 -
src/master/main.cpp | 103 +++++++++----------
.../isolators/network/port_mapping.cpp | 10 --
.../isolators/network/port_mapping.hpp | 2 -
src/slave/main.cpp | 58 +++++------
src/tests/main.cpp | 35 ++-----
src/usage/main.cpp | 37 ++-----
25 files changed, 282 insertions(+), 550 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/execute.cpp
----------------------------------------------------------------------
diff --git a/src/cli/execute.cpp b/src/cli/execute.cpp
index dbd19e6..b387b64 100644
--- a/src/cli/execute.cpp
+++ b/src/cli/execute.cpp
@@ -50,15 +50,6 @@ using std::string;
using std::vector;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
class Flags : public flags::FlagsBase
{
public:
@@ -287,50 +278,43 @@ int main(int argc, char** argv)
{
Flags flags;
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
// Load flags from environment and command line.
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- return -1;
+ // TODO(marco): this should be encapsulated entirely into the
+ // FlagsBase API - possibly with a 'guard' that prevents FlagsBase
+ // from calling ::exit(EXIT_FAILURE) after calling usage() (which
+ // would be the default behavior); see MESOS-2766.
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.master.isNone()) {
- cerr << "Missing --master=IP:PORT" << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage("Missing required option --master") << endl;
+ return EXIT_FAILURE;
}
UPID master("master@" + flags.master.get());
-
if (!master) {
- cerr << "Could not parse --master=" << flags.master.get() << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage("Could not parse --master=" + flags.master.get())
+ << endl;
+ return EXIT_FAILURE;
}
if (flags.name.isNone()) {
- cerr << "Missing --name=NAME" << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage("Missing required option --name") << endl;
+ return EXIT_FAILURE;
}
if (flags.command.isNone()) {
- cerr << "Missing --command=COMMAND" << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage("Missing required option --command") << endl;
+ return EXIT_FAILURE;
}
Result<string> user = os::user();
@@ -340,10 +324,10 @@ int main(int argc, char** argv)
} else {
cerr << "No username for uid " << ::getuid() << endl;
}
- return -1;
+ return EXIT_FAILURE;
}
- Option<hashmap<string, string>> environment;
+ Option<hashmap<string, string>> environment = None();
if (flags.environment.isSome()) {
environment = flags.environment.get();
@@ -370,22 +354,22 @@ int main(int argc, char** argv)
Try<bool> exists = hdfs.exists(path);
if (exists.isError()) {
cerr << "Failed to check if file exists: " << exists.error() << endl;
- return -1;
+ return EXIT_FAILURE;
} else if (exists.get() && flags.overwrite) {
Try<Nothing> rm = hdfs.rm(path);
if (rm.isError()) {
cerr << "Failed to remove existing file: " << rm.error() << endl;
- return -1;
+ return EXIT_FAILURE;
}
} else if (exists.get()) {
cerr << "File already exists (see --overwrite)" << endl;
- return -1;
+ return EXIT_FAILURE;
}
Try<Nothing> copy = hdfs.copyFromLocal(flags.package.get(), path);
if (copy.isError()) {
cerr << "Failed to copy package: " << copy.error() << endl;
- return -1;
+ return EXIT_FAILURE;
}
// Now save the URI.
@@ -413,5 +397,5 @@ int main(int argc, char** argv)
MesosSchedulerDriver driver(&scheduler, framework, flags.master.get());
- return driver.run() == DRIVER_STOPPED ? 0 : 1;
+ return driver.run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/cli/mesos.cpp b/src/cli/mesos.cpp
index 171a707..1121e19 100644
--- a/src/cli/mesos.cpp
+++ b/src/cli/mesos.cpp
@@ -65,7 +65,7 @@ int main(int argc, char** argv)
if (argc < 2) {
usage(argv[0]);
- exit(1);
+ return EXIT_FAILURE;
}
// Update PYTHONPATH to include path to installed 'mesos' module.
@@ -78,7 +78,7 @@ int main(int argc, char** argv)
if (string(argv[1]) == "help") {
if (argc == 2) {
usage(argv[0]);
- return 0;
+ return EXIT_SUCCESS;
} else {
// 'mesos help command' => 'mesos command --help'
argv[1] = argv[2];
@@ -88,7 +88,7 @@ int main(int argc, char** argv)
} else if (string(argv[1]).find("--") == 0) {
cerr << "Not expecting '" << argv[1] << "' before command" << endl;
usage(argv[0]);
- return -1;
+ return EXIT_FAILURE;
} else {
string command = argv[1];
string executable = "mesos-" + command;
@@ -101,8 +101,8 @@ int main(int argc, char** argv)
cerr << "Failed to execute " << command
<< ": " << strerror(errno) << endl;
}
- return -1;
+ return EXIT_FAILURE;
}
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/cli/resolve.cpp
----------------------------------------------------------------------
diff --git a/src/cli/resolve.cpp b/src/cli/resolve.cpp
index a99b609..74545a0 100644
--- a/src/cli/resolve.cpp
+++ b/src/cli/resolve.cpp
@@ -43,24 +43,10 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " <master>" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char** argv)
{
flags::FlagsBase flags;
-
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
+ flags.setUsageMessage("Usage: " + os::basename(argv[0]).get() + " <master>");
Duration timeout;
flags.add(&timeout,
@@ -68,75 +54,54 @@ int main(int argc, char** argv)
"How long to wait to resolve master",
Seconds(5));
+ // TODO(marco): `verbose` is also a great candidate for FlagsBase.
bool verbose;
flags.add(&verbose,
"verbose",
"Be verbose",
false);
- // Load flags from environment and command line.
- Try<Nothing> load = flags.load(None(), argc, argv);
+ // Load flags from environment and command line, and remove
+ // them from argv.
+ Try<Nothing> load = flags.load(None(), &argc, &argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- return -1;
- }
-
- if (help) {
- usage(argv[0], flags);
- return -1;
- }
-
- if (argc < 2) {
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- Option<string> master = None();
-
- // Find 'master' argument (the only argument not prefixed by '--').
- for (int i = 1; i < argc; i++) {
- const std::string arg(strings::trim(argv[i]));
- if (arg.find("--") != 0) {
- if (master.isSome()) {
- // There should only be one non-flag argument.
- cerr << "Ambiguous 'master': "
- << master.get() << " and " << arg << endl;
- usage(argv[0], flags);
- return -1;
- } else {
- master = arg;
- }
- }
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
- if (master.isNone()) {
- cerr << "Missing 'master'" << endl;
- usage(argv[0], flags);
- return -1;
+ // 'master' argument must be the only argument left after parsing.
+ if (argc != 2) {
+ cerr << flags.usage("There must be only one argument: <master>") << endl;
+ return EXIT_FAILURE;
}
- Try<MasterDetector*> detector = MasterDetector::create(master.get());
+ string master = argv[1];
+ Try<MasterDetector*> detector = MasterDetector::create(master);
if (detector.isError()) {
cerr << "Failed to create a master detector: " << detector.error() << endl;
- return -1;
+ return EXIT_FAILURE;
}
Future<Option<MasterInfo> > masterInfo = detector.get()->detect();
if (!masterInfo.await(timeout)) {
- cerr << "Failed to detect master from '" << master.get()
+ cerr << "Failed to detect master from '" << master
<< "' within " << timeout << endl;
return -1;
} else {
CHECK(!masterInfo.isDiscarded());
if (masterInfo.isFailed()) {
- cerr << "Failed to detect master from '" << master.get()
+ cerr << "Failed to detect master from '" << master
<< "': " << masterInfo.failure() << endl;
- return -1;
+ return EXIT_FAILURE;
}
}
@@ -144,5 +109,5 @@ int main(int argc, char** argv)
CHECK_SOME(masterInfo.get());
cout << strings::remove(masterInfo.get().get().pid(), "master@") << endl;
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/docker/executor.cpp
----------------------------------------------------------------------
diff --git a/src/docker/executor.cpp b/src/docker/executor.cpp
index 709fbe3..cdcd8ee 100644
--- a/src/docker/executor.cpp
+++ b/src/docker/executor.cpp
@@ -348,75 +348,54 @@ private:
} // namespace mesos {
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char** argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
mesos::internal::docker::Flags flags;
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
// Load flags from environment and command line.
Try<Nothing> load = flags.load(None(), &argc, &argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
std::cout << stringify(flags) << std::endl;
mesos::internal::logging::initialize(argv[0], flags, true); // Catch signals.
- if (help) {
- usage(argv[0], flags);
- return -1;
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
std::cout << stringify(flags) << std::endl;
if (flags.docker.isNone()) {
- LOG(WARNING) << "Expected docker executable path";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --docker") << endl;
+ return EXIT_FAILURE;
}
if (flags.container.isNone()) {
- LOG(WARNING) << "Expected container name";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --container") << endl;
+ return EXIT_FAILURE;
}
if (flags.sandbox_directory.isNone()) {
- LOG(WARNING) << "Expected sandbox directory path";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --sandbox_directory") << endl;
+ return EXIT_FAILURE;
}
if (flags.mapped_directory.isNone()) {
- LOG(WARNING) << "Expected mapped sandbox directory path";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --mapped_directory") << endl;
+ return EXIT_FAILURE;
}
if (flags.stop_timeout.isNone()) {
- LOG(WARNING) << "Expected stop timeout";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --stop_timeout") << endl;
+ return EXIT_FAILURE;
}
// The 2nd argument for docker create is set to false so we skip
@@ -424,8 +403,8 @@ int main(int argc, char** argv)
// should have already validated docker.
Try<Docker*> docker = Docker::create(flags.docker.get(), false);
if (docker.isError()) {
- LOG(WARNING) << "Unable to create docker abstraction: " << docker.error();
- return -1;
+ cerr << "Unable to create docker abstraction: " << docker.error() << endl;
+ return EXIT_FAILURE;
}
mesos::internal::docker::DockerExecutor executor(
@@ -436,5 +415,5 @@ int main(int argc, char** argv)
flags.stop_timeout.get());
mesos::MesosExecutorDriver driver(&executor);
- return driver.run() == mesos::DRIVER_STOPPED ? 0 : 1;
+ return driver.run() == mesos::DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/load_generator_framework.cpp
----------------------------------------------------------------------
diff --git a/src/examples/load_generator_framework.cpp b/src/examples/load_generator_framework.cpp
index be1a3bf..6e83308 100644
--- a/src/examples/load_generator_framework.cpp
+++ b/src/examples/load_generator_framework.cpp
@@ -270,32 +270,17 @@ public:
"Run LoadGenerator for the specified duration.\n"
"Without this option this framework would keep generating load\n"
"forever as long as it is connected to the master");
-
- add(&Flags::help,
- "help",
- "Print this help message",
- false);
}
Option<string> master;
string principal;
Option<string> secret;
bool authenticate;
- bool help;
Option<double> qps;
Option<Duration> duration;
};
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char** argv)
{
Flags flags;
@@ -303,26 +288,28 @@ int main(int argc, char** argv)
Try<Nothing> load = flags.load("MESOS_", argc, argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- exit(1);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
if (flags.help) {
- usage(argv[0], flags);
- exit(1);
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.master.isNone()) {
- EXIT(1) << "Missing required option --master. See --help";
+ cerr << flags.usage( "Missing required option --master") << endl;
+ return EXIT_FAILURE;
}
if (flags.qps.isNone()) {
- EXIT(1) << "Missing required option --qps. See --help";
+ cerr << flags.usage("Missing required option --qps") << endl;
+ return EXIT_FAILURE;
}
if (flags.qps.get() <= 0) {
- EXIT(1) << "--qps needs to be greater than zero";
+ cerr << flags.usage("--qps needs to be greater than zero") << endl;
+ return EXIT_FAILURE;
}
// We want the logger to catch failure signals.
@@ -344,7 +331,8 @@ int main(int argc, char** argv)
cout << "Enabling authentication for the framework" << endl;
if (flags.secret.isNone()) {
- EXIT(1) << "Expecting --secret when --authenticate is set";
+ cerr << "Expecting --secret when --authenticate is set" << endl;
+ return EXIT_FAILURE;
}
string secret = flags.secret.get();
@@ -364,7 +352,7 @@ int main(int argc, char** argv)
&scheduler, framework, flags.master.get());
}
- int status = driver->run() == DRIVER_STOPPED ? 0 : 1;
+ int status = driver->run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_SUCCESS;
// Ensure that the driver process terminates.
driver->stop();
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/low_level_scheduler_libprocess.cpp
----------------------------------------------------------------------
diff --git a/src/examples/low_level_scheduler_libprocess.cpp b/src/examples/low_level_scheduler_libprocess.cpp
index bee2e7e..bd228fd 100644
--- a/src/examples/low_level_scheduler_libprocess.cpp
+++ b/src/examples/low_level_scheduler_libprocess.cpp
@@ -427,5 +427,5 @@ int main(int argc, char** argv)
process::wait(scheduler);
delete scheduler;
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/low_level_scheduler_pthread.cpp
----------------------------------------------------------------------
diff --git a/src/examples/low_level_scheduler_pthread.cpp b/src/examples/low_level_scheduler_pthread.cpp
index fb8cd66..81388f1 100644
--- a/src/examples/low_level_scheduler_pthread.cpp
+++ b/src/examples/low_level_scheduler_pthread.cpp
@@ -483,5 +483,5 @@ int main(int argc, char** argv)
scheduler->wait();
delete scheduler;
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/examples/persistent_volume_framework.cpp
----------------------------------------------------------------------
diff --git a/src/examples/persistent_volume_framework.cpp b/src/examples/persistent_volume_framework.cpp
index 8a893fc..6a0c0cb 100644
--- a/src/examples/persistent_volume_framework.cpp
+++ b/src/examples/persistent_volume_framework.cpp
@@ -43,6 +43,7 @@
using namespace mesos;
using namespace mesos::internal;
+using std::cerr;
using std::cout;
using std::endl;
using std::ostringstream;
@@ -403,11 +404,6 @@ public:
"tasks_per_shard",
"The number of tasks should be launched per shard.",
3);
-
- add(&help,
- "help",
- "Print this help message",
- false);
}
Option<string> master;
@@ -415,23 +411,9 @@ public:
string principal;
size_t num_shards;
size_t tasks_per_shard;
- bool help;
};
-static string usage(const char* argv0, const flags::FlagsBase& flags)
-{
- ostringstream stream;
-
- stream << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-
- return stream.str();
-}
-
-
int main(int argc, char** argv)
{
Flags flags;
@@ -439,15 +421,18 @@ int main(int argc, char** argv)
Try<Nothing> load = flags.load("MESOS_", argc, argv);
if (load.isError()) {
- EXIT(1) << load.error() << endl << usage(argv[0], flags);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
if (flags.help) {
- EXIT(1) << usage(argv[0], flags);
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.master.isNone()) {
- EXIT(1) << "Missing required option --master. See --help";
+ cerr << flags.usage("Missing required option --master") << endl;
+ return EXIT_FAILURE;
}
logging::initialize(argv[0], flags, true); // Catch signals.
@@ -489,7 +474,7 @@ int main(int argc, char** argv)
framework,
flags.master.get());
- int status = driver->run() == DRIVER_STOPPED ? 0 : 1;
+ int status = driver->run() == DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
driver->stop();
delete driver;
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/health-check/main.cpp
----------------------------------------------------------------------
diff --git a/src/health-check/main.cpp b/src/health-check/main.cpp
index a4ce742..3607479 100644
--- a/src/health-check/main.cpp
+++ b/src/health-check/main.cpp
@@ -294,66 +294,60 @@ int main(int argc, char** argv)
Flags flags;
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- LOG(WARNING) << load.error();
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- return 0;
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.health_check_json.isNone()) {
- LOG(WARNING) << "Expected JSON with health check description";
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Expected JSON with health check description") << endl;
+ return EXIT_FAILURE;
}
Try<JSON::Object> parse =
JSON::parse<JSON::Object>(flags.health_check_json.get());
- if (parse.isError()) {
- LOG(WARNING) << "JSON parse error: " << parse.error();
- usage(argv[0], flags);
- return 0;
- }
- if (flags.executor.isNone()) {
- LOG(WARNING) << "Expected UPID for health check";
- usage(argv[0], flags);
- return 0;
+ if (parse.isError()) {
+ cerr << flags.usage("Failed to parse --health_check_json: " + parse.error())
+ << endl;
+ return EXIT_FAILURE;
}
Try<HealthCheck> check = protobuf::parse<HealthCheck>(parse.get());
+
if (check.isError()) {
- LOG(WARNING) << "JSON error: " << check.error();
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Failed to parse --health_check_json: " + check.error())
+ << endl;
+ return EXIT_SUCCESS;
+ }
+
+ if (flags.executor.isNone()) {
+ cerr << flags.usage("Missing required option --executor") << endl;
+ return EXIT_FAILURE;
}
if (check.get().has_http() && check.get().has_command()) {
- LOG(WARNING) << "Both HTTP and Command check passed in";
- return -1;
+ cerr << flags.usage("Both 'http' and 'command' health check requested")
+ << endl;
+ return EXIT_FAILURE;
}
if (!check.get().has_http() && !check.get().has_command()) {
- LOG(WARNING) << "No health check found";
- return -1;
+ cerr << flags.usage("Expecting one of 'http' or 'command' health check")
+ << endl;
+ return EXIT_FAILURE;
}
if (flags.task_id.isNone()) {
- LOG(WARNING) << "TaskID error: " << check.error();
- usage(argv[0], flags);
- return 0;
+ cerr << flags.usage("Missing required option --task_id") << endl;
+ return EXIT_FAILURE;
}
TaskID taskID;
@@ -377,8 +371,8 @@ int main(int argc, char** argv)
if (checking.isFailed()) {
LOG(WARNING) << "Health check failed " << checking.failure();
- return 1;
+ return EXIT_FAILURE;
}
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/launcher/executor.cpp
----------------------------------------------------------------------
diff --git a/src/launcher/executor.cpp b/src/launcher/executor.cpp
index de6f1b1..f79dc60 100644
--- a/src/launcher/executor.cpp
+++ b/src/launcher/executor.cpp
@@ -581,15 +581,6 @@ private:
} // namespace mesos {
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
class Flags : public flags::FlagsBase
{
public:
@@ -615,24 +606,17 @@ int main(int argc, char** argv)
{
Flags flags;
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
// Load flags from command line.
Try<Nothing> load = flags.load(None(), &argc, &argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- return -1;
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
// After flags.load(..., &argc, &argv) all flags will have been
@@ -653,5 +637,5 @@ int main(int argc, char** argv)
}
mesos::internal::CommandExecutor executor(override, path);
mesos::MesosExecutorDriver driver(&executor);
- return driver.run() == mesos::DRIVER_STOPPED ? 0 : 1;
+ return driver.run() == mesos::DRIVER_STOPPED ? EXIT_SUCCESS : EXIT_FAILURE;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/local/main.cpp
----------------------------------------------------------------------
diff --git a/src/local/main.cpp b/src/local/main.cpp
index a641b9e..ec21ed0 100644
--- a/src/local/main.cpp
+++ b/src/local/main.cpp
@@ -39,21 +39,11 @@ using mesos::internal::master::Master;
using mesos::internal::slave::Slave;
using std::cerr;
+using std::cout;
using std::endl;
using std::string;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Launches an in-memory cluster within a single process."
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char **argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -64,6 +54,10 @@ int main(int argc, char **argv)
// master::flags, then slave::Flags, then local::Flags.
local::Flags flags;
+ flags.setUsageMessage(
+ "Usage: " + os::basename(argv[0]).get() + " [...]\n\n" +
+ "Launches an in-memory cluster within a single process.");
+
// The following flags are executable specific (e.g., since we only
// have one instance of libprocess per execution, we only want to
// advertise the port and ip option once, here).
@@ -73,25 +67,18 @@ int main(int argc, char **argv)
Option<string> ip;
flags.add(&ip, "ip", "IP address to listen on");
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
// Load flags from environment and command line but allow unknown
// flags since we might have some master/slave flags as well.
Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- exit(1);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- exit(1);
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
// Initialize libprocess.
@@ -107,5 +94,5 @@ int main(int argc, char **argv)
process::wait(local::launch(flags));
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/benchmark.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.cpp b/src/log/tool/benchmark.cpp
index 01e5511..4895dd8 100644
--- a/src/log/tool/benchmark.cpp
+++ b/src/log/tool/benchmark.cpp
@@ -47,7 +47,6 @@ using std::cout;
using std::endl;
using std::ifstream;
using std::ofstream;
-using std::ostringstream;
using std::string;
using std::vector;
@@ -95,44 +94,30 @@ Benchmark::Flags::Flags()
"initialize",
"Whether to initialize the log",
true);
-
- add(&Flags::help,
- "help",
- "Prints the help message",
- false);
-}
-
-
-string Benchmark::usage(const string& argv0) const
-{
- ostringstream out;
-
- out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
- << endl
- << "This command is used to do performance test on the" << endl
- << "replicated log. It takes a trace file of write sizes" << endl
- << "and replay that trace to measure the latency of each" << endl
- << "write. The data to be written for each write can be" << endl
- << "specified using the '--type' flag." << endl
- << endl
- << "Supported OPTIONS:" << endl
- << flags.usage();
-
- return out.str();
}
Try<Nothing> Benchmark::execute(int argc, char** argv)
{
+ flags.setUsageMessage(
+ "Usage: " + name() + " [options]\n"
+ "\n"
+ "This command is used to do performance test on the\n"
+ "replicated log. It takes a trace file of write sizes\n"
+ "and replay that trace to measure the latency of each\n"
+ "write. The data to be written for each write can be\n"
+ "specified using the --type flag.\n"
+ "\n");
+
// Configure the tool by parsing command line arguments.
if (argc > 0 && argv != NULL) {
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- return Error(load.error() + "\n\n" + usage(argv[0]));
+ return Error(flags.usage(load.error()));
}
if (flags.help) {
- return Error(usage(argv[0]));
+ return Error(flags.usage());
}
process::initialize();
@@ -140,27 +125,27 @@ Try<Nothing> Benchmark::execute(int argc, char** argv)
}
if (flags.quorum.isNone()) {
- return Error("Missing flag '--quorum'");
+ return Error(flags.usage("Missing required option --quorum"));
}
if (flags.path.isNone()) {
- return Error("Missing flag '--path'");
+ return Error(flags.usage("Missing required option --path"));
}
if (flags.servers.isNone()) {
- return Error("Missing flag '--servers'");
+ return Error(flags.usage("Missing required option --servers"));
}
if (flags.znode.isNone()) {
- return Error("Missing flag '--znode'");
+ return Error(flags.usage("Missing required option --znode"));
}
if (flags.input.isNone()) {
- return Error("Missing flag '--input'");
+ return Error(flags.usage("Missing required option --input"));
}
if (flags.output.isNone()) {
- return Error("Missing flag '--output'");
+ return Error(flags.usage("Missing required option --output"));
}
// Initialize the log.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/benchmark.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/benchmark.hpp b/src/log/tool/benchmark.hpp
index e0109e2..5714b87 100644
--- a/src/log/tool/benchmark.hpp
+++ b/src/log/tool/benchmark.hpp
@@ -55,9 +55,6 @@ public:
// Users can change the default configuration by setting this flags.
Flags flags;
-
-private:
- std::string usage(const std::string& argv0) const;
};
} // namespace tool {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/initialize.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/initialize.cpp b/src/log/tool/initialize.cpp
index ccda7fb..a5146fd 100644
--- a/src/log/tool/initialize.cpp
+++ b/src/log/tool/initialize.cpp
@@ -16,9 +16,6 @@
* limitations under the License.
*/
-#include <iostream>
-#include <sstream>
-
#include <process/process.hpp>
#include <process/timeout.hpp>
@@ -31,8 +28,6 @@
using namespace process;
-using std::endl;
-using std::ostringstream;
using std::string;
namespace mesos {
@@ -50,40 +45,26 @@ Initialize::Flags::Flags()
"timeout",
"Maximum time allowed for the command to finish\n"
"(e.g., 500ms, 1sec, etc.)");
-
- add(&Flags::help,
- "help",
- "Prints the help message",
- false);
-}
-
-
-string Initialize::usage(const string& argv0) const
-{
- ostringstream out;
-
- out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
- << endl
- << "This command is used to initialize the log" << endl
- << endl
- << "Supported OPTIONS:" << endl
- << flags.usage();
-
- return out.str();
}
Try<Nothing> Initialize::execute(int argc, char** argv)
{
+ flags.setUsageMessage(
+ "Usage: " + name() + " [option]\n"
+ "\n"
+ "This command is used to initialize the log.\n"
+ "\n");
+
// Configure the tool by parsing command line arguments.
if (argc > 0 && argv != NULL) {
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- return Error(load.error() + "\n\n" + usage(argv[0]));
+ return Error(flags.usage(load.error()));
}
if (flags.help) {
- return Error(usage(argv[0]));
+ return Error(flags.usage());
}
process::initialize();
@@ -91,7 +72,7 @@ Try<Nothing> Initialize::execute(int argc, char** argv)
}
if (flags.path.isNone()) {
- return Error("Missing flag: '--path'");
+ return Error(flags.usage("Missing required option --path"));
}
// Setup the timeout if specified.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/initialize.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/initialize.hpp b/src/log/tool/initialize.hpp
index 10ac269..dc25e97 100644
--- a/src/log/tool/initialize.hpp
+++ b/src/log/tool/initialize.hpp
@@ -50,9 +50,6 @@ public:
// Users can change the default configuration by setting this flags.
Flags flags;
-
-private:
- std::string usage(const std::string& argv0) const;
};
} // namespace tool {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/read.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/read.cpp b/src/log/tool/read.cpp
index d141385..08d1932 100644
--- a/src/log/tool/read.cpp
+++ b/src/log/tool/read.cpp
@@ -19,12 +19,12 @@
#include <stdint.h>
#include <iostream>
-#include <sstream>
#include <process/process.hpp>
#include <process/timeout.hpp>
#include <stout/error.hpp>
+#include <stout/stringify.hpp>
#include "log/replica.hpp"
#include "log/tool/read.hpp"
@@ -36,7 +36,6 @@ using namespace process;
using std::cout;
using std::endl;
using std::list;
-using std::ostringstream;
using std::string;
namespace mesos {
@@ -62,40 +61,26 @@ Read::Flags::Flags()
"timeout",
"Maximum time allowed for the command to finish\n"
"(e.g., 500ms, 1sec, etc.)");
-
- add(&Flags::help,
- "help",
- "Prints the help message",
- false);
-}
-
-
-string Read::usage(const string& argv0) const
-{
- ostringstream out;
-
- out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
- << endl
- << "This command is used to read the log" << endl
- << endl
- << "Supported OPTIONS:" << endl
- << flags.usage();
-
- return out.str();
}
Try<Nothing> Read::execute(int argc, char** argv)
{
+ flags.setUsageMessage(
+ "Usage: " + name() + " [options]\n"
+ "\n"
+ "This command is used to read the log.\n"
+ "\n");
+
// Configure the tool by parsing command line arguments.
if (argc > 0 && argv != NULL) {
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- return Error(load.error() + "\n\n" + usage(argv[0]));
+ return Error(flags.usage(load.error()));
}
if (flags.help) {
- return Error(usage(argv[0]));
+ return Error(flags.usage());
}
process::initialize();
@@ -103,7 +88,7 @@ Try<Nothing> Read::execute(int argc, char** argv)
}
if (flags.path.isNone()) {
- return Error("Missing flag '--path'");
+ return Error(flags.usage("Missing required flag --path"));
}
// Setup the timeout if specified.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/read.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/read.hpp b/src/log/tool/read.hpp
index 9a6971b..f5958cd 100644
--- a/src/log/tool/read.hpp
+++ b/src/log/tool/read.hpp
@@ -54,9 +54,6 @@ public:
// Users can change the default configuration by setting this flags.
Flags flags;
-
-private:
- std::string usage(const std::string& argv0) const;
};
} // namespace tool {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/replica.cpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.cpp b/src/log/tool/replica.cpp
index 3985fc7..1eba480 100644
--- a/src/log/tool/replica.cpp
+++ b/src/log/tool/replica.cpp
@@ -17,7 +17,6 @@
*/
#include <iostream>
-#include <sstream>
#include <process/future.hpp>
#include <process/process.hpp>
@@ -33,7 +32,6 @@
using namespace process;
using std::endl;
-using std::ostringstream;
using std::string;
namespace mesos {
@@ -63,40 +61,26 @@ Replica::Flags::Flags()
"initialize",
"Whether to initialize the log",
true);
-
- add(&Flags::help,
- "help",
- "Prints the help message",
- false);
-}
-
-
-string Replica::usage(const string& argv0) const
-{
- ostringstream out;
-
- out << "Usage: " << argv0 << " " << name() << " [OPTIONS]" << endl
- << endl
- << "This command is used to start a replica server" << endl
- << endl
- << "Supported OPTIONS:" << endl
- << flags.usage();
-
- return out.str();
}
Try<Nothing> Replica::execute(int argc, char** argv)
{
+ flags.setUsageMessage(
+ "Usage: " + name() + " [options]\n"
+ "\n"
+ "This command is used to start a replica server.\n"
+ "\n");
+
// Configure the tool by parsing command line arguments.
if (argc > 0 && argv != NULL) {
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- return Error(load.error() + "\n\n" + usage(argv[0]));
+ return Error(flags.usage(load.error()));
}
if (flags.help) {
- return Error(usage(argv[0]));
+ return Error(flags.usage());
}
process::initialize();
@@ -104,19 +88,19 @@ Try<Nothing> Replica::execute(int argc, char** argv)
}
if (flags.quorum.isNone()) {
- return Error("Missing flag '--quorum'");
+ return Error(flags.usage("Missing required option --quorum"));
}
if (flags.path.isNone()) {
- return Error("Missing flag '--path'");
+ return Error(flags.usage("Missing required option --path"));
}
if (flags.servers.isNone()) {
- return Error("Missing flag '--servers'");
+ return Error(flags.usage("Missing required option --servers"));
}
if (flags.znode.isNone()) {
- return Error("Missing flag '--znode'");
+ return Error(flags.usage("Missing required option --znode"));
}
// Initialize the log.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/log/tool/replica.hpp
----------------------------------------------------------------------
diff --git a/src/log/tool/replica.hpp b/src/log/tool/replica.hpp
index 7140c7e..7a8f391 100644
--- a/src/log/tool/replica.hpp
+++ b/src/log/tool/replica.hpp
@@ -55,9 +55,6 @@ public:
// Users can change the default configuration by setting this flags.
Flags flags;
-
-private:
- std::string usage(const std::string& argv0) const;
};
} // namespace tool {
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index d5666bc..3d490c3 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -98,15 +98,6 @@ using std::string;
using std::vector;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
void version()
{
cout << "mesos" << " " << MESOS_VERSION << endl;
@@ -137,28 +128,21 @@ int main(int argc, char** argv)
" zk://username:password@host1:port1,host2:port2,.../path\n"
" file:///path/to/file (where file contains one of the above)");
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
Try<Nothing> load = flags.load("MESOS_", argc, argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- exit(1);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
if (flags.version) {
version();
- exit(0);
+ return EXIT_SUCCESS;
}
- if (help) {
- usage(argv[0], flags);
- exit(1);
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
// Initialize modules. Note that since other subsystems may depend
@@ -166,7 +150,7 @@ int main(int argc, char** argv)
if (flags.modules.isSome()) {
Try<Nothing> result = ModuleManager::load(flags.modules.get());
if (result.isError()) {
- EXIT(1) << "Error loading modules: " << result.error();
+ EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
}
}
@@ -174,7 +158,7 @@ int main(int argc, char** argv)
if (flags.hooks.isSome()) {
Try<Nothing> result = HookManager::initialize(flags.hooks.get());
if (result.isError()) {
- EXIT(1) << "Error installing hooks: " << result.error();
+ EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
}
}
@@ -206,8 +190,9 @@ int main(int argc, char** argv)
Try<Allocator*> allocator = Allocator::create(allocatorName);
if (allocator.isError()) {
- EXIT(1) << "Failed to create '" << allocatorName << "' allocator: "
- << allocator.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create '" << allocatorName
+ << "' allocator: " << allocator.error();
}
CHECK_NOTNULL(allocator.get());
@@ -218,8 +203,9 @@ int main(int argc, char** argv)
if (flags.registry == "in_memory") {
if (flags.registry_strict) {
- EXIT(1) << "Cannot use '--registry_strict' when using in-memory storage"
- << " based registry";
+ EXIT(EXIT_FAILURE)
+ << "Cannot use '--registry_strict' when using in-memory storage"
+ << " based registry";
}
storage = new state::InMemoryStorage();
} else if (flags.registry == "replicated_log" ||
@@ -227,25 +213,28 @@ int main(int argc, char** argv)
// TODO(bmahler): "log_storage" is present for backwards
// compatibility, can be removed before 0.19.0.
if (flags.work_dir.isNone()) {
- EXIT(1) << "--work_dir needed for replicated log based registry";
+ EXIT(EXIT_FAILURE)
+ << "--work_dir needed for replicated log based registry";
}
Try<Nothing> mkdir = os::mkdir(flags.work_dir.get());
if (mkdir.isError()) {
- EXIT(1) << "Failed to create work directory '" << flags.work_dir.get()
- << "': " << mkdir.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create work directory '" << flags.work_dir.get()
+ << "': " << mkdir.error();
}
if (zk.isSome()) {
// Use replicated log with ZooKeeper.
if (flags.quorum.isNone()) {
- EXIT(1) << "Need to specify --quorum for replicated log based"
- << " registry when using ZooKeeper";
+ EXIT(EXIT_FAILURE)
+ << "Need to specify --quorum for replicated log based"
+ << " registry when using ZooKeeper";
}
Try<zookeeper::URL> url = zookeeper::URL::parse(zk.get());
if (url.isError()) {
- EXIT(1) << "Error parsing ZooKeeper URL: " << url.error();
+ EXIT(EXIT_FAILURE) << "Error parsing ZooKeeper URL: " << url.error();
}
log = new Log(
@@ -266,8 +255,9 @@ int main(int argc, char** argv)
}
storage = new state::LogStorage(log);
} else {
- EXIT(1) << "'" << flags.registry << "' is not a supported"
- << " option for registry persistence";
+ EXIT(EXIT_FAILURE)
+ << "'" << flags.registry << "' is not a supported"
+ << " option for registry persistence";
}
CHECK_NOTNULL(storage);
@@ -285,7 +275,8 @@ int main(int argc, char** argv)
// Option<string>.
Try<MasterContender*> contender_ = MasterContender::create(zk.get(""));
if (contender_.isError()) {
- EXIT(1) << "Failed to create a master contender: " << contender_.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create a master contender: " << contender_.error();
}
contender = contender_.get();
@@ -293,7 +284,8 @@ int main(int argc, char** argv)
// Option<string>.
Try<MasterDetector*> detector_ = MasterDetector::create(zk.get(""));
if (detector_.isError()) {
- EXIT(1) << "Failed to create a master detector: " << detector_.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create a master detector: " << detector_.error();
}
detector = detector_.get();
@@ -302,8 +294,9 @@ int main(int argc, char** argv)
Try<Owned<Authorizer>> create = Authorizer::create(flags.acls.get());
if (create.isError()) {
- EXIT(1) << "Failed to initialize the authorizer: "
- << create.error() << " (see --acls flag)";
+ EXIT(EXIT_FAILURE)
+ << "Failed to initialize the authorizer: "
+ << create.error() << " (see --acls flag)";
}
// Now pull out the authorizer but need to make a copy since we
@@ -320,25 +313,28 @@ int main(int argc, char** argv)
strings::tokenize(flags.slave_removal_rate_limit.get(), "/");
if (tokens.size() != 2) {
- EXIT(1) << "Invalid slave_removal_rate_limit: "
- << flags.slave_removal_rate_limit.get()
- << ". Format is <Number of slaves>/<Duration>";
+ EXIT(EXIT_FAILURE)
+ << "Invalid slave_removal_rate_limit: "
+ << flags.slave_removal_rate_limit.get()
+ << ". Format is <Number of slaves>/<Duration>";
}
Try<int> permits = numify<int>(tokens[0]);
if (permits.isError()) {
- EXIT(1) << "Invalid slave_removal_rate_limit: "
- << flags.slave_removal_rate_limit.get()
- << ". Format is <Number of slaves>/<Duration>"
- << ": " << permits.error();
+ EXIT(EXIT_FAILURE)
+ << "Invalid slave_removal_rate_limit: "
+ << flags.slave_removal_rate_limit.get()
+ << ". Format is <Number of slaves>/<Duration>"
+ << ": " << permits.error();
}
Try<Duration> duration = Duration::parse(tokens[1]);
if (duration.isError()) {
- EXIT(1) << "Invalid slave_removal_rate_limit: "
- << flags.slave_removal_rate_limit.get()
- << ". Format is <Number of slaves>/<Duration>"
- << ": " << duration.error();
+ EXIT(EXIT_FAILURE)
+ << "Invalid slave_removal_rate_limit: "
+ << flags.slave_removal_rate_limit.get()
+ << ". Format is <Number of slaves>/<Duration>"
+ << ": " << duration.error();
}
slaveRemovalLimiter = new RateLimiter(permits.get(), duration.get());
@@ -348,7 +344,8 @@ int main(int argc, char** argv)
foreach (const string& name, ModuleManager::find<Anonymous>()) {
Try<Anonymous*> create = ModuleManager::create<Anonymous>(name);
if (create.isError()) {
- EXIT(1) << "Failed to create anonymous module named '" << name << "'";
+ EXIT(EXIT_FAILURE)
+ << "Failed to create anonymous module named '" << name << "'";
}
// We don't bother keeping around the pointer to this anonymous
@@ -399,5 +396,5 @@ int main(int argc, char** argv)
delete authorizer.get();
}
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/containerizer/isolators/network/port_mapping.cpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.cpp b/src/slave/containerizer/isolators/network/port_mapping.cpp
index d3c1918..781c35b 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.cpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.cpp
@@ -312,11 +312,6 @@ const char* PortMappingUpdate::NAME = "update";
PortMappingUpdate::Flags::Flags()
{
- add(&help,
- "help",
- "Prints this help message",
- false);
-
add(ð0_name,
"eth0_name",
"The name of the public network interface (e.g., eth0)");
@@ -581,11 +576,6 @@ const char* PortMappingStatistics::NAME = "statistics";
PortMappingStatistics::Flags::Flags()
{
- add(&help,
- "help",
- "Prints this help message",
- false);
-
add(&pid,
"pid",
"The pid of the process whose namespaces we will enter");
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/containerizer/isolators/network/port_mapping.hpp
----------------------------------------------------------------------
diff --git a/src/slave/containerizer/isolators/network/port_mapping.hpp b/src/slave/containerizer/isolators/network/port_mapping.hpp
index 52c7e7c..9f83af1 100644
--- a/src/slave/containerizer/isolators/network/port_mapping.hpp
+++ b/src/slave/containerizer/isolators/network/port_mapping.hpp
@@ -342,7 +342,6 @@ public:
{
Flags();
- bool help;
Option<std::string> eth0_name;
Option<std::string> lo_name;
Option<pid_t> pid;
@@ -372,7 +371,6 @@ public:
{
Flags();
- bool help;
Option<pid_t> pid;
bool enable_socket_statistics_summary;
bool enable_socket_statistics_details;
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/slave/main.cpp
----------------------------------------------------------------------
diff --git a/src/slave/main.cpp b/src/slave/main.cpp
index f762f5b..e3a45f4 100644
--- a/src/slave/main.cpp
+++ b/src/slave/main.cpp
@@ -62,15 +62,6 @@ using std::endl;
using std::string;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
void version()
{
cout << "mesos" << " " << MESOS_VERSION << endl;
@@ -100,32 +91,28 @@ int main(int argc, char** argv)
" zk://username:password@host1:port1,host2:port2,.../path\n"
" file:///path/to/file (where file contains one of the above)");
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
Try<Nothing> load = flags.load("MESOS_", argc, argv);
+ // TODO(marco): this pattern too should be abstracted away
+ // in FlagsBase; I have seen it at least 15 times.
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- EXIT(1);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- EXIT(1);
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.version) {
version();
- exit(0);
+ return EXIT_SUCCESS;
}
if (master.isNone()) {
- EXIT(1) << "Missing required option --master";
+ cerr << flags.usage("Missing required option --master") << endl;
+ return EXIT_FAILURE;
}
// Initialize modules. Note that since other subsystems may depend
@@ -133,7 +120,7 @@ int main(int argc, char** argv)
if (flags.modules.isSome()) {
Try<Nothing> result = ModuleManager::load(flags.modules.get());
if (result.isError()) {
- EXIT(1) << "Error loading modules: " << result.error();
+ EXIT(EXIT_FAILURE) << "Error loading modules: " << result.error();
}
}
@@ -141,7 +128,7 @@ int main(int argc, char** argv)
if (flags.hooks.isSome()) {
Try<Nothing> result = HookManager::initialize(flags.hooks.get());
if (result.isError()) {
- EXIT(1) << "Error installing hooks: " << result.error();
+ EXIT(EXIT_FAILURE) << "Error installing hooks: " << result.error();
}
}
@@ -174,21 +161,23 @@ int main(int argc, char** argv)
Containerizer::create(flags, false, &fetcher);
if (containerizer.isError()) {
- EXIT(1) << "Failed to create a containerizer: "
- << containerizer.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create a containerizer: " << containerizer.error();
}
Try<MasterDetector*> detector = MasterDetector::create(master.get());
if (detector.isError()) {
- EXIT(1) << "Failed to create a master detector: " << detector.error();
+ EXIT(EXIT_FAILURE)
+ << "Failed to create a master detector: " << detector.error();
}
// Create anonymous modules.
foreach (const string& name, ModuleManager::find<Anonymous>()) {
Try<Anonymous*> create = ModuleManager::create<Anonymous>(name);
if (create.isError()) {
- EXIT(1) << "Failed to create anonymous module named '" << name << "'";
+ EXIT(EXIT_FAILURE)
+ << "Failed to create anonymous module named '" << name << "'";
}
// We don't bother keeping around the pointer to this anonymous
@@ -200,8 +189,6 @@ int main(int argc, char** argv)
// terminating.
}
- LOG(INFO) << "Starting Mesos slave";
-
Files files;
GarbageCollector gc;
StatusUpdateManager statusUpdateManager(flags);
@@ -210,10 +197,13 @@ int main(int argc, char** argv)
ResourceEstimator::create(flags.resource_estimator);
if (resourceEstimator.isError()) {
- EXIT(1) << "Failed to create resource estimator: "
- << resourceEstimator.error();
+ cerr << "Failed to create resource estimator: "
+ << resourceEstimator.error() << endl;
+ return EXIT_FAILURE;
}
+ LOG(INFO) << "Starting Mesos slave";
+
Slave* slave = new Slave(
flags,
detector.get(),
@@ -234,5 +224,5 @@ int main(int argc, char** argv)
delete containerizer.get();
- return 0;
+ return EXIT_SUCCESS;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/tests/main.cpp
----------------------------------------------------------------------
diff --git a/src/tests/main.cpp b/src/tests/main.cpp
index e3fff5d..970a8b0 100644
--- a/src/tests/main.cpp
+++ b/src/tests/main.cpp
@@ -43,52 +43,37 @@ using namespace mesos::internal;
using namespace mesos::internal::tests;
using std::cerr;
+using std::cout;
using std::endl;
using std::string;
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char** argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
using mesos::internal::tests::flags; // Needed to disabmiguate.
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
// Load flags from environment and command line but allow unknown
// flags (since we might have gtest/gmock flags as well).
Try<Nothing> load = flags.load("MESOS_", argc, argv, true);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- exit(1);
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- cerr << endl;
+ if (flags.help) {
+ cout << flags.usage() << endl;
testing::InitGoogleTest(&argc, argv); // Get usage from gtest too.
- exit(1);
+ return EXIT_SUCCESS;
}
// Initialize Modules.
Try<Nothing> result = tests::initModules(flags.modules);
if (result.isError()) {
- EXIT(1) << "Error initializing modules: " << result.error();
+ cerr << "Error initializing modules: " << result.error() << endl;
+ return EXIT_FAILURE;
}
// Initialize libprocess.
@@ -114,8 +99,8 @@ int main(int argc, char** argv)
testing::InitGoogleTest(&argc, argv);
testing::FLAGS_gtest_death_test_style = "threadsafe";
- std::cout << "Source directory: " << flags.source_dir << std::endl;
- std::cout << "Build directory: " << flags.build_dir << std::endl;
+ cout << "Source directory: " << flags.source_dir << endl;
+ cout << "Build directory: " << flags.build_dir << endl;
// Instantiate our environment. Note that it will be managed by
// gtest after we add it via testing::AddGlobalTestEnvironment.
http://git-wip-us.apache.org/repos/asf/mesos/blob/4cc0ffc4/src/usage/main.cpp
----------------------------------------------------------------------
diff --git a/src/usage/main.cpp b/src/usage/main.cpp
index 97f55e9..86fd796 100644
--- a/src/usage/main.cpp
+++ b/src/usage/main.cpp
@@ -60,62 +60,45 @@ public:
};
-void usage(const char* argv0, const flags::FlagsBase& flags)
-{
- cerr << "Usage: " << os::basename(argv0).get() << " [...]" << endl
- << endl
- << "Supported options:" << endl
- << flags.usage();
-}
-
-
int main(int argc, char** argv)
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
Flags flags;
- bool help;
- flags.add(&help,
- "help",
- "Prints this help message",
- false);
-
Try<Nothing> load = flags.load(None(), argc, argv);
if (load.isError()) {
- cerr << load.error() << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage(load.error()) << endl;
+ return EXIT_FAILURE;
}
- if (help) {
- usage(argv[0], flags);
- return 0;
+ if (flags.help) {
+ cout << flags.usage() << endl;
+ return EXIT_SUCCESS;
}
if (flags.pid.isNone()) {
- cerr << "Missing pid" << endl;
- usage(argv[0], flags);
- return -1;
+ cerr << flags.usage("Missing required option --pid") << endl;
+ return EXIT_FAILURE;
}
Try<ResourceStatistics> statistics = mesos::internal::usage(flags.pid.get());
if (statistics.isError()) {
cerr << "Failed to get usage: " << statistics.error() << endl;
- return -1;
+ return EXIT_FAILURE;
}
if (flags.recordio) {
Try<Nothing> write = protobuf::write(STDOUT_FILENO, statistics.get());
if (write.isError()) {
cerr << "Failed to write record: " << write.error() << endl;
- return -1;
+ return EXIT_FAILURE;
}
} else {
cout << stringify(JSON::Protobuf(statistics.get())) << endl;
}
- return 0;
+ return EXIT_SUCCESS;
}
[2/2] mesos git commit: Refactored common functionality into
FlagsBase.
Posted by be...@apache.org.
Refactored common functionality into FlagsBase.
Jira: MESOS-2711
Every program that uses stout's `FlagsBase` ends up re-implementing
the `usage()` function, and adding a `bool help` (and associated
--help flag); this functionality has now been refactored in the base
class and is available everywhere.
This change attempts to be backward-compatible, so it does not alter
the behavior of the program when --help is invoked (by, e.g.,
automatically printing usage and exiting) but leaves up to the caller
to check for `flags.help` and then decide what action to take.
There is now a default behavior for the "leader" ("Usage: <program
name> [options]") but the client API allows to modify that too.
Note - anywhere I found the use of the `--help` flag the behavior was
the same: print usage and exit (see also
https://reviews.apache.org/r/34195).
Review: https://reviews.apache.org/r/34193
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/1694bda8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/1694bda8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/1694bda8
Branch: refs/heads/master
Commit: 1694bda8d8b7a43ac8fd857c5909d8a1a25f2754
Parents: f855fb7
Author: Marco Massenzio <ma...@mesosphere.io>
Authored: Mon Jun 1 03:49:00 2015 -0700
Committer: Benjamin Hindman <be...@gmail.com>
Committed: Mon Jun 1 15:59:38 2015 -0700
----------------------------------------------------------------------
.../stout/include/stout/flags/flags.hpp | 126 +++++++++++++++----
.../3rdparty/stout/tests/flags_tests.cpp | 70 ++++++++++-
2 files changed, 171 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/1694bda8/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
index fb383b4..61a405f 100644
--- a/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
+++ b/3rdparty/libprocess/3rdparty/stout/include/stout/flags/flags.hpp
@@ -42,6 +42,7 @@ namespace flags {
class FlagsBase
{
public:
+ FlagsBase() { add(&help, "help", "Prints this help message", false); }
virtual ~FlagsBase() {}
// Load any flags from the environment given the variable prefix,
@@ -64,11 +65,11 @@ public:
// Load any flags from the environment as above but remove processed
// flags from 'argv' and update 'argc' appropriately. For example:
//
- // argv = ["/path/to/program", "--arg1", "hello", "--arg2", "--", "world"]
+ // argv = ["/path/program", "--arg1", "hi", "--arg2", "--", "bye"]
//
// Becomes:
//
- // argv = ["/path/to/program", "hello", "world"]
+ // argv = ["/path/program", "hi", "bye"]
virtual Try<Nothing> load(
const Option<std::string>& prefix,
int* argc,
@@ -84,18 +85,57 @@ public:
const std::map<std::string, std::string>& values,
bool unknowns = false);
- // Returns a string describing the flags.
- std::string usage() const;
+ // Returns a string describing the flags, preceded by a "usage
+ // message" that will be prepended to that description (see
+ // 'FlagsBase::usageMessage_').
+ //
+ // The optional 'message' passed to this function will be prepended
+ // to the generated string returned from this function.
+ //
+ // Derived classes and clients can modify the standard usage message
+ // by setting it before calling this method via 'setUsageMessage()'.
+ //
+ // This allows one to set a generic message that will be used for
+ // each invocation of this method, and to additionally add one for
+ // the particular invocation:
+ //
+ // MyFlags flags;
+ // flags.setUsageMessage("Custom Usage Message");
+ // ...
+ // if (flags.foo.isNone()) {
+ // std::cerr << flags.usage("Missing required --foo flag");
+ // }
+ //
+ // The 'message' would be emitted first, followed by a blank line,
+ // then the 'usageMessage_', finally followed by the flags'
+ // description, for example:
+ //
+ // Missing required --foo flag
+ //
+ // Custom Usage Message
+ //
+ // --[no-]help Prints this help message. (default: false)
+ // --foo=VALUE Description about 'foo' here.
+ // --bar=VALUE Description about 'bar' here. (default: 42)
+ //
+ std::string usage(const Option<std::string>& message = None()) const;
+
+ // Sets the default message that is prepended to the flags'
+ // description in 'usage()'.
+ void setUsageMessage(const std::string& message)
+ {
+ usageMessage_ = Some(message);
+ }
typedef std::map<std::string, Flag>::const_iterator const_iterator;
- const_iterator begin() const { return flags.begin(); }
- const_iterator end() const { return flags.end(); }
+ const_iterator begin() const { return flags_.begin(); }
+ const_iterator end() const { return flags_.end(); }
typedef std::map<std::string, Flag>::iterator iterator;
- iterator begin() { return flags.begin(); }
- iterator end() { return flags.end(); }
+ iterator begin() { return flags_.begin(); }
+ iterator end() { return flags_.end(); }
template <typename T1, typename T2>
void add(T1* t1,
@@ -122,12 +162,31 @@ protected:
void add(const Flag& flag);
+public:
+ // TODO(marco): IMO the entire --help functionality should be
+ // encapsulated inside the FlagsBase class.
+ // For now, exposing this for the caller(s) to decide what to
+ // do when the user asks for help.
+ bool help;
+
+protected:
+ // The program's name, extracted from argv[0] by default;
+ // declared 'protected' so that derived classes can alter this
+ // behavior.
+ std::string programName_;
+
+ // An optional custom usage message, will be printed 'as is'
+ // just above the list of flags and their explanation.
+ // It is 'None' by default, in which case the default
+ // behavior is to print "Usage:" followed by the 'programName_'.
+ Option<std::string> usageMessage_;
+
private:
// Extract environment variable "flags" with the specified prefix.
std::map<std::string, Option<std::string> > extract(
const std::string& prefix);
- std::map<std::string, Flag> flags;
+ std::map<std::string, Flag> flags_;
};
@@ -141,7 +200,7 @@ class _Flags4 : public virtual FlagsBase {};
class _Flags5 : public virtual FlagsBase {};
-// TODO(benh): Add some "type constraints" for template paramters to
+// TODO(benh): Add some "type constraints" for template parameters to
// make sure they are all of type FlagsBase.
template <typename Flags1 = _Flags1,
typename Flags2 = _Flags2,
@@ -287,14 +346,14 @@ void FlagsBase::add(
inline void FlagsBase::add(const Flag& flag)
{
- if (flags.count(flag.name) > 0) {
+ if (flags_.count(flag.name) > 0) {
EXIT(1) << "Attempted to add duplicate flag '" << flag.name << "'";
} else if (flag.name.find("no-") == 0) {
EXIT(1) << "Attempted to add flag '" << flag.name
<< "' that starts with the reserved 'no-' prefix";
}
- flags[flag.name] = flag;
+ flags_[flag.name] = flag;
}
@@ -312,8 +371,8 @@ inline std::map<std::string, Option<std::string> > FlagsBase::extract(
name = strings::lower(name); // Allow PREFIX_NAME or PREFIX_name.
// Only add if it's a known flag.
- if (flags.count(name) > 0 ||
- (name.find("no-") == 0 && flags.count(name.substr(3)) > 0)) {
+ if (flags_.count(name) > 0 ||
+ (name.find("no-") == 0 && flags_.count(name.substr(3)) > 0)) {
values[name] = Some(value);
}
}
@@ -338,10 +397,15 @@ inline Try<Nothing> FlagsBase::load(
{
std::map<std::string, Option<std::string> > values;
+ // Grab the program name from argv[0].
+ programName_ = argc > 0 ? os::basename(argv[0]).get() : "";
+
if (prefix.isSome()) {
values = extract(prefix.get());
}
+
+
// Read flags from the command line.
for (int i = 1; i < argc; i++) {
const std::string arg(strings::trim(argv[i]));
@@ -398,6 +462,9 @@ inline Try<Nothing> FlagsBase::load(
values = extract(prefix.get());
}
+ // Grab the program name from argv, without removing it.
+ programName_ = argc > 0 ? os::basename(*(argv[0])).get() : "";
+
// Keep the arguments that are not being processed as flags.
std::vector<char*> args;
@@ -477,30 +544,30 @@ inline Try<Nothing> FlagsBase::load(
const std::string& name = iterator->first;
const Option<std::string>& value = iterator->second;
- if (flags.count(name) > 0) {
+ if (flags_.count(name) > 0) {
if (value.isSome()) { // --name=value
- if (flags[name].boolean && value.get() == "") {
- flags[name].loader(this, "true"); // Should never fail.
+ if (flags_[name].boolean && value.get() == "") {
+ flags_[name].loader(this, "true"); // Should never fail.
} else {
- Try<Nothing> loader = flags[name].loader(this, value.get());
+ Try<Nothing> loader = flags_[name].loader(this, value.get());
if (loader.isError()) {
return Error(
"Failed to load flag '" + name + "': " + loader.error());
}
}
} else { // --name
- if (flags[name].boolean) {
- flags[name].loader(this, "true"); // Should never fail.
+ if (flags_[name].boolean) {
+ flags_[name].loader(this, "true"); // Should never fail.
} else {
return Error(
"Failed to load non-boolean flag '" + name + "': Missing value");
}
}
} else if (name.find("no-") == 0) {
- if (flags.count(name.substr(3)) > 0) { // --no-name
- if (flags[name.substr(3)].boolean) {
+ if (flags_.count(name.substr(3)) > 0) { // --no-name
+ if (flags_[name.substr(3)].boolean) {
if (value.isNone() || value.get() == "") {
- flags[name.substr(3)].loader(this, "false"); // Should never fail.
+ flags_[name.substr(3)].loader(this, "false"); // Should never fail.
} else {
return Error(
"Failed to load boolean flag '" + name.substr(3) +
@@ -540,12 +607,22 @@ inline Try<Nothing> FlagsBase::load(
}
-inline std::string FlagsBase::usage() const
+inline std::string FlagsBase::usage( const Option<std::string>& message) const
{
const int PAD = 5;
std::string usage;
+ if (message.isSome()) {
+ usage = message.get() + "\n\n";
+ }
+
+ if (usageMessage_.isNone()) {
+ usage += "Usage: " + programName_ + " [options]\n\n";
+ } else {
+ usage += usageMessage_.get() + "\n\n";
+ }
+
std::map<std::string, std::string> col1; // key -> col 1 string.
// Construct string for the first column and store width of column.
@@ -581,6 +658,7 @@ inline std::string FlagsBase::usage() const
usage += line;
}
}
+
return usage;
}
http://git-wip-us.apache.org/repos/asf/mesos/blob/1694bda8/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
index 0028119..a6e8ba9 100644
--- a/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
+++ b/3rdparty/libprocess/3rdparty/stout/tests/flags_tests.cpp
@@ -19,9 +19,17 @@
using namespace flags;
+using std::cout;
+using std::endl;
using std::string;
using std::map;
+
+// Just used to test that the default implementation
+// of --help and 'usage()' works as intended.
+class EmptyFlags : public FlagsBase {};
+
+
class TestFlags : public virtual FlagsBase
{
public:
@@ -478,11 +486,15 @@ TEST(FlagsTest, Errors)
}
-TEST(FlagsTest, Usage)
+TEST(FlagsTest, UsageMessage)
{
TestFlags flags;
+ flags.setUsageMessage("This is a test");
EXPECT_EQ(
+ "This is a test\n"
+ "\n"
+ " --[no-]help Prints this help message (default: false)\n"
" --name1=VALUE Set name1 (default: ben folds)\n"
" --name2=VALUE Set name2 (default: 42)\n"
" --[no-]name3 Set name3 (default: false)\n"
@@ -492,6 +504,62 @@ TEST(FlagsTest, Usage)
}
+TEST(FlagsTest, EmptyUsage)
+{
+ EmptyFlags flags;
+
+ EXPECT_EQ(
+ "Usage: [options]\n"
+ "\n"
+ " --[no-]help Prints this help message (default: false)\n",
+ flags.usage());
+}
+
+
+TEST(FlagsTest, ProgramName)
+{
+ // To test with a custom program name.
+ class MyTestFlags : public TestFlags
+ {
+ public:
+ MyTestFlags() { programName_ = "TestProgram"; }
+ };
+
+
+ MyTestFlags flags;
+
+ EXPECT_EQ(
+ "Usage: TestProgram [options]\n"
+ "\n"
+ " --[no-]help Prints this help message (default: false)\n"
+ " --name1=VALUE Set name1 (default: ben folds)\n"
+ " --name2=VALUE Set name2 (default: 42)\n"
+ " --[no-]name3 Set name3 (default: false)\n"
+ " --[no-]name4 Set name4\n"
+ " --[no-]name5 Set name5\n",
+ flags.usage());
+}
+
+
+TEST(FlagsTest, OptionalMessage)
+{
+ TestFlags flags;
+
+ EXPECT_EQ(
+ "Good news: this test passed!\n"
+ "\n"
+ "Usage: [options]\n"
+ "\n"
+ " --[no-]help Prints this help message (default: false)\n"
+ " --name1=VALUE Set name1 (default: ben folds)\n"
+ " --name2=VALUE Set name2 (default: 42)\n"
+ " --[no-]name3 Set name3 (default: false)\n"
+ " --[no-]name4 Set name4\n"
+ " --[no-]name5 Set name5\n",
+ flags.usage("Good news: this test passed!"));
+}
+
+
TEST(FlagsTest, Duration)
{
Flags<TestFlags> flags;