From 9bd280ba663557a44c0177327cf668ff813a397d Mon Sep 17 00:00:00 2001 From: fwe Date: Fri, 1 Sep 2017 16:40:49 +0200 Subject: Refactor HelpCommand by applying the visitor pattern to iterate over Bazel options in emitCompletionHelp(). This change is in preparation for unknown commit which introduces "bazel help flags" - a new command whose functionality is similar to the existing "bazel help completion". Both commands have to iterate over Bazel options, which means that applying the visitor patterns helps to avoid duplicate iteration code. I also tested this change by running "bazel help completion" with and without this change. PiperOrigin-RevId: 167273874 --- .../build/lib/runtime/commands/HelpCommand.java | 72 +++++++++++++++++----- 1 file changed, 57 insertions(+), 15 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java') diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java index d0a13f9692..87cc44c09f 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java @@ -13,7 +13,9 @@ // limitations under the License. package com.google.devtools.build.lib.runtime.commands; +import com.google.common.base.CaseFormat; import com.google.common.base.Joiner; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; @@ -49,6 +51,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; /** The 'blaze help' command, which prints all available commands as well as specific help pages. */ @Command( @@ -235,37 +238,59 @@ public final class HelpCommand implements BlazeCommand { } private void emitCompletionHelp(BlazeRuntime runtime, OutErr outErr) { - // First startup_options - Iterable blazeModules = runtime.getBlazeModules(); - ConfiguredRuleClassProvider ruleClassProvider = runtime.getRuleClassProvider(); Map commandsByName = getSortedCommands(runtime); outErr.printOutLn("BAZEL_COMMAND_LIST=\"" + SPACE_JOINER.join(commandsByName.keySet()) + "\""); outErr.printOutLn("BAZEL_INFO_KEYS=\""); for (String name : InfoCommand.getHardwiredInfoItemNames(runtime.getProductName())) { - outErr.printOutLn(name); + outErr.printOutLn(name); } outErr.printOutLn("\""); - outErr.printOutLn("BAZEL_STARTUP_OPTIONS=\""); + Consumer startupOptionVisitor = + parser -> { + outErr.printOutLn("BAZEL_STARTUP_OPTIONS=\""); + outErr.printOut(parser.getOptionsCompletion()); + outErr.printOutLn("\""); + }; + CommandOptionVisitor commandOptionVisitor = + (commandName, commandAnnotation, parser) -> { + String varName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE, commandName); + if (!Strings.isNullOrEmpty(commandAnnotation.completion())) { + outErr.printOutLn( + "BAZEL_COMMAND_" + + varName + + "_ARGUMENT=\"" + + commandAnnotation.completion() + + "\""); + } + outErr.printOutLn("BAZEL_COMMAND_" + varName + "_FLAGS=\""); + outErr.printOut(parser.getOptionsCompletion()); + outErr.printOutLn("\""); + }; + + visitAllOptions(runtime, startupOptionVisitor, commandOptionVisitor); + } + + private void visitAllOptions( + BlazeRuntime runtime, + Consumer startupOptionVisitor, + CommandOptionVisitor commandOptionVisitor) { + // First startup_options + Iterable blazeModules = runtime.getBlazeModules(); + ConfiguredRuleClassProvider ruleClassProvider = runtime.getRuleClassProvider(); + Map commandsByName = getSortedCommands(runtime); + Iterable> options = BlazeCommandUtils.getStartupOptions(blazeModules); - outErr.printOut(OptionsParser.newOptionsParser(options).getOptionsCompletion()); - outErr.printOutLn("\""); + startupOptionVisitor.accept(OptionsParser.newOptionsParser(options)); for (Map.Entry e : commandsByName.entrySet()) { BlazeCommand command = e.getValue(); - String varName = e.getKey().toUpperCase(Locale.US).replace('-', '_'); Command annotation = command.getClass().getAnnotation(Command.class); - if (!annotation.completion().isEmpty()) { - outErr.printOutLn("BAZEL_COMMAND_" + varName + "_ARGUMENT=\"" - + annotation.completion() + "\""); - } options = BlazeCommandUtils.getOptions(command.getClass(), blazeModules, ruleClassProvider); - outErr.printOutLn("BAZEL_COMMAND_" + varName + "_FLAGS=\""); - outErr.printOut(OptionsParser.newOptionsParser(options).getOptionsCompletion()); - outErr.printOutLn("\""); + commandOptionVisitor.visit(e.getKey(), annotation, OptionsParser.newOptionsParser(options)); } } @@ -420,4 +445,21 @@ public final class HelpCommand implements BlazeCommand { return s.substring(0, 1).toUpperCase(Locale.US) + s.substring(1); } } + + /** A visitor for Blaze commands and their respective command line options. */ + @FunctionalInterface + interface CommandOptionVisitor { + + /** + * Visits a Blaze command by providing access to its name, its meta-data and its command line + * options (via an {@link OptionsParser} instance). + * + * @param commandName name of the command, e.g. "help". + * @param commandAnnotation {@link Command} that contains addition information about the + * command. + * @param parser an {@link OptionsParser} instance that provides access to all options supported + * by the command. + */ + void visit(String commandName, Command commandAnnotation, OptionsParser parser); + } } -- cgit v1.2.3