aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java248
1 files changed, 248 insertions, 0 deletions
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
new file mode 100644
index 0000000000..5267e71acc
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/HelpCommand.java
@@ -0,0 +1,248 @@
+// Copyright 2014 Google Inc. All rights reserved.
+//
+// Licensed 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 com.google.devtools.build.lib.runtime.commands;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.docgen.BlazeRuleHelpPrinter;
+import com.google.devtools.build.lib.analysis.BlazeVersionInfo;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.events.Event;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.runtime.BlazeCommand;
+import com.google.devtools.build.lib.runtime.BlazeCommandUtils;
+import com.google.devtools.build.lib.runtime.BlazeModule;
+import com.google.devtools.build.lib.runtime.BlazeRuntime;
+import com.google.devtools.build.lib.runtime.Command;
+import com.google.devtools.build.lib.util.ExitCode;
+import com.google.devtools.build.lib.util.io.OutErr;
+import com.google.devtools.common.options.Converters;
+import com.google.devtools.common.options.Option;
+import com.google.devtools.common.options.OptionsBase;
+import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.OptionsProvider;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The 'blaze help' command, which prints all available commands as well as
+ * specific help pages.
+ */
+@Command(name = "help",
+ options = { HelpCommand.Options.class },
+ allowResidue = true,
+ mustRunInWorkspace = false,
+ shortDescription = "Prints help for commands, or the index.",
+ help = "resource:help.txt")
+public final class HelpCommand implements BlazeCommand {
+ public static class Options extends OptionsBase {
+
+ @Option(name = "help_verbosity",
+ category = "help",
+ defaultValue = "medium",
+ converter = Converters.HelpVerbosityConverter.class,
+ help = "Select the verbosity of the help command.")
+ public OptionsParser.HelpVerbosity helpVerbosity;
+
+ @Option(name = "long",
+ abbrev = 'l',
+ defaultValue = "null",
+ category = "help",
+ expansion = {"--help_verbosity", "long"},
+ help = "Show full description of each option, instead of just its name.")
+ public Void showLongFormOptions;
+
+ @Option(name = "short",
+ defaultValue = "null",
+ category = "help",
+ expansion = {"--help_verbosity", "short"},
+ help = "Show only the names of the options, not their types or meanings.")
+ public Void showShortFormOptions;
+ }
+
+ /**
+ * Returns a map that maps option categories to descriptive help strings for categories that
+ * are not part of the Bazel core.
+ */
+ private ImmutableMap<String, String> getOptionCategories(BlazeRuntime runtime) {
+ ImmutableMap.Builder<String, String> optionCategoriesBuilder = ImmutableMap.builder();
+ optionCategoriesBuilder
+ .put("checking",
+ "Checking options, which control Blaze's error checking and/or warnings")
+ .put("coverage",
+ "Options that affect how Blaze generates code coverage information")
+ .put("experimental",
+ "Experimental options, which control experimental (and potentially risky) features")
+ .put("flags",
+ "Flags options, for passing options to other tools")
+ .put("help",
+ "Help options")
+ .put("host jvm startup",
+ "Options that affect the startup of the Blaze server's JVM")
+ .put("misc",
+ "Miscellaneous options")
+ .put("package loading",
+ "Options that specify how to locate packages")
+ .put("query",
+ "Options affecting the 'blaze query' dependency query command")
+ .put("run",
+ "Options specific to 'blaze run'")
+ .put("semantics",
+ "Semantics options, which affect the build commands and/or output file contents")
+ .put("server startup",
+ "Startup options, which affect the startup of the Blaze server")
+ .put("strategy",
+ "Strategy options, which affect how Blaze will execute the build")
+ .put("testing",
+ "Options that affect how Blaze runs tests")
+ .put("verbosity",
+ "Verbosity options, which control what Blaze prints")
+ .put("version",
+ "Version options, for selecting which version of other tools will be used")
+ .put("what",
+ "Output selection options, for determining what to build/test");
+ for (BlazeModule module : runtime.getBlazeModules()) {
+ optionCategoriesBuilder.putAll(module.getOptionCategories());
+ }
+ return optionCategoriesBuilder.build();
+ }
+
+ @Override
+ public void editOptions(BlazeRuntime runtime, OptionsParser optionsParser) {}
+
+ @Override
+ public ExitCode exec(BlazeRuntime runtime, OptionsProvider options) {
+ OutErr outErr = runtime.getReporter().getOutErr();
+ Options helpOptions = options.getOptions(Options.class);
+ if (options.getResidue().isEmpty()) {
+ emitBlazeVersionInfo(outErr);
+ emitGenericHelp(runtime, outErr);
+ return ExitCode.SUCCESS;
+ }
+ if (options.getResidue().size() != 1) {
+ runtime.getReporter().handle(Event.error("You must specify exactly one command"));
+ return ExitCode.COMMAND_LINE_ERROR;
+ }
+ String helpSubject = options.getResidue().get(0);
+ if (helpSubject.equals("startup_options")) {
+ emitBlazeVersionInfo(outErr);
+ emitStartupOptions(outErr, helpOptions.helpVerbosity, runtime, getOptionCategories(runtime));
+ return ExitCode.SUCCESS;
+ } else if (helpSubject.equals("target-syntax")) {
+ emitBlazeVersionInfo(outErr);
+ emitTargetSyntaxHelp(outErr, getOptionCategories(runtime));
+ return ExitCode.SUCCESS;
+ } else if (helpSubject.equals("info-keys")) {
+ emitInfoKeysHelp(runtime, outErr);
+ return ExitCode.SUCCESS;
+ }
+
+ BlazeCommand command = runtime.getCommandMap().get(helpSubject);
+ if (command == null) {
+ ConfiguredRuleClassProvider provider = runtime.getRuleClassProvider();
+ RuleClass ruleClass = provider.getRuleClassMap().get(helpSubject);
+ if (ruleClass != null && ruleClass.isDocumented()) {
+ // There is a rule with a corresponding name
+ outErr.printOut(BlazeRuleHelpPrinter.getRuleDoc(helpSubject, provider));
+ return ExitCode.SUCCESS;
+ } else {
+ runtime.getReporter().handle(Event.error(
+ null, "'" + helpSubject + "' is neither a command nor a build rule"));
+ return ExitCode.COMMAND_LINE_ERROR;
+ }
+ }
+ emitBlazeVersionInfo(outErr);
+ outErr.printOut(BlazeCommandUtils.getUsage(
+ command.getClass(),
+ getOptionCategories(runtime),
+ helpOptions.helpVerbosity,
+ runtime.getBlazeModules(),
+ runtime.getRuleClassProvider()));
+ return ExitCode.SUCCESS;
+ }
+
+ private void emitBlazeVersionInfo(OutErr outErr) {
+ String releaseInfo = BlazeVersionInfo.instance().getReleaseName();
+ String line = "[Blaze " + releaseInfo + "]";
+ outErr.printOut(String.format("%80s\n", line));
+ }
+
+ @SuppressWarnings("unchecked") // varargs generic array creation
+ private void emitStartupOptions(OutErr outErr, OptionsParser.HelpVerbosity helpVerbosity,
+ BlazeRuntime runtime, ImmutableMap<String, String> optionCategories) {
+ outErr.printOut(
+ BlazeCommandUtils.expandHelpTopic("startup_options",
+ "resource:startup_options.txt",
+ getClass(),
+ BlazeCommandUtils.getStartupOptions(runtime.getBlazeModules()),
+ optionCategories,
+ helpVerbosity));
+ }
+
+ private void emitTargetSyntaxHelp(OutErr outErr, ImmutableMap<String, String> optionCategories) {
+ outErr.printOut(BlazeCommandUtils.expandHelpTopic("target-syntax",
+ "resource:target-syntax.txt",
+ getClass(),
+ ImmutableList.<Class<? extends OptionsBase>>of(),
+ optionCategories,
+ OptionsParser.HelpVerbosity.MEDIUM));
+ }
+
+ private void emitInfoKeysHelp(BlazeRuntime runtime, OutErr outErr) {
+ for (InfoKey key : InfoKey.values()) {
+ outErr.printOut(String.format("%-23s %s\n", key.getName(), key.getDescription()));
+ }
+
+ for (BlazeModule.InfoItem item : InfoCommand.getInfoItemMap(runtime,
+ OptionsParser.newOptionsParser(
+ ImmutableList.<Class<? extends OptionsBase>>of())).values()) {
+ outErr.printOut(String.format("%-23s %s\n", item.getName(), item.getDescription()));
+ }
+ }
+
+ private void emitGenericHelp(BlazeRuntime runtime, OutErr outErr) {
+ outErr.printOut("Usage: blaze <command> <options> ...\n\n");
+
+ outErr.printOut("Available commands:\n");
+
+ Map<String, BlazeCommand> commandsByName = runtime.getCommandMap();
+ List<String> namesInOrder = new ArrayList<>(commandsByName.keySet());
+ Collections.sort(namesInOrder);
+
+ for (String name : namesInOrder) {
+ BlazeCommand command = commandsByName.get(name);
+ Command annotation = command.getClass().getAnnotation(Command.class);
+ if (annotation.hidden()) {
+ continue;
+ }
+
+ String shortDescription = annotation.shortDescription();
+ outErr.printOut(String.format(" %-19s %s\n", name, shortDescription));
+ }
+
+ outErr.printOut("\n");
+ outErr.printOut("Getting more help:\n");
+ outErr.printOut(" blaze help <command>\n");
+ outErr.printOut(" Prints help and options for <command>.\n");
+ outErr.printOut(" blaze help startup_options\n");
+ outErr.printOut(" Options for the JVM hosting Blaze.\n");
+ outErr.printOut(" blaze help target-syntax\n");
+ outErr.printOut(" Explains the syntax for specifying targets.\n");
+ outErr.printOut(" blaze help info-keys\n");
+ outErr.printOut(" Displays a list of keys used by the info command.\n");
+ }
+}