From ee2eaf8ae00c09a6eaa3de857f27d607a3e6511c Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 4 Dec 2018 22:17:58 +0100
Subject: [PATCH] git subrepo pull packages/CLI11

subrepo:
  subdir:   "packages/CLI11"
  merged:   "bd4dc9118"
upstream:
  origin:   "git@github.com:CLIUtils/CLI11.git"
  branch:   "master"
  commit:   "bd4dc9118"
git-subrepo:
  version:  "0.4.0"
  origin:   "git@github.com:ingydotnet/git-subrepo.git"
  commit:   "5d6aba9"
---
 packages/CLI11/.gitrepo                 |  4 ++--
 packages/CLI11/CHANGELOG.md             |  7 +++++-
 packages/CLI11/README.md                |  3 +++
 packages/CLI11/include/CLI/App.hpp      | 10 +++++++--
 packages/CLI11/include/CLI/Option.hpp   | 30 ++++++++++++++++++++++---
 packages/CLI11/include/CLI/Version.hpp  |  4 ++--
 packages/CLI11/tests/AppTest.cpp        | 28 +++++++++++++++++++++++
 packages/CLI11/tests/SubcommandTest.cpp | 14 ++++++++++++
 8 files changed, 90 insertions(+), 10 deletions(-)

diff --git a/packages/CLI11/.gitrepo b/packages/CLI11/.gitrepo
index 529dab075..7c4acccc9 100644
--- a/packages/CLI11/.gitrepo
+++ b/packages/CLI11/.gitrepo
@@ -6,7 +6,7 @@
 [subrepo]
 	remote = git@github.com:CLIUtils/CLI11.git
 	branch = master
-	commit = b683f4ed96b2da6c4992e63f49482b8c9cd00968
-	parent = b9ec061afdb0aefa3489d9beaecf99cd608f3d15
+	commit = bd4dc911847d0cde7a6b41dfa626a85aab213baf
+	parent = 5c82607003abda391c299d089e4624664a41de7a
 	cmdver = 0.4.0
 	method = merge
diff --git a/packages/CLI11/CHANGELOG.md b/packages/CLI11/CHANGELOG.md
index ba405ea01..0b8ade8ea 100644
--- a/packages/CLI11/CHANGELOG.md
+++ b/packages/CLI11/CHANGELOG.md
@@ -1,6 +1,6 @@
 ## Version 1.6.2: Help-all
 
