You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bookkeeper.apache.org by si...@apache.org on 2018/11/10 00:34:23 UTC

[bookkeeper] branch branch-4.8 updated: [TOOLS] improve bkctl help message

This is an automated email from the ASF dual-hosted git repository.

sijie pushed a commit to branch branch-4.8
in repository https://gitbox.apache.org/repos/asf/bookkeeper.git


The following commit(s) were added to refs/heads/branch-4.8 by this push:
     new 5006eeb  [TOOLS] improve bkctl help message
5006eeb is described below

commit 5006eeb4a4bee97066595623ad3b3329f06754b9
Author: Sijie Guo <gu...@gmail.com>
AuthorDate: Fri Nov 9 16:32:37 2018 -0800

    [TOOLS] improve bkctl help message
    
    Descriptions of the changes in this PR:
    
    *Motivation*
    
    Currently `bin/bktcl help` will output all command groups all together.
    It is a bit hard to tell what command groups to use, especially some
    commands are used for table service.
    
    *Changes*
    
    Introduce `category` in the cli spec to define which category that a
    command group belongs to. So when it prints out the help message, it
    can use that information to categorize the command groups together
    to provide better user experience.
    
    *Results*
    
    ```
    $ bin/bkctl help
    bkctl interacts and operates Apache BookKeeper clusters
    
    Usage:  bkctl [flags] [command group] [commands]
    
    Infrastructure commands :
    
        bookie          Commands on operating a single bookie
        bookies         Commands on operating a cluster of bookies
        cluster         Commands on administrating bookkeeper clusters
    
    Ledger service commands :
    
        ledger          Commands on interacting with ledgers
    
    Table service commands :
    
        namespace       Commands on operating namespaces
        table           Commands on interacting with tables
        tables          Commands on operating tables
    
    Other commands :
    
        help            Display help information about it
    ```
    
    Reviewers: Enrico Olivelli <eo...@gmail.com>, Matteo Merli <mm...@apache.org>
    
    This closes #1793 from sijie/add_groups
    
    (cherry picked from commit 843c0cc2fe73fc59d743e41dde81178608a29b8e)
    Signed-off-by: Sijie Guo <si...@apache.org>
---
 .../tools/cli/commands/BookieCommandGroup.java     |  3 ++
 .../tools/cli/commands/BookiesCommandGroup.java    |  3 ++
 .../tools/cli/commands/LedgerCommandGroup.java     |  3 ++
 .../tools/common/BKCommandCategories.java          | 36 +++++++++++++++
 .../bookkeeper/tools/framework/CliCommand.java     |  5 ++
 .../apache/bookkeeper/tools/framework/CliSpec.java | 17 ++++++-
 .../apache/bookkeeper/tools/framework/Command.java |  9 ++++
 .../bookkeeper/tools/framework/CommandUtils.java   | 53 +++++++++++++++++++---
 .../bookkeeper/stream/cli/ClusterCommandGroup.java |  3 ++
 .../stream/cli/NamespaceCommandGroup.java          |  3 ++
 .../stream/cli/TableAdminCommandGroup.java         |  3 ++
 .../bookkeeper/stream/cli/TableCommandGroup.java   |  3 ++
 12 files changed, 134 insertions(+), 7 deletions(-)

diff --git a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookieCommandGroup.java b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookieCommandGroup.java
index ec4fbc5..2a5cf1f 100644
--- a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookieCommandGroup.java
+++ b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookieCommandGroup.java
@@ -18,6 +18,8 @@
  */
 package org.apache.bookkeeper.tools.cli.commands;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_INFRA_SERVICE;
+
 import org.apache.bookkeeper.tools.cli.BKCtl;
 import org.apache.bookkeeper.tools.cli.commands.bookie.LastMarkCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
@@ -36,6 +38,7 @@ public class BookieCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent(BKCtl.NAME)
+        .withCategory(CATEGORY_INFRA_SERVICE)
         .addCommand(new LastMarkCommand())
         .build();
 
