You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by vi...@apache.org on 2016/05/12 19:15:07 UTC

[1/6] mesos git commit: Added support to mesos to work with flag alias.

Repository: mesos
Updated Branches:
  refs/heads/master 3bd9ccf0c -> af894485b


Added support to mesos to work with flag alias.

Review: https://reviews.apache.org/r/46624


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/af894485
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/af894485
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/af894485

Branch: refs/heads/master
Commit: af894485b70d0e489c3d3d52f0404ebb6f7d8bd8
Parents: f0dd6ee
Author: Vinod Kone <vi...@gmail.com>
Authored: Sun Apr 24 15:09:12 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 src/master/http.cpp | 8 ++++----
 src/slave/http.cpp  | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/af894485/src/master/http.cpp
----------------------------------------------------------------------
diff --git a/src/master/http.cpp b/src/master/http.cpp
index b02ae54..6cefcc8 100644
--- a/src/master/http.cpp
+++ b/src/master/http.cpp
@@ -904,10 +904,10 @@ Future<Response> Master::Http::_flags(const Request& request) const
 
   {
     JSON::Object flags;
-    foreachpair (const string& name, const flags::Flag& flag, master->flags) {
+    foreachvalue (const flags::Flag& flag, master->flags) {
       Option<string> value = flag.stringify(master->flags);
       if (value.isSome()) {
-        flags.values[name] = value.get();
+        flags.values[flag.effective_name().value] = value.get();
       }
     }
     object.values["flags"] = std::move(flags);
@@ -1528,10 +1528,10 @@ Future<Response> Master::Http::state(
     }
 
     writer->field("flags", [this](JSON::ObjectWriter* writer) {
-      foreachpair (const string& name, const flags::Flag& flag, master->flags) {
+      foreachvalue (const flags::Flag& flag, master->flags) {
         Option<string> value = flag.stringify(master->flags);
         if (value.isSome()) {
-          writer->field(name, value.get());
+          writer->field(flag.effective_name().value, value.get());
         }
       }
     });

http://git-wip-us.apache.org/repos/asf/mesos/blob/af894485/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index fe48351..db60a24 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -384,10 +384,10 @@ Future<Response> Slave::Http::_flags(
 
   {
     JSON::Object flags;
-    foreachpair (const string& name, const flags::Flag& flag, slaveFlags) {
+    foreachvalue (const flags::Flag& flag, slaveFlags) {
       Option<string> value = flag.stringify(slaveFlags);
       if (value.isSome()) {
-        flags.values[name] = value.get();
+        flags.values[flag.effective_name().value] = value.get();
       }
     }
     object.values["flags"] = std::move(flags);
@@ -574,10 +574,10 @@ Future<Response> Slave::Http::state(
     });
 
     writer->field("flags", [this](JSON::ObjectWriter* writer) {
-      foreachpair (const string& name, const flags::Flag& flag, slave->flags) {
+      foreachvalue (const flags::Flag& flag, slave->flags) {
         Option<string> value = flag.stringify(slave->flags);
         if (value.isSome()) {
-          writer->field(name, value.get());
+          writer->field(flag.effective_name().value, value.get());
         }
       }
     });


[3/6] mesos git commit: Refactored Flags to store name in `Name` struct instead of string.

Posted by vi...@apache.org.
Refactored Flags to store name in `Name` struct instead of string.

This sets up the stage to add metadata to the name (e.g., deprecated).
This will be used to add deprecation support subsequently.

Review: https://reviews.apache.org/r/46620


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8b0eb8d3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8b0eb8d3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8b0eb8d3

Branch: refs/heads/master
Commit: 8b0eb8d3a045ba049fe8b9b40aa19e3602ad7142
Parents: 3bd9ccf
Author: Vinod Kone <vi...@gmail.com>
Authored: Mon Apr 18 17:25:15 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/stout/flags/flag.hpp  | 18 +++++++-
 3rdparty/stout/include/stout/flags/flags.hpp | 50 ++++++++++++-----------
 2 files changed, 43 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8b0eb8d3/3rdparty/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/flags/flag.hpp b/3rdparty/stout/include/stout/flags/flag.hpp
index 2502d9e..3a5930b 100644
--- a/3rdparty/stout/include/stout/flags/flag.hpp
+++ b/3rdparty/stout/include/stout/flags/flag.hpp
@@ -13,6 +13,7 @@
 #ifndef __STOUT_FLAGS_FLAG_HPP__
 #define __STOUT_FLAGS_FLAG_HPP__
 
+#include <ostream>
 #include <string>
 
 #include <stout/error.hpp>
@@ -25,9 +26,24 @@ namespace flags {
 // Forward declaration.
 class FlagsBase;
 
+
+struct Name
+{
+  Name() = default;
+
+  Name(const std::string& _value)
+    : value(_value) {}
+
+  Name(const char* _value)
+    : value(_value) {}
+
+  std::string value;
+};
+
+
 struct Flag
 {
-  std::string name;
+  Name name;
   std::string help;
   bool boolean;
   lambda::function<Try<Nothing>(FlagsBase*, const std::string&)> load;

http://git-wip-us.apache.org/repos/asf/mesos/blob/8b0eb8d3/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/flags/flags.hpp b/3rdparty/stout/include/stout/flags/flags.hpp
index c3cbcdb..5fd9357 100644
--- a/3rdparty/stout/include/stout/flags/flags.hpp
+++ b/3rdparty/stout/include/stout/flags/flags.hpp
@@ -143,7 +143,7 @@ public:
   template <typename T1, typename T2, typename F>
   void add(
       T1* t1,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       const T2& t2,
       F validate);
@@ -151,7 +151,7 @@ public:
   template <typename T1, typename T2>
   void add(
       T1* t1,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       const T2& t2)
   {
@@ -161,14 +161,14 @@ public:
   template <typename T, typename F>
   void add(
       Option<T>* option,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       F validate);
 
   template <typename T>
   void add(
       Option<T>* option,
-      const std::string& name,
+      const Name& name,
       const std::string& help)
   {
     add(option, name, help, [](const Option<T>&) { return None(); });
@@ -178,7 +178,7 @@ protected:
   template <typename Flags, typename T1, typename T2, typename F>
   void add(
       T1 Flags::*t1,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       const T2& t2,
       F validate);
@@ -186,7 +186,7 @@ protected:
   template <typename Flags, typename T1, typename T2>
   void add(
       T1 Flags::*t1,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       const T2& t2)
   {
@@ -196,14 +196,14 @@ protected:
   template <typename Flags, typename T, typename F>
   void add(
       Option<T> Flags::*option,
-      const std::string& name,
+      const Name& name,
       const std::string& help,
       F validate);
 
   template <typename Flags, typename T>
   void add(
       Option<T> Flags::*option,
-      const std::string& name,
+      const Name& name,
       const std::string& help)
   {
     add(option, name, help, [](const Option<T>&) { return None(); });
@@ -260,7 +260,7 @@ class Flags<> : public virtual FlagsBase {};
 template <typename T1, typename T2, typename F>
 void FlagsBase::add(
     T1* t1,
-    const std::string& name,
+    const Name& name,
     const std::string& help,
     const T2& t2,
     F validate)
@@ -317,7 +317,7 @@ void FlagsBase::add(
 template <typename T, typename F>
 void FlagsBase::add(
     Option<T>* option,
-    const std::string& name,
+    const Name& name,
     const std::string& help,
     F validate)
 {
@@ -364,7 +364,7 @@ void FlagsBase::add(
 template <typename Flags, typename T1, typename T2, typename F>
 void FlagsBase::add(
     T1 Flags::*t1,
-    const std::string& name,
+    const Name& name,
     const std::string& help,
     const T2& t2,
     F validate)
@@ -376,7 +376,8 @@ void FlagsBase::add(
 
   Flags* flags = dynamic_cast<Flags*>(this);
   if (flags == NULL) {
-    ABORT("Attempted to add flag '" + name + "' with incompatible type");
+    ABORT("Attempted to add flag '" + name.value +
+          "' with incompatible type");
   } else {
     flags->*t1 = t2; // Set the default.
   }
@@ -438,7 +439,7 @@ void FlagsBase::add(
 template <typename Flags, typename T, typename F>
 void FlagsBase::add(
     Option<T> Flags::*option,
-    const std::string& name,
+    const Name& name,
     const std::string& help,
     F validate)
 {
@@ -449,7 +450,8 @@ void FlagsBase::add(
 
   Flags* flags = dynamic_cast<Flags*>(this);
   if (flags == NULL) {
-    ABORT("Attempted to add flag '" + name + "' with incompatible type");
+    ABORT("Attempted to add flag '" + name.value +
+          "' with incompatible type");
   }
 
   Flag flag;
@@ -501,16 +503,16 @@ void FlagsBase::add(
 
 inline void FlagsBase::add(const Flag& flag)
 {
-  if (flags_.count(flag.name) > 0) {
+  if (flags_.count(flag.name.value) > 0) {
     EXIT(EXIT_FAILURE)
-      << "Attempted to add duplicate flag '" << flag.name << "'";
-  } else if (flag.name.find("no-") == 0) {
+      << "Attempted to add duplicate flag '" << flag.name.value << "'";
+  } else if (flag.name.value.find("no-") == 0) {
     EXIT(EXIT_FAILURE)
-      << "Attempted to add flag '" << flag.name
+      << "Attempted to add flag '" << flag.name.value
       << "' that starts with the reserved 'no-' prefix";
   }
 
-  flags_[flag.name] = flag;
+  flags_[flag.name.value] = flag;
 }
 
 
@@ -803,15 +805,15 @@ inline std::string FlagsBase::usage( const Option<std::string>& message) const
 
   foreachvalue (const flags::Flag& flag, *this) {
     if (flag.boolean) {
-      col1[flag.name] = "  --[no-]" + flag.name;
+      col1[flag.name.value] = "  --[no-]" + flag.name.value;
     } else {
-      col1[flag.name] = "  --" + flag.name + "=VALUE";
+      col1[flag.name.value] = "  --" + flag.name.value + "=VALUE";
     }
-    width = std::max(width, col1[flag.name].size());
+    width = std::max(width, col1[flag.name.value].size());
   }
 
   foreachvalue (const flags::Flag& flag, *this) {
-    std::string line = col1[flag.name];
+    std::string line = col1[flag.name.value];
 
     std::string pad(PAD + width - line.size(), ' ');
     line += pad;
@@ -843,7 +845,7 @@ inline std::ostream& operator<<(std::ostream& stream, const FlagsBase& flags)
   foreachvalue (const flags::Flag& flag, flags) {
     const Option<std::string> value = flag.stringify(flags);
     if (value.isSome()) {
-      _flags.push_back("--" + flag.name + "=\"" + value.get() + '"');
+      _flags.push_back("--" + flag.name.value + "=\"" + value.get() + '"');
     }
   }
 


[6/6] mesos git commit: Added alias support for flags.

Posted by vi...@apache.org.
Added alias support for flags.

This lets a user to load a flag either by the original name or an
alias.

Review: https://reviews.apache.org/r/46621


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/01d4cae2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/01d4cae2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/01d4cae2

Branch: refs/heads/master
Commit: 01d4cae238373a667cac82892ca58c5231e35a67
Parents: eba1699
Author: Vinod Kone <vi...@gmail.com>
Authored: Sun Apr 24 15:07:51 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/stout/flags/flag.hpp  |  20 ++
 3rdparty/stout/include/stout/flags/flags.hpp | 212 ++++++++++++++++++----
 2 files changed, 201 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/01d4cae2/3rdparty/stout/include/stout/flags/flag.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/flags/flag.hpp b/3rdparty/stout/include/stout/flags/flag.hpp
index 3a5930b..d869904 100644
--- a/3rdparty/stout/include/stout/flags/flag.hpp
+++ b/3rdparty/stout/include/stout/flags/flag.hpp
@@ -37,6 +37,11 @@ struct Name
   Name(const char* _value)
     : value(_value) {}
 
+  bool operator==(const Name& other) const
+  {
+    return value == other.value;
+  }
+
   std::string value;
 };
 
@@ -44,11 +49,26 @@ struct Name
 struct Flag
 {
   Name name;
+  Option<Name> alias;
+
+  // This is the name that the user uses to specifically load the flag (e.g, via
+  // command line `--foo=val`). This is optional because a flag might not be
+  // explicitly loaded by the user (e.g., flag with a default value). Note that
+  // this name should be one of `name` or `alias`.
+  Option<Name> loaded_name;
+
   std::string help;
   bool boolean;
   lambda::function<Try<Nothing>(FlagsBase*, const std::string&)> load;
   lambda::function<Option<std::string>(const FlagsBase&)> stringify;
   lambda::function<Option<Error>(const FlagsBase&)> validate;
+
+  // This is the name of the flag that the user loads. If the loading is
+  // implicit this defaults to the `name`.
+  const Name& effective_name() const
+  {
+    return loaded_name.isSome() ? loaded_name.get() : name;
+  }
 };
 
 } // namespace flags {

http://git-wip-us.apache.org/repos/asf/mesos/blob/01d4cae2/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/flags/flags.hpp b/3rdparty/stout/include/stout/flags/flags.hpp
index 21c9a02..02584e2 100644
--- a/3rdparty/stout/include/stout/flags/flags.hpp
+++ b/3rdparty/stout/include/stout/flags/flags.hpp
@@ -144,10 +144,22 @@ public:
   void add(
       T1* t1,
       const Name& name,
+      const Option<Name>& alias,
       const std::string& help,
       const T2& t2,
       F validate);
 
+  template <typename T1, typename T2, typename F>
+  void add(
+      T1* t1,
+      const Name& name,
+      const std::string& help,
+      const T2& t2,
+      F validate)
+  {
+    add(t1, name, None(), help, t2, validate);
+  }
+
   template <typename T1, typename T2>
   void add(
       T1* t1,
@@ -155,23 +167,55 @@ public:
       const std::string& help,
       const T2& t2)
   {
-    add(t1, name, help, t2, [](const T1&) { return None(); });
+    add(t1, name, None(), help, t2, [](const T1&) { return None(); });
+  }
+
+  template <typename T1, typename T2>
+  void add(
+      T1* t1,
+      const Name& name,
+      const Option<Name>& alias,
+      const std::string& help,
+      const T2& t2)
+  {
+    add(t1, name, alias, help, t2, [](const T1&) { return None(); });
   }
 
   template <typename T, typename F>
   void add(
       Option<T>* option,
       const Name& name,
+      const Option<Name>& alias,
       const std::string& help,
       F validate);
 
+  template <typename T, typename F>
+  void add(
+      Option<T>* option,
+      const Name& name,
+      const std::string& help,
+      F validate)
+  {
+    add(option, name, None(), help, validate);
+  }
+
   template <typename T>
   void add(
       Option<T>* option,
       const Name& name,
       const std::string& help)
   {
-    add(option, name, help, [](const Option<T>&) { return None(); });
+    add(option, name, None(), help, [](const Option<T>&) { return None(); });
+  }
+
+  template <typename T>
+  void add(
+      Option<T>* option,
+      const Name& name,
+      const Option<Name>& alias,
+      const std::string& help)
+  {
+    add(option, name, alias, help, [](const Option<T>&) { return None(); });
   }
 
 protected:
@@ -179,34 +223,78 @@ protected:
   void add(
       T1 Flags::*t1,
       const Name& name,
+      const Option<Name>& alias,
       const std::string& help,
       const T2& t2,
       F validate);
 
+  template <typename Flags, typename T1, typename T2, typename F>
+  void add(
+      T1 Flags::*t1,
+      const Name& name,
+      const std::string& help,
+      const T2& t2,
+      F validate)
+  {
+    add(t1, name, None(), help, t2, validate);
+  }
+
+  template <typename Flags, typename T1, typename T2>
+  void add(
+      T1 Flags::*t1,
+      const Name& name,
+      const std::string& help,
+      const T2& t2)
+  {
+    add(t1, name, None(), help, t2, [](const T1&) { return None(); });
+  }
+
   template <typename Flags, typename T1, typename T2>
   void add(
       T1 Flags::*t1,
       const Name& name,
+      const Option<Name>& alias,
       const std::string& help,
       const T2& t2)
   {
-    add(t1, name, help, t2, [](const T1&) { return None(); });
+    add(t1, name, alias, help, t2, [](const T1&) { return None(); });
   }
 
   template <typename Flags, typename T, typename F>
   void add(
       Option<T> Flags::*option,
       const Name& name,
+      const Option<Name>& alias,
       const std::string& help,
       F validate);
 
+  template <typename Flags, typename T, typename F>
+  void add(
+      Option<T> Flags::*option,
+      const Name& name,
+      const std::string& help,
+      F validate)
+  {
+    add(option, name, None(), help, validate);
+  }
+
   template <typename Flags, typename T>
   void add(
       Option<T> Flags::*option,
       const Name& name,
       const std::string& help)
   {
-    add(option, name, help, [](const Option<T>&) { return None(); });
+    add(option, name, None(), help, [](const Option<T>&) { return None(); });
+  }
+
+  template <typename Flags, typename T>
+  void add(
+      Option<T> Flags::*option,
+      const Name& name,
+      const Option<Name>& alias,
+      const std::string& help)
+  {
+    add(option, name, alias, help, [](const Option<T>&) { return None(); });
   }
 
   void add(const Flag& flag);
@@ -235,7 +323,11 @@ private:
   std::map<std::string, Option<std::string>> extract(
       const std::string& prefix);
 
+  // Maps flag's name to flag.
   std::map<std::string, Flag> flags_;
+
+  // Maps flag's alias to flag's name.
+  std::map<std::string, std::string> aliases;
 };
 
 
@@ -261,6 +353,7 @@ template <typename T1, typename T2, typename F>
 void FlagsBase::add(
     T1* t1,
     const Name& name,
+    const Option<Name>& alias,
     const std::string& help,
     const T2& t2,
     F validate)
@@ -274,6 +367,7 @@ void FlagsBase::add(
 
   Flag flag;
   flag.name = name;
+  flag.alias = alias;
   flag.help = help;
   flag.boolean = typeid(T1) == typeid(bool);
 
@@ -292,6 +386,7 @@ void FlagsBase::add(
     } else {
       return Error("Failed to load value '" + value + "': " + t.error());
     }
+
     return Nothing();
   };
 
@@ -318,6 +413,7 @@ template <typename T, typename F>
 void FlagsBase::add(
     Option<T>* option,
     const Name& name,
+    const Option<Name>& alias,
     const std::string& help,
     F validate)
 {
@@ -328,6 +424,7 @@ void FlagsBase::add(
 
   Flag flag;
   flag.name = name;
+  flag.alias = alias;
   flag.help = help;
   flag.boolean = typeid(T) == typeid(bool);
 
@@ -343,6 +440,7 @@ void FlagsBase::add(
     } else {
       return Error("Failed to load value '" + value + "': " + t.error());
     }
+
     return Nothing();
   };
 
@@ -365,6 +463,7 @@ template <typename Flags, typename T1, typename T2, typename F>
 void FlagsBase::add(
     T1 Flags::*t1,
     const Name& name,
+    const Option<Name>& alias,
     const std::string& help,
     const T2& t2,
     F validate)
@@ -384,6 +483,7 @@ void FlagsBase::add(
 
   Flag flag;
   flag.name = name;
+  flag.alias = alias;
   flag.help = help;
   flag.boolean = typeid(T1) == typeid(bool);
 
@@ -406,6 +506,7 @@ void FlagsBase::add(
         return Error("Failed to load value '" + value + "': " + t.error());
       }
     }
+
     return Nothing();
   };
 
@@ -440,6 +541,7 @@ template <typename Flags, typename T, typename F>
 void FlagsBase::add(
     Option<T> Flags::*option,
     const Name& name,
+    const Option<Name>& alias,
     const std::string& help,
     F validate)
 {
@@ -456,6 +558,7 @@ void FlagsBase::add(
 
   Flag flag;
   flag.name = name;
+  flag.alias = alias;
   flag.help = help;
   flag.boolean = typeid(T) == typeid(bool);
 
@@ -465,19 +568,20 @@ void FlagsBase::add(
 
   flag.load =
     [option](FlagsBase* base, const std::string& value) -> Try<Nothing> {
-      Flags* flags = dynamic_cast<Flags*>(base);
-      if (flags != NULL) {
-        // NOTE: 'fetch' "retrieves" the value if necessary and then
-        // invokes 'parse'. See 'fetch' for more details.
-        Try<T> t = fetch<T>(value);
-        if (t.isSome()) {
-          flags->*option = Some(t.get());
-        } else {
-          return Error("Failed to load value '" + value + "': " + t.error());
-        }
+    Flags* flags = dynamic_cast<Flags*>(base);
+    if (flags != NULL) {
+      // NOTE: 'fetch' "retrieves" the value if necessary and then
+      // invokes 'parse'. See 'fetch' for more details.
+      Try<T> t = fetch<T>(value);
+      if (t.isSome()) {
+        flags->*option = Some(t.get());
+      } else {
+        return Error("Failed to load value '" + value + "': " + t.error());
       }
-      return Nothing();
-    };
+    }
+
+    return Nothing();
+  };
 
   flag.stringify = [option](const FlagsBase& base) -> Option<std::string> {
     const Flags* flags = dynamic_cast<const Flags*>(&base);
@@ -503,16 +607,33 @@ void FlagsBase::add(
 
 inline void FlagsBase::add(const Flag& flag)
 {
-  if (flags_.count(flag.name.value) > 0) {
-    EXIT(EXIT_FAILURE)
-      << "Attempted to add duplicate flag '" << flag.name.value << "'";
-  } else if (flag.name.value.find("no-") == 0) {
-    EXIT(EXIT_FAILURE)
-      << "Attempted to add flag '" << flag.name.value
-      << "' that starts with the reserved 'no-' prefix";
+  // Check if the name and alias of the flag are valid.
+  std::vector<Name> names = {flag.name};
+  if (flag.alias.isSome()) {
+    if (flag.alias.get() == flag.name) {
+      EXIT(EXIT_FAILURE)
+        << "Attempted to add flag '" << flag.name.value << "' with an alias"
+        << " that is same as the flag name";
+    }
+
+    names.push_back(flag.alias.get());
+  }
+
+  foreach (const Name& name, names) {
+    if (flags_.count(name.value) > 0) {
+      EXIT(EXIT_FAILURE)
+        << "Attempted to add duplicate flag '" << name.value << "'";
+    } else if (name.value.find("no-") == 0) {
+      EXIT(EXIT_FAILURE)
+        << "Attempted to add flag '" << name.value
+        << "' that starts with the reserved 'no-' prefix";
+    }
   }
 
   flags_[flag.name.value] = flag;
+  if (flag.alias.isSome()) {
+    aliases[flag.alias.get().value] = flag.name.value;
+  }
 }
 
 
@@ -709,7 +830,11 @@ inline Try<Nothing> FlagsBase::load(
 
     bool is_negated = strings::startsWith(name, "no-");
     std::string flag_name = !is_negated ? name : name.substr(3);
-    auto iter = flags_.find(flag_name);
+
+    auto iter = aliases.count(flag_name)
+      ? flags_.find(aliases[flag_name])
+      : flags_.find(flag_name);
+
     if (iter == flags_.end()) {
       if (!unknowns) {
         return Error("Failed to load unknown flag '" + flag_name + "'" +
@@ -719,10 +844,16 @@ inline Try<Nothing> FlagsBase::load(
       }
     }
 
-    const Flag& flag = iter->second;
-    std::string value_;
+    Flag* flag = &(iter->second);
+
+    if (flag->loaded_name.isSome()) {
+      return Error("Flag is already loaded via name '" +
+                   flag->loaded_name->value + "'");
+    }
 
-    if (!flag.boolean) {  // Non-boolean flag.
+    // Validate the flag value.
+    std::string value_;
+    if (!flag->boolean) {  // Non-boolean flag.
       if (is_negated) { // Non-boolean flag cannot be loaded with "no-" prefix.
         return Error("Failed to load non-boolean flag '" + flag_name +
                      "' via '" + name + "'");
@@ -746,10 +877,19 @@ inline Try<Nothing> FlagsBase::load(
       }
     }
 
-    Try<Nothing> load = flag.load(this, value_);
+    Try<Nothing> load = flag->load(this, value_);
     if (load.isError()) {
       return Error("Failed to load flag '" + flag_name + "': " + load.error());
     }
+
+    // TODO(vinod): Move this logic inside `Flag::load()`.
+    // Set `loaded_name` to the Name corresponding to `flag_name`.
+    if (aliases.count(flag_name)) {
+      CHECK_SOME(flag->alias);
+      flag->loaded_name = flag->alias.get();
+    } else {
+      flag->loaded_name = flag->name;
+    }
   }
 
   // Validate the flags value.
@@ -806,13 +946,22 @@ inline std::string FlagsBase::usage( const Option<std::string>& message) const
 
   foreachvalue (const flags::Flag& flag, *this) {
     if (flag.boolean) {
-      col1[flag.name.value] = "  --[no-]" + flag.name.value;
+      col1[flag.name.value] += "  --[no-]" + flag.name.value;
+      if (flag.alias.isSome()) {
+        col1[flag.name.value] += ", --[no-]" + flag.alias->value;
+      }
     } else {
-      col1[flag.name.value] = "  --" + flag.name.value + "=VALUE";
+      // TODO(vinod): Rename "=VALUE" to "=<VALUE>".
+      col1[flag.name.value] += "  --" + flag.name.value + "=VALUE";
+      if (flag.alias.isSome()) {
+        col1[flag.name.value] += ", --" + flag.alias->value + "=VALUE";
+      }
     }
     width = std::max(width, col1[flag.name.value].size());
   }
 
+  // TODO(vinod): Print the help on the next line instead of on the same line as
+  // the names.
   foreachvalue (const flags::Flag& flag, *this) {
     std::string line = col1[flag.name.value];
 
@@ -846,7 +995,8 @@ inline std::ostream& operator<<(std::ostream& stream, const FlagsBase& flags)
   foreachvalue (const flags::Flag& flag, flags) {
     const Option<std::string> value = flag.stringify(flags);
     if (value.isSome()) {
-      _flags.push_back("--" + flag.name.value + "=\"" + value.get() + '"');
+      _flags.push_back("--" + flag.effective_name().value + "=\"" +
+                       value.get() + '"');
     }
   }
 


[5/6] mesos git commit: Updated libprocess to work with flag alias.

Posted by vi...@apache.org.
Updated libprocess to work with flag alias.

Review: https://reviews.apache.org/r/46623


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f0dd6ee9
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f0dd6ee9
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f0dd6ee9

Branch: refs/heads/master
Commit: f0dd6ee9cc2d26ae66da837c03cceec965906c9d
Parents: 6d8638b
Author: Vinod Kone <vi...@gmail.com>
Authored: Sun Apr 24 15:08:24 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/src/subprocess.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/f0dd6ee9/3rdparty/libprocess/src/subprocess.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/subprocess.cpp b/3rdparty/libprocess/src/subprocess.cpp
index 67d04b9..4407314 100644
--- a/3rdparty/libprocess/src/subprocess.cpp
+++ b/3rdparty/libprocess/src/subprocess.cpp
@@ -147,10 +147,10 @@ Try<Subprocess> subprocess(
   // Prepare the arguments. If the user specifies the 'flags', we will
   // stringify them and append them to the existing arguments.
   if (flags.isSome()) {
-    foreachpair (const string& name, const flags::Flag& flag, flags.get()) {
+    foreachvalue (const flags::Flag& flag, flags.get()) {
       Option<string> value = flag.stringify(flags.get());
       if (value.isSome()) {
-        argv.push_back("--" + name + "=" + value.get());
+        argv.push_back("--" + flag.effective_name().value + "=" + value.get());
       }
     }
   }


[4/6] mesos git commit: Refactored FlagsBase::load().

Posted by vi...@apache.org.
Refactored FlagsBase::load().

Made this function more readable. The error strings are still kept the
same as the previous code.

Review: https://reviews.apache.org/r/46814


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/eba1699f
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/eba1699f
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/eba1699f

Branch: refs/heads/master
Commit: eba1699f5cfcecf79a7d07b3727f3a34188e76ae
Parents: 8b0eb8d
Author: Vinod Kone <vi...@gmail.com>
Authored: Wed Apr 27 16:04:33 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 3rdparty/stout/include/stout/flags/flags.hpp | 77 ++++++++++++-----------
 1 file changed, 39 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/eba1699f/3rdparty/stout/include/stout/flags/flags.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/flags/flags.hpp b/3rdparty/stout/include/stout/flags/flags.hpp
index 5fd9357..21c9a02 100644
--- a/3rdparty/stout/include/stout/flags/flags.hpp
+++ b/3rdparty/stout/include/stout/flags/flags.hpp
@@ -707,47 +707,48 @@ inline Try<Nothing> FlagsBase::load(
     const std::string& name = iterator->first;
     const Option<std::string>& value = iterator->second;
 
-    if (flags_.count(name) > 0) {
-      if (value.isSome()) {                        // --name=value
-        if (flags_[name].boolean && value.get() == "") {
-          flags_[name].load(this, "true"); // Should never fail.
-        } else {
-          Try<Nothing> load = flags_[name].load(this, value.get());
-          if (load.isError()) {
-            return Error(
-                "Failed to load flag '" + name + "': " + load.error());
-          }
-        }
-      } else {                                     // --name
-        if (flags_[name].boolean) {
-          flags_[name].load(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 (value.isNone() || value.get() == "") {
-            flags_[name.substr(3)].load(this, "false"); // Should never fail.
-          } else {
-            return Error(
-                "Failed to load boolean flag '" + name.substr(3) +
-                "' via '" + name + "' with value '" + value.get() + "'");
-          }
-        } else {
-          return Error(
-              "Failed to load non-boolean flag '" + name.substr(3) +
-              "' via '" + name + "'");
-        }
+    bool is_negated = strings::startsWith(name, "no-");
+    std::string flag_name = !is_negated ? name : name.substr(3);
+    auto iter = flags_.find(flag_name);
+    if (iter == flags_.end()) {
+      if (!unknowns) {
+        return Error("Failed to load unknown flag '" + flag_name + "'" +
+                     (!is_negated ? "" : " via '" + name + "'"));
       } else {
+        continue;
+      }
+    }
+
+    const Flag& flag = iter->second;
+    std::string value_;
+
+    if (!flag.boolean) {  // Non-boolean flag.
+      if (is_negated) { // Non-boolean flag cannot be loaded with "no-" prefix.
+        return Error("Failed to load non-boolean flag '" + flag_name +
+                     "' via '" + name + "'");
+      }
+
+      if (value.isNone()) {
+        return Error("Failed to load non-boolean flag '" + flag_name +
+                     "': Missing value");
+      }
+
+      value_ = value.get();
+    } else {  // Boolean flag.
+      if (value.isNone() || value.get() == "") {
+        value_ = !is_negated ? "true" : "false";
+      } else if (!is_negated) {
+        value_ = value.get();
+      } else { // Boolean flag with "no-" prefix cannot have non-empty value.
         return Error(
-            "Failed to load unknown flag '" + name.substr(3) +
-            "' via '" + name + "'");
+            "Failed to load boolean flag '" + flag_name + "' via '" + name +
+            "' with value '" + value.get() + "'");
       }
-    } else if (!unknowns) {
-      return Error("Failed to load unknown flag '" + name + "'");
+    }
+
+    Try<Nothing> load = flag.load(this, value_);
+    if (load.isError()) {
+      return Error("Failed to load flag '" + flag_name + "': " + load.error());
     }
   }
 


[2/6] mesos git commit: Added tests for flag aliases.

Posted by vi...@apache.org.
Added tests for flag aliases.

Review: https://reviews.apache.org/r/46622


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/6d8638b0
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/6d8638b0
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/6d8638b0

Branch: refs/heads/master
Commit: 6d8638b071f0fb1426810dff99093859c54c576b
Parents: 01d4cae
Author: Vinod Kone <vi...@gmail.com>
Authored: Sun Apr 24 15:12:55 2016 -0700
Committer: Vinod Kone <vi...@gmail.com>
Committed: Thu May 12 12:14:54 2016 -0700

----------------------------------------------------------------------
 3rdparty/stout/tests/flags_tests.cpp | 147 ++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/6d8638b0/3rdparty/stout/tests/flags_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/tests/flags_tests.cpp b/3rdparty/stout/tests/flags_tests.cpp
index 66e16ab..a2880a0 100644
--- a/3rdparty/stout/tests/flags_tests.cpp
+++ b/3rdparty/stout/tests/flags_tests.cpp
@@ -156,6 +156,51 @@ TEST(FlagsTest, Add)
 }
 
 
+TEST(FlagsTest, Alias)
+{
+  TestFlags flags;
+
+  Option<string> name6;
+
+  flags.add(&name6,
+            "name6",
+            Some("alias6"),
+            "Also set name6");
+
+  bool name7;
+
+  flags.add(&name7,
+            "name7",
+            Some("alias7"),
+            "Also set name7",
+            true);
+
+  string name8;
+
+  flags.add(&name8,
+            "name8",
+            Some("alias8"),
+            "Also set name8",
+            "value8");
+
+  // Load with alias names.
+  const map<string, Option<string> > values = {
+     {"alias6", Some("foo")},
+     {"no-alias7", None()},
+     {"alias8", Some("bar")}
+  };
+
+  flags.load(values);
+
+  ASSERT_SOME(name6);
+  EXPECT_EQ("foo", name6.get());
+
+  EXPECT_FALSE(name7);
+
+  EXPECT_EQ("bar", name8);
+}
+
+
 TEST(FlagsTest, Flags)
 {
   TestFlags flags;
@@ -399,6 +444,42 @@ TEST(FlagsTest, Stringification)
 }
 
 
+TEST(FlagsTest, EffectiveName)
+{
+  TestFlags flags;
+
+  Option<string> name6;
+
+  flags.add(&name6,
+            "name6",
+            Some("alias6"),
+            "Also set name6");
+
+  string name7;
+
+  flags.add(&name7,
+            "name7",
+            Some("alias7"),
+            "Also set name7",
+            "value7");
+
+  // Only load "name6" flag explicitly.
+  const map<string, Option<string> > values = {
+    {"alias6", Some("value6")}
+  };
+
+  flags.load(values);
+
+  foreachvalue (const Flag& flag, flags) {
+    if (flag.name == "name6") {
+      EXPECT_EQ("alias6", flag.effective_name().value);
+    } else if (flag.name == "name7") {
+      EXPECT_EQ("name7", flag.effective_name().value);
+    }
+  }
+}
+
+
 TEST(FlagsTest, DuplicatesFromEnvironment)
 {
   TestFlags flags;
@@ -437,6 +518,29 @@ TEST(FlagsTest, DuplicatesFromCommandLine)
 }
 
 
+TEST(FlagsTest, AliasDuplicateFromCommandLine)
+{
+  TestFlags flags;
+
+  Option<string> name6;
+
+  flags.add(&name6,
+            "name6",
+            Some("alias6"),
+            "Also set name6");
+
+  const char* argv[] = {
+    "/path/to/program",
+    "--name6=billy joel",
+    "--alias6=ben folds"
+  };
+
+  // Loading the same flag with the name and alias should be an error.
+  Try<Nothing> load = flags.load("FLAGSTEST_", arraySize(argv), argv);
+  EXPECT_ERROR(load);
+}
+
+
 TEST(FlagsTest, Errors)
 {
   TestFlags flags;
@@ -557,6 +661,49 @@ TEST(FlagsTest, Validate)
 }
 
 
+TEST(FlagsTest, Usage)
+{
+  TestFlags flags;
+
+  Option<string> name6;
+
+  flags.add(&name6,
+            "z6",
+            Some("a6"),
+            "Also set name6");
+
+  bool name7;
+
+  flags.add(&name7,
+            "z7",
+            Some("a7"),
+            "Also set name7",
+            true);
+
+  string name8;
+
+  flags.add(&name8,
+            "z8",
+            Some("a8"),
+            "Also set name8",
+            "value8");
+
+  EXPECT_EQ(
+      "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"
+      "  --z6=VALUE, --a6=VALUE     Also set name6\n"
+      "  --[no-]z7, --[no-]a7       Also set name7 (default: true)\n"
+      "  --z8=VALUE, --a8=VALUE     Also set name8 (default: value8)\n",
+      flags.usage());
+}
+
+
 TEST(FlagsTest, UsageMessage)
 {
   TestFlags flags;