-This version fixes some formatting bugs with help-all. It also adds fixes for several warnings, including an experimental optional error on Clang 7.
+This version fixes some formatting bugs with help-all. It also adds fixes for several warnings, including an experimental optional error on Clang 7. Several smaller fixes.
 
 * Fixed help-all formatting [#163]
     * Printing help-all on nested command now fixed (App)
@@ -11,11 +11,16 @@ This version fixes some formatting bugs with help-all. It also adds fixes for se
 * Fixed CMake install as subproject with `CLI11_INSTALL` flag. [#156]
 * Fixed warning about local variable hiding class member with MSVC [#157]
 * Fixed compile error with default settings on Clang 7 and libc++ [#158]
+* Fixed special case of `--help` on subcommands (general fix planned for 1.7) [#168]
+* Removing an option with links  [#179]
 
 [#156]: https://github.com/CLIUtils/CLI11/issues/156
 [#157]: https://github.com/CLIUtils/CLI11/issues/157
 [#158]: https://github.com/CLIUtils/CLI11/issues/158
 [#163]: https://github.com/CLIUtils/CLI11/pull/163
+[#168]: https://github.com/CLIUtils/CLI11/issues/168
+[#179]: https://github.com/CLIUtils/CLI11/pull/179
+
 
 ## Version 1.6.1: Platform fixes
 
diff --git a/packages/CLI11/README.md b/packages/CLI11/README.md
index 319769ff0..c03b5e904 100644
--- a/packages/CLI11/README.md
+++ b/packages/CLI11/README.md
@@ -458,6 +458,9 @@ Significant features and/or improvements to the code were contributed by:
 -   [Nathan Hourt](https://github.com/nathanhourt)
 -   [Sean Fisk](https://github.com/seanfisk)
 -   [Stéphane Del Pino](https://github.com/delpinux)
+-   [Mak Kolybabi](https://github.com/mogigoma)
+-   [Paweł Bylica](https://github.com/chfast)
+
 
 ## License
 
diff --git a/packages/CLI11/include/CLI/App.hpp b/packages/CLI11/include/CLI/App.hpp
index 99bc97742..4b207e133 100644
--- a/packages/CLI11/include/CLI/App.hpp
+++ b/packages/CLI11/include/CLI/App.hpp
@@ -781,6 +781,12 @@ class App {
 
     /// Removes an option from the App. Takes an option pointer. Returns true if found and removed.
     bool remove_option(Option *opt) {
+        // Make sure no links exist
+        for(Option_p &op : options_) {
+            op->remove_needs(opt);
+            op->remove_excludes(opt);
+        }
+
         auto iterator =
             std::find_if(std::begin(options_), std::end(options_), [opt](const Option_p &v) { return v.get() == opt; });
         if(iterator != std::end(options_)) {
@@ -1356,7 +1362,7 @@ class App {
                     throw RequiredError(opt->get_name());
             }
             // Requires
-            for(const Option *opt_req : opt->requires_)
+            for(const Option *opt_req : opt->needs_)
                 if(opt->count() > 0 && opt_req->count() == 0)
                     throw RequiresError(opt->get_name(), opt_req->get_name());
             // Excludes
@@ -1383,7 +1389,7 @@ class App {
         }
     }
 
-    /// Return True if a help flag detected (checks all parents)
+    /// Return True if a help flag detected (checks all parents) (only run if help called before subcommand)
     bool _any_help_flag() const {
         bool result = false;
         const Option *help_ptr = get_help_ptr();
diff --git a/packages/CLI11/include/CLI/Option.hpp b/packages/CLI11/include/CLI/Option.hpp
index a5f046a22..c37e39f7b 100644
--- a/packages/CLI11/include/CLI/Option.hpp
+++ b/packages/CLI11/include/CLI/Option.hpp
@@ -200,7 +200,7 @@ class Option : public OptionBase<Option> {
     std::vector<std::function<std::string(std::string &)>> validators_;
 
     /// A list of options that are required with this option
-    std::set<Option *> requires_;
+    std::set<Option *> needs_;
 
     /// A list of options that are excluded with this option
     std::set<Option *> excludes_;
@@ -322,7 +322,7 @@ class Option : public OptionBase<Option> {
 
     /// Sets required options
     Option *needs(Option *opt) {
-        auto tup = requires_.insert(opt);
+        auto tup = needs_.insert(opt);
         if(!tup.second)
             throw OptionAlreadyAdded::Requires(get_name(), opt->get_name());
         return this;
@@ -342,6 +342,18 @@ class Option : public OptionBase<Option> {
         return needs(opt1, args...);
     }
 
+    /// Remove needs link from an option. Returns true if the option really was in the needs list.
+    bool remove_needs(Option *opt) {
+        auto iterator = std::find(std::begin(needs_), std::end(needs_), opt);
+
+        if(iterator != std::end(needs_)) {
+            needs_.erase(iterator);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /// Sets excluded options
     Option *excludes(Option *opt) {
         excludes_.insert(opt);
@@ -369,6 +381,18 @@ class Option : public OptionBase<Option> {
         return excludes(opt1, args...);
     }
 
+    /// Remove needs link from an option. Returns true if the option really was in the needs list.
+    bool remove_excludes(Option *opt) {
+        auto iterator = std::find(std::begin(excludes_), std::end(excludes_), opt);
+
+        if(iterator != std::end(excludes_)) {
+            excludes_.erase(iterator);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     /// Sets environment variable to read if no option given
     Option *envname(std::string name) {
         envname_ = name;
@@ -418,7 +442,7 @@ class Option : public OptionBase<Option> {
     std::string get_envname() const { return envname_; }
 
     /// The set of options needed
-    std::set<Option *> get_needs() const { return requires_; }
+    std::set<Option *> get_needs() const { return needs_; }
 
     /// The set of options excluded
     std::set<Option *> get_excludes() const { return excludes_; }
diff --git a/packages/CLI11/include/CLI/Version.hpp b/packages/CLI11/include/CLI/Version.hpp
index 80eaf2a0d..b2ae8641d 100644
--- a/packages/CLI11/include/CLI/Version.hpp
+++ b/packages/CLI11/include/CLI/Version.hpp
@@ -7,7 +7,7 @@
 
 #define CLI11_VERSION_MAJOR 1
 #define CLI11_VERSION_MINOR 6
-#define CLI11_VERSION_PATCH 1
-#define CLI11_VERSION "1.6.1"
+#define CLI11_VERSION_PATCH 2
+#define CLI11_VERSION "1.6.2"
 
 // [CLI11:verbatim]
diff --git a/packages/CLI11/tests/AppTest.cpp b/packages/CLI11/tests/AppTest.cpp
index 1c6a969f7..b1bd218e5 100644
--- a/packages/CLI11/tests/AppTest.cpp
+++ b/packages/CLI11/tests/AppTest.cpp
@@ -816,6 +816,34 @@ TEST_F(TApp, RemoveOption) {
     EXPECT_THROW(run(), CLI::ExtrasError);
 }
 
+TEST_F(TApp, RemoveNeedsLinks) {
+    auto one = app.add_flag("--one");
+    auto two = app.add_flag("--two");
+
+    two->needs(one);
+    one->needs(two);
+
+    EXPECT_TRUE(app.remove_option(one));
+
+    args = {"--two"};
+
+    run();
+}
+
+TEST_F(TApp, RemoveExcludesLinks) {
+    auto one = app.add_flag("--one");
+    auto two = app.add_flag("--two");
+
+    two->excludes(one);
+    one->excludes(two);
+
+    EXPECT_TRUE(app.remove_option(one));
+
+    args = {"--two"};
+
+    run(); // Mostly hoping it does not crash
+}
+
 TEST_F(TApp, FileNotExists) {
     std::string myfile{"TestNonFileNotUsed.txt"};
     ASSERT_NO_THROW(CLI::NonexistentPath(myfile));
diff --git a/packages/CLI11/tests/SubcommandTest.cpp b/packages/CLI11/tests/SubcommandTest.cpp
index bc5d8ca00..e752f4f2c 100644
--- a/packages/CLI11/tests/SubcommandTest.cpp
+++ b/packages/CLI11/tests/SubcommandTest.cpp
@@ -438,6 +438,8 @@ struct SubcommandProgram : public TApp {
     int count;
 
     SubcommandProgram() {
+        app.set_help_all_flag("--help-all");
+
         start = app.add_subcommand("start", "Start prog");
         stop = app.add_subcommand("stop", "Stop prog");
 
@@ -541,6 +543,18 @@ TEST_F(SubcommandProgram, HelpOrder) {
     EXPECT_THROW(run(), CLI::CallForHelp);
 }
 
+TEST_F(SubcommandProgram, HelpAllOrder) {
+
+    args = {"--help-all"};
+    EXPECT_THROW(run(), CLI::CallForAllHelp);
+
+    args = {"start", "--help-all"};
+    EXPECT_THROW(run(), CLI::CallForAllHelp);
+
+    args = {"--help-all", "start"};
+    EXPECT_THROW(run(), CLI::CallForAllHelp);
+}
+
 TEST_F(SubcommandProgram, Callbacks) {
 
     start->callback([]() { throw CLI::Success(); });
-- 
GitLab