diff --git a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookiesCommandGroup.java b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookiesCommandGroup.java
index 1fff60f..6b86de7 100644
--- a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookiesCommandGroup.java
+++ b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/BookiesCommandGroup.java
@@ -18,6 +18,8 @@
  */
 package org.apache.bookkeeper.tools.cli.commands;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_INFRA_SERVICE;
+
 import org.apache.bookkeeper.tools.cli.BKCtl;
 import org.apache.bookkeeper.tools.cli.commands.bookies.ListBookiesCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
@@ -36,6 +38,7 @@ public class BookiesCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent(BKCtl.NAME)
+        .withCategory(CATEGORY_INFRA_SERVICE)
         .addCommand(new ListBookiesCommand())
         .build();
 
diff --git a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/LedgerCommandGroup.java b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/LedgerCommandGroup.java
index 4236c49..c528656 100644
--- a/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/LedgerCommandGroup.java
+++ b/tools/all/src/main/java/org/apache/bookkeeper/tools/cli/commands/LedgerCommandGroup.java
@@ -18,6 +18,8 @@
  */
 package org.apache.bookkeeper.tools.cli.commands;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_LEDGER_SERVICE;
+
 import org.apache.bookkeeper.tools.cli.BKCtl;
 import org.apache.bookkeeper.tools.cli.commands.client.SimpleTestCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
@@ -36,6 +38,7 @@ public class LedgerCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent(BKCtl.NAME)
+        .withCategory(CATEGORY_LEDGER_SERVICE)
         .addCommand(new SimpleTestCommand())
         .build();
 
diff --git a/tools/framework/src/main/java/org/apache/bookkeeper/tools/common/BKCommandCategories.java b/tools/framework/src/main/java/org/apache/bookkeeper/tools/common/BKCommandCategories.java
new file mode 100644
index 0000000..35aa3bd
--- /dev/null
+++ b/tools/framework/src/main/java/org/apache/bookkeeper/tools/common/BKCommandCategories.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.bookkeeper.tools.common;
+
+/**
+ * Classes to keep a list of command categories.
+ */
+public final class BKCommandCategories {
+
+    // commands that operate cluster and nodes
+    public static final String CATEGORY_INFRA_SERVICE = "Infrastructure commands";
+
+    // commands that operate ledger service
+    public static final String CATEGORY_LEDGER_SERVICE = "Ledger service commands";
+
+    // commands that operate table service
+    public static final String CATEGORY_TABLE_SERVICE = "Table service commands";
+
+}
diff --git a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliCommand.java b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliCommand.java
index ab7b955..cf68acf 100644
--- a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliCommand.java
+++ b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliCommand.java
@@ -42,6 +42,11 @@ public class CliCommand<GlobalFlagsT extends CliFlags, CommandFlagsT extends Cli
     }
 
     @Override
+    public String category() {
+        return spec.category();
+    }
+
+    @Override
     public String name() {
         return name;
     }
diff --git a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliSpec.java b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliSpec.java
index bbae3f5..c708bf1 100644
--- a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliSpec.java
+++ b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CliSpec.java
@@ -67,10 +67,12 @@ public class CliSpec<CliFlagsT extends CliFlags> {
         private PrintStream console = System.out;
         private boolean isCommandGroup = false;
         private String argumentsUsage = "";
+        private String category = "";
 
         private Builder() {}
 
         private Builder(CliSpec<CliFlagsT> spec) {
+            this.category = spec.category;
             this.name = spec.name;
             this.parent = spec.parent;
             this.usage = spec.usage;
@@ -85,6 +87,11 @@ public class CliSpec<CliFlagsT extends CliFlags> {
             this.isCommandGroup = spec.isCommandGroup;
         }
 
+        public Builder<CliFlagsT> withCategory(String category) {
+            this.category = category;
+            return this;
+        }
+
         public Builder<CliFlagsT> withName(String name) {
             this.name = name;
             return this;
@@ -142,6 +149,7 @@ public class CliSpec<CliFlagsT extends CliFlags> {
 
         public CliSpec<CliFlagsT> build() {
             return new CliSpec<>(
+                category,
                 name,
                 parent,
                 usage,
@@ -158,6 +166,7 @@ public class CliSpec<CliFlagsT extends CliFlags> {
 
     }
 
+    private final String category;
     private final String name;
     private final String parent;
     private final String usage;
@@ -171,7 +180,8 @@ public class CliSpec<CliFlagsT extends CliFlags> {
     // whether the cli spec is for a command group.
     private final boolean isCommandGroup;
 
-    private CliSpec(String name,
+    private CliSpec(String category,
+                    String name,
                     String parent,
                     String usage,
                     String argumentsUsage,
@@ -182,6 +192,7 @@ public class CliSpec<CliFlagsT extends CliFlags> {
                     Function<CliFlagsT, Boolean> runFunc,
                     PrintStream console,
                     boolean isCommandGroup) {
+        this.category = category;
         this.name = name;
         this.parent = parent;
         this.usage = usage;
@@ -195,6 +206,10 @@ public class CliSpec<CliFlagsT extends CliFlags> {
         this.isCommandGroup = isCommandGroup;
     }
 
+    public String category() {
+        return category;
+    }
+
     public String name() {
         return name;
     }
diff --git a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/Command.java b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/Command.java
index 186b29f..1681432 100644
--- a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/Command.java
+++ b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/Command.java
@@ -33,6 +33,15 @@ public interface Command<GlobalFlagsT extends CliFlags> {
     }
 
     /**
+     * Return category of this command belongs to.
+     *
+     * @return category name
+     */
+    default String category() {
+        return "";
+    }
+
+    /**
      * Return command name.
      *
      * @return command name.
diff --git a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CommandUtils.java b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CommandUtils.java
index 77c6b48..4698be9 100644
--- a/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CommandUtils.java
+++ b/tools/framework/src/main/java/org/apache/bookkeeper/tools/framework/CommandUtils.java
@@ -27,7 +27,9 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.stream.IntStream;
+import org.apache.commons.lang.StringUtils;
 
 /**
  * Utils to process a commander.
@@ -164,9 +166,6 @@ public class CommandUtils {
             return;
         }
 
-        printer.println("Commands:");
-        printer.println();
-
         int longestCommandName = commands
             .keySet()
             .stream()
@@ -174,17 +173,44 @@ public class CommandUtils {
             .max()
             .orElse(0);
 
+        // group the commands by category
+        Map<String, Map<String, Command>> categorizedCommands = new TreeMap<>();
         for (Map.Entry<String, Command> commandEntry : commands.entrySet()) {
             if ("help".equals(commandEntry.getKey())) {
-                // don't print help message along with available other commands
+                // don't add help message along with other commands
                 continue;
             }
-            printCommand(printer, commandEntry.getKey(), commandEntry.getValue(), longestCommandName);
+            String category = commandEntry.getValue().category();
+            Map<String, Command> subCommands = categorizedCommands.get(category);
+            if (null == subCommands) {
+                subCommands = new TreeMap<>();
+                categorizedCommands.put(category, subCommands);
+            }
+            subCommands.put(commandEntry.getKey(), commandEntry.getValue());
+        }
+
+        // there is only one category, print all of them under `Commands`.
+        if (categorizedCommands.size() <= 1) {
+            printer.println("Commands:");
+            printer.println();
+        }
+
+        for (Map.Entry<String, Map<String, Command>> categoryEntry : categorizedCommands.entrySet()) {
+            String category = categoryEntry.getKey();
+            printCategoryHeader(printer, category);
+            Map<String, Command> subCommands = categoryEntry.getValue();
+            for (Map.Entry<String, Command> commandEntry : subCommands.entrySet()) {
+                printCommand(printer, commandEntry.getKey(), commandEntry.getValue(), longestCommandName);
+            }
+            printer.println();
         }
 
         Command helpCmd = commands.get("help");
         if (null != helpCmd) {
-            printer.println();
+            if (categorizedCommands.size() > 1) {
+                // if commands has been categorized, put help
+                printCategoryHeader(printer, "Other commands");
+            }
             printCommand(printer, "help", helpCmd, longestCommandName);
         }
 
@@ -215,4 +241,19 @@ public class CommandUtils {
             command.description());
     }
 
+    private static void printCategoryHeader(PrintStream printer,
+                                            String category) {
+        if (StringUtils.isEmpty(category)) {
+            return;
+        }
+
+        printIndent(printer, 0);
+        printDescription(
+            printer,
+            0,
+            0,
+            category + " :");
+        printer.println();
+    }
+
 }
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/ClusterCommandGroup.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/ClusterCommandGroup.java
index 375bc66..303275f 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/ClusterCommandGroup.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/ClusterCommandGroup.java
@@ -17,6 +17,8 @@
  */
 package org.apache.bookkeeper.stream.cli;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_INFRA_SERVICE;
+
 import org.apache.bookkeeper.stream.cli.commands.cluster.InitClusterCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
 import org.apache.bookkeeper.tools.framework.CliCommandGroup;
@@ -34,6 +36,7 @@ public class ClusterCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent("bkctl")
+        .withCategory(CATEGORY_INFRA_SERVICE)
         .addCommand(new InitClusterCommand())
         .build();
 
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/NamespaceCommandGroup.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/NamespaceCommandGroup.java
index be9e062..de8d32b 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/NamespaceCommandGroup.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/NamespaceCommandGroup.java
@@ -17,6 +17,8 @@
  */
 package org.apache.bookkeeper.stream.cli;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_TABLE_SERVICE;
+
 import org.apache.bookkeeper.stream.cli.commands.namespace.CreateNamespaceCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
 import org.apache.bookkeeper.tools.framework.CliCommandGroup;
@@ -34,6 +36,7 @@ public class NamespaceCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent("bkctl")
+        .withCategory(CATEGORY_TABLE_SERVICE)
         .addCommand(new CreateNamespaceCommand())
         .build();
 
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableAdminCommandGroup.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableAdminCommandGroup.java
index 60b9892..9b2f3e4 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableAdminCommandGroup.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableAdminCommandGroup.java
@@ -17,6 +17,8 @@
  */
 package org.apache.bookkeeper.stream.cli;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_TABLE_SERVICE;
+
 import org.apache.bookkeeper.stream.cli.commands.table.CreateTableCommand;
 import org.apache.bookkeeper.tools.common.BKFlags;
 import org.apache.bookkeeper.tools.framework.CliCommandGroup;
@@ -34,6 +36,7 @@ public class TableAdminCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent("bkctl")
+        .withCategory(CATEGORY_TABLE_SERVICE)
         .addCommand(new CreateTableCommand())
         .build();
 
diff --git a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableCommandGroup.java b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableCommandGroup.java
index 09d3be6..eec98a9 100644
--- a/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableCommandGroup.java
+++ b/tools/stream/src/main/java/org/apache/bookkeeper/stream/cli/TableCommandGroup.java
@@ -17,6 +17,8 @@
  */
 package org.apache.bookkeeper.stream.cli;
 
+import static org.apache.bookkeeper.tools.common.BKCommandCategories.CATEGORY_TABLE_SERVICE;
+
 import org.apache.bookkeeper.stream.cli.commands.table.GetCommand;
 import org.apache.bookkeeper.stream.cli.commands.table.IncrementCommand;
 import org.apache.bookkeeper.stream.cli.commands.table.PutCommand;
@@ -36,6 +38,7 @@ public class TableCommandGroup extends CliCommandGroup<BKFlags> {
         .withName(NAME)
         .withDescription(DESC)
         .withParent("bkctl")
+        .withCategory(CATEGORY_TABLE_SERVICE)
         .addCommand(new PutCommand())
         .addCommand(new GetCommand())
         .addCommand(new IncrementCommand())