diff options
author | 2016-05-03 15:44:16 +0000 | |
---|---|---|
committer | 2016-05-03 21:31:21 +0000 | |
commit | f07b76e5fc9a07cbc0b2b45d5bfe8eb4b1ec2e03 (patch) | |
tree | 737d4e6348234360403a65bc3dacedf1d5b432ab /src/main/java/com | |
parent | 4b71d2e1bc3afa0ce0a5b6e68dac3c559654d975 (diff) |
Redesign InfoItem to use classes instead of the InfoKey enum. This way the InfoItems can
now take parameters.
--
MOS_MIGRATED_REVID=121379097
Diffstat (limited to 'src/main/java/com')
5 files changed, 683 insertions, 383 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java index a75e20722a..0037fd0d2f 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java @@ -14,7 +14,6 @@ package com.google.devtools.build.lib.runtime; import com.google.common.base.Predicate; -import com.google.common.base.Supplier; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.actions.ActionContextConsumer; @@ -24,7 +23,6 @@ import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.BlazeVersionInfo; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.WorkspaceStatusAction; -import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.exec.OutputService; import com.google.devtools.build.lib.packages.NoSuchThingException; @@ -35,6 +33,7 @@ import com.google.devtools.build.lib.query2.QueryEnvironmentFactory; import com.google.devtools.build.lib.query2.engine.QueryEnvironment.QueryFunction; import com.google.devtools.build.lib.query2.output.OutputFormatter; import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory; +import com.google.devtools.build.lib.runtime.commands.InfoItem; import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy; import com.google.devtools.build.lib.skyframe.DiffAwareness; import com.google.devtools.build.lib.skyframe.PrecomputedValue.Injected; @@ -254,34 +253,6 @@ public abstract class BlazeModule { } /** - * A item that is returned by "blaze info". - */ - public interface InfoItem { - /** - * The name of the info key. - */ - String getName(); - - /** - * The help description of the info key. - */ - String getDescription(); - - /** - * Whether the key is printed when "blaze info" is invoked without arguments. - * - * <p>This is usually true for info keys that take multiple lines, thus, cannot really be - * included in the output of argumentless "blaze info". - */ - boolean isHidden(); - - /** - * Returns the value of the info key. The return value is directly printed to stdout. - */ - byte[] get(Supplier<BuildConfiguration> configurationSupplier) throws AbruptExitException; - } - - /** * Returns the additional information this module provides to "blaze info". * * <p>This method will be called at the beginning of each "blaze info" command (after 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 a514596719..08ef73eae8 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 @@ -159,7 +159,7 @@ public final class HelpCommand implements BlazeCommand { emitTargetSyntaxHelp(outErr, getOptionCategories(runtime)); return ExitCode.SUCCESS; } else if (helpSubject.equals("info-keys")) { - emitInfoKeysHelp(runtime, outErr); + emitInfoKeysHelp(env, outErr); return ExitCode.SUCCESS; } else if (helpSubject.equals("completion")) { emitCompletionHelp(runtime, outErr); @@ -218,8 +218,8 @@ public final class HelpCommand implements BlazeCommand { outErr.printOutLn("BAZEL_COMMAND_LIST=\"" + SPACE_JOINER.join(commands) + "\""); outErr.printOutLn("BAZEL_INFO_KEYS=\""); - for (InfoKey key : InfoKey.values()) { - outErr.printOutLn(key.getName()); + for (String name : InfoCommand.getHardwiredInfoItemNames(Constants.PRODUCT_NAME)) { + outErr.printOutLn(name); } outErr.printOutLn("\""); @@ -253,8 +253,8 @@ public final class HelpCommand implements BlazeCommand { OptionsParser.HelpVerbosity.MEDIUM)); } - private void emitInfoKeysHelp(BlazeRuntime runtime, OutErr outErr) { - for (BlazeModule.InfoItem item : InfoCommand.getInfoItemMap(runtime, + private void emitInfoKeysHelp(CommandEnvironment env, OutErr outErr) { + for (InfoItem item : InfoCommand.getInfoItemMap(env, OptionsParser.newOptionsParser( ImmutableList.<Class<? extends OptionsBase>>of())).values()) { outErr.printOut(String.format("%-23s %s\n", item.getName(), item.getDescription())); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java index fd5adcbc96..a2badf3c31 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java @@ -13,51 +13,31 @@ // limitations under the License. package com.google.devtools.build.lib.runtime.commands; -import com.google.common.base.Joiner; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; import com.google.common.base.Supplier; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.analysis.BlazeVersionInfo; +import com.google.common.base.Verify; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.Constants; import com.google.devtools.build.lib.analysis.NoBuildEvent; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; import com.google.devtools.build.lib.events.Event; -import com.google.devtools.build.lib.packages.Attribute; -import com.google.devtools.build.lib.packages.BuildType; -import com.google.devtools.build.lib.packages.ProtoUtils; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.packages.RuleClassProvider; import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; -import com.google.devtools.build.lib.query2.proto.proto2api.Build.AllowedRuleClassInfo; -import com.google.devtools.build.lib.query2.proto.proto2api.Build.AttributeDefinition; -import com.google.devtools.build.lib.query2.proto.proto2api.Build.BuildLanguage; -import com.google.devtools.build.lib.query2.proto.proto2api.Build.RuleDefinition; import com.google.devtools.build.lib.runtime.BlazeCommand; -import com.google.devtools.build.lib.runtime.BlazeCommandDispatcher; 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.runtime.CommandEnvironment; import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.ExitCode; -import com.google.devtools.build.lib.util.OsUtils; -import com.google.devtools.build.lib.util.StringUtilities; import com.google.devtools.build.lib.util.io.OutErr; 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.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintWriter; -import java.lang.management.GarbageCollectorMXBean; -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryMXBean; -import java.lang.management.MemoryUsage; import java.nio.charset.StandardCharsets; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -115,68 +95,6 @@ public class InfoCommand implements BlazeCommand { } } - private static class HardwiredInfoItem implements BlazeModule.InfoItem { - private final InfoKey key; - private final BlazeRuntime runtime; - private final OptionsProvider commandOptions; - - private HardwiredInfoItem(InfoKey key, BlazeRuntime runtime, OptionsProvider commandOptions) { - this.key = key; - this.runtime = runtime; - this.commandOptions = commandOptions; - } - - @Override - public String getName() { - return key.getName(); - } - - @Override - public String getDescription() { - return key.getDescription(); - } - - @Override - public boolean isHidden() { - return key.isHidden(); - } - - @Override - public byte[] get(Supplier<BuildConfiguration> configurationSupplier) { - return print(getInfoItem(runtime, key, configurationSupplier, commandOptions)); - } - } - - private static class MakeInfoItem implements BlazeModule.InfoItem { - private final String name; - private final String value; - - private MakeInfoItem(String name, String value) { - this.name = name; - this.value = value; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDescription() { - return "Make environment variable '" + name + "'"; - } - - @Override - public boolean isHidden() { - return false; - } - - @Override - public byte[] get(Supplier<BuildConfiguration> configurationSupplier) { - return print(value); - } - } - @Override public void editOptions(CommandEnvironment env, OptionsParser optionsParser) { } @@ -220,13 +138,13 @@ public class InfoCommand implements BlazeCommand { } }; - Map<String, BlazeModule.InfoItem> items = getInfoItemMap(runtime, optionsProvider); + Map<String, InfoItem> items = getInfoItemMap(env, optionsProvider); try { if (infoOptions.showMakeEnvironment) { Map<String, String> makeEnv = configurationSupplier.get().getMakeEnvironment(); for (Map.Entry<String, String> entry : makeEnv.entrySet()) { - BlazeModule.InfoItem item = new MakeInfoItem(entry.getKey(), entry.getValue()); + InfoItem item = new InfoItem.MakeInfoItem(entry.getKey(), entry.getValue()); items.put(item.getName(), item); } } @@ -242,7 +160,7 @@ public class InfoCommand implements BlazeCommand { if (key != null) { // print just the value for the specified key: byte[] value; if (items.containsKey(key)) { - value = items.get(key).get(configurationSupplier); + value = items.get(key).get(configurationSupplier, env); } else { env.getReporter().handle(Event.error("unknown key: '" + key + "'")); return ExitCode.COMMAND_LINE_ERROR; @@ -256,13 +174,13 @@ public class InfoCommand implements BlazeCommand { } } else { // print them all configurationSupplier.get(); // We'll need this later anyway - for (BlazeModule.InfoItem infoItem : items.values()) { + for (InfoItem infoItem : items.values()) { if (infoItem.isHidden()) { continue; } outErr.getOutputStream().write( (infoItem.getName() + ": ").getBytes(StandardCharsets.UTF_8)); - outErr.getOutputStream().write(infoItem.get(configurationSupplier)); + outErr.getOutputStream().write(infoItem.get(configurationSupplier, env)); } } } catch (AbruptExitException e) { @@ -275,177 +193,56 @@ public class InfoCommand implements BlazeCommand { return ExitCode.SUCCESS; } - /** - * Compute and return the info for the given key. Only keys that are not hidden are supported - * here. - */ - private static Object getInfoItem(BlazeRuntime runtime, InfoKey key, - Supplier<BuildConfiguration> configurationSupplier, OptionsProvider options) { - switch (key) { - // directories - case WORKSPACE : return runtime.getWorkspace().getWorkspace(); - case INSTALL_BASE : return runtime.getWorkspace().getInstallBase(); - case OUTPUT_BASE : return runtime.getWorkspace().getOutputBase(); - case EXECUTION_ROOT : return runtime.getWorkspace().getExecRoot(); - case OUTPUT_PATH : return runtime.getWorkspace().getOutputPath(); - // These are the only (non-hidden) info items that require a configuration, because the - // corresponding paths contain the short name. Maybe we should recommend using the symlinks - // or make them hidden by default? - case BLAZE_BIN : return configurationSupplier.get().getBinDirectory().getPath(); - case BLAZE_GENFILES : return configurationSupplier.get().getGenfilesDirectory().getPath(); - case BLAZE_TESTLOGS : return configurationSupplier.get().getTestLogsDirectory().getPath(); - - // logs - case COMMAND_LOG : return BlazeCommandDispatcher.getCommandLogPath( - runtime.getWorkspace().getOutputBase()); - case MESSAGE_LOG : - // NB: Duplicated in EventLogModule - return runtime.getWorkspace().getOutputBase().getRelative("message.log"); - - // misc - case RELEASE : return BlazeVersionInfo.instance().getReleaseName(); - case SERVER_PID : return OsUtils.getpid(); - case PACKAGE_PATH : return getPackagePath(options); - - // memory statistics - case GC_COUNT : - case GC_TIME : - // The documentation is not very clear on what it means to have more than - // one GC MXBean, so we just sum them up. - int gcCount = 0; - int gcTime = 0; - for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { - gcCount += gcBean.getCollectionCount(); - gcTime += gcBean.getCollectionTime(); - } - if (key == InfoKey.GC_COUNT) { - return gcCount + ""; - } else { - return gcTime + "ms"; - } - - case MAX_HEAP_SIZE : - return StringUtilities.prettyPrintBytes(getMemoryUsage().getMax()); - case USED_HEAP_SIZE : - case COMMITTED_HEAP_SIZE : - return StringUtilities.prettyPrintBytes(key == InfoKey.USED_HEAP_SIZE ? - getMemoryUsage().getUsed() : getMemoryUsage().getCommitted()); - - case USED_HEAP_SIZE_AFTER_GC : - // Note that this info value is not printed by default, but only when explicitly requested. - System.gc(); - return StringUtilities.prettyPrintBytes(getMemoryUsage().getUsed()); - - case DEFAULTS_PACKAGE: - return runtime.getDefaultsPackageContent(); - - case BUILD_LANGUAGE: - return getBuildLanguageDefinition(runtime.getRuleClassProvider()); - - case DEFAULT_PACKAGE_PATH: - return Joiner.on(":").join(options.getOptions(PackageCacheOptions.class).packagePath); - - default: - throw new IllegalArgumentException("missing implementation for " + key); - } - } - - private static MemoryUsage getMemoryUsage() { - MemoryMXBean memBean = ManagementFactory.getMemoryMXBean(); - return memBean.getHeapMemoryUsage(); - } - - /** - * Get the package_path variable for the given set of options. - */ - private static String getPackagePath(OptionsProvider options) { - PackageCacheOptions packageCacheOptions = - options.getOptions(PackageCacheOptions.class); - return Joiner.on(":").join(packageCacheOptions.packagePath); - } - - private static AllowedRuleClassInfo getAllowedRuleClasses( - Collection<RuleClass> ruleClasses, Attribute attr) { - AllowedRuleClassInfo.Builder info = AllowedRuleClassInfo.newBuilder(); - info.setPolicy(AllowedRuleClassInfo.AllowedRuleClasses.ANY); - - if (attr.isStrictLabelCheckingEnabled() - && attr.getAllowedRuleClassesPredicate() != Predicates.<RuleClass>alwaysTrue()) { - info.setPolicy(AllowedRuleClassInfo.AllowedRuleClasses.SPECIFIED); - Predicate<RuleClass> filter = attr.getAllowedRuleClassesPredicate(); - for (RuleClass otherClass : Iterables.filter(ruleClasses, filter)) { - if (otherClass.isDocumented()) { - info.addAllowedRuleClass(otherClass.getName()); - } - } - } - - return info.build(); - } - - /** - * Returns a byte array containing a proto-buffer describing the build language. - */ - private static byte[] getBuildLanguageDefinition(RuleClassProvider provider) { - BuildLanguage.Builder resultPb = BuildLanguage.newBuilder(); - Collection<RuleClass> ruleClasses = provider.getRuleClassMap().values(); - for (RuleClass ruleClass : ruleClasses) { - if (!ruleClass.isDocumented()) { - continue; - } - - RuleDefinition.Builder rulePb = RuleDefinition.newBuilder(); - rulePb.setName(ruleClass.getName()); - for (Attribute attr : ruleClass.getAttributes()) { - if (!attr.isDocumented()) { - continue; - } - - AttributeDefinition.Builder attrPb = AttributeDefinition.newBuilder(); - attrPb.setName(attr.getName()); - // The protocol compiler, in its infinite wisdom, generates the field as one of the - // integer type and the getTypeEnum() method is missing. WTF? - attrPb.setType(ProtoUtils.getDiscriminatorFromType(attr.getType())); - attrPb.setMandatory(attr.isMandatory()); - - if (BuildType.isLabelType(attr.getType())) { - attrPb.setAllowedRuleClasses(getAllowedRuleClasses(ruleClasses, attr)); - } - - rulePb.addAttribute(attrPb); - } - - resultPb.addRule(rulePb); + static Map<String, InfoItem> getHardwiredInfoItemMap(OptionsProvider commandOptions, + String productName) { + List<InfoItem> hardwiredInfoItems = ImmutableList.<InfoItem>of( + new InfoItem.WorkspaceInfoItem(), + new InfoItem.InstallBaseInfoItem(), + new InfoItem.OutputBaseInfoItem(), + new InfoItem.ExecutionRootInfoItem(), + new InfoItem.OutputPathInfoItem(), + new InfoItem.BlazeBinInfoItem(productName), + new InfoItem.BlazeGenfilesInfoItem(productName), + new InfoItem.BlazeTestlogsInfoItem(productName), + new InfoItem.CommandLogInfoItem(), + new InfoItem.MessageLogInfoItem(), + new InfoItem.ReleaseInfoItem(productName), + new InfoItem.ServerPidInfoItem(productName), + new InfoItem.PackagePathInfoItem(commandOptions), + new InfoItem.UsedHeapSizeInfoItem(), + new InfoItem.UsedHeapSizeAfterGcInfoItem(), + new InfoItem.CommitedHeapSizeInfoItem(), + new InfoItem.MaxHeapSizeInfoItem(), + new InfoItem.GcTimeInfoItem(), + new InfoItem.GcCountInfoItem(), + new InfoItem.DefaultsPackageInfoItem(), + new InfoItem.BuildLanguageInfoItem(), + new InfoItem.DefaultPackagePathInfoItem(commandOptions)); + ImmutableMap.Builder<String, InfoItem> result = new ImmutableMap.Builder<>(); + for (InfoItem item : hardwiredInfoItems) { + result.put(item.getName(), item); } - - return resultPb.build().toByteArray(); + return result.build(); } - private static byte[] print(Object value) { - if (value instanceof byte[]) { - return (byte[]) value; + public static List<String> getHardwiredInfoItemNames(String productName) { + ImmutableList.Builder<String> result = new ImmutableList.Builder<>(); + for (String name : InfoCommand.getHardwiredInfoItemMap(null, productName).keySet()) { + result.add(name); } - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - PrintWriter writer = new PrintWriter(outputStream); - writer.print(value + "\n"); - writer.flush(); - return outputStream.toByteArray(); + return result.build(); } - static Map<String, BlazeModule.InfoItem> getInfoItemMap( - BlazeRuntime runtime, OptionsProvider commandOptions) { - Map<String, BlazeModule.InfoItem> result = new TreeMap<>(); // order by key - for (BlazeModule module : runtime.getBlazeModules()) { - for (BlazeModule.InfoItem item : module.getInfoItems()) { + static Map<String, InfoItem> getInfoItemMap( + CommandEnvironment env, OptionsProvider commandOptions) { + Map<String, InfoItem> result = new TreeMap<>(); // order by key + for (BlazeModule module : env.getRuntime().getBlazeModules()) { + for (InfoItem item : module.getInfoItems()) { + Verify.verify(!result.containsKey(item.getName())); result.put(item.getName(), item); } } - - for (InfoKey key : InfoKey.values()) { - BlazeModule.InfoItem item = new HardwiredInfoItem(key, runtime, commandOptions); - result.put(item.getName(), item); - } - + result.putAll(getHardwiredInfoItemMap(commandOptions, Constants.PRODUCT_NAME)); return result; } } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java new file mode 100644 index 0000000000..923f29ce0c --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java @@ -0,0 +1,627 @@ +// Copyright 2014 The Bazel Authors. 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 static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Joiner; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; +import com.google.devtools.build.lib.Constants; +import com.google.devtools.build.lib.analysis.BlazeVersionInfo; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.packages.ProtoUtils; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClassProvider; +import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; +import com.google.devtools.build.lib.query2.proto.proto2api.Build.AllowedRuleClassInfo; +import com.google.devtools.build.lib.query2.proto.proto2api.Build.AttributeDefinition; +import com.google.devtools.build.lib.query2.proto.proto2api.Build.BuildLanguage; +import com.google.devtools.build.lib.query2.proto.proto2api.Build.RuleDefinition; +import com.google.devtools.build.lib.runtime.BlazeCommandDispatcher; +import com.google.devtools.build.lib.runtime.CommandEnvironment; +import com.google.devtools.build.lib.util.AbruptExitException; +import com.google.devtools.build.lib.util.OsUtils; +import com.google.devtools.build.lib.util.StringUtilities; +import com.google.devtools.common.options.OptionsProvider; +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; +import java.lang.management.MemoryUsage; +import java.util.Collection; + +/** + * An item that is returned by <code>blaze info</code>. + */ +public abstract class InfoItem { + protected final String name; + protected final String description; + protected final boolean hidden; + + protected InfoItem(String name, + String description, + boolean hidden) { + this.name = name; + this.description = description; + this.hidden = hidden; + } + + protected InfoItem(String name, + String description) { + this(name, description, false); + } + + /** + * The name of the info key. + */ + public String getName() { + return name; + } + + /** + * The help description of the info key. + */ + public String getDescription() { + return description; + } + + /** + * Whether the key is printed when "blaze info" is invoked without arguments. + * + * <p>This is usually true for info keys that take multiple lines, thus, cannot really be + * included in the output of argumentless "blaze info". + */ + public boolean isHidden() { + return hidden; + } + + /** + * Returns the value of the info key. The return value is directly printed to stdout. + * @param env TODO(lpino): + */ + public abstract byte[] get(Supplier<BuildConfiguration> configurationSupplier, + CommandEnvironment env) throws AbruptExitException; + + private static byte[] print(Object value) { + if (value instanceof byte[]) { + return (byte[]) value; + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintWriter writer = new PrintWriter(outputStream); + writer.print(value + "\n"); + writer.flush(); + return outputStream.toByteArray(); + } + + /** + * Info item for the workspace directory. + */ + public static final class WorkspaceInfoItem extends InfoItem { + public WorkspaceInfoItem() { + super("workspace", + "The working directory of the server."); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getWorkspace().getWorkspace()); + } + } + + /** + * Info item for the install_base directory. + */ + public static final class InstallBaseInfoItem extends InfoItem { + public InstallBaseInfoItem() { + super("install_base", + "The installation base directory.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getWorkspace().getInstallBase()); + } + } + + /** + * Info item for the output_base directory. + */ + public static final class OutputBaseInfoItem extends InfoItem { + public OutputBaseInfoItem() { + super("output_base", + "A directory for shared " + Constants.PRODUCT_NAME + + " state as well as tool and strategy specific subdirectories.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getWorkspace().getOutputBase()); + } + } + + /** + * Info item for the execution_root directory. + */ + public static final class ExecutionRootInfoItem extends InfoItem { + public ExecutionRootInfoItem() { + super("execution_root", + "A directory that makes all input and output files visible to the build.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getWorkspace().getExecRoot()); + } + } + + /** + * Info item for the output_path directory. + */ + public static final class OutputPathInfoItem extends InfoItem { + public OutputPathInfoItem() { + super("output_path", + "Output directory", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getWorkspace().getOutputPath()); + } + } + + /** + * Info item for the {blaze,bazel}-bin directory. + */ + public static final class BlazeBinInfoItem extends InfoItem { + public BlazeBinInfoItem(String productName) { + super(productName + "-bin", + "Configuration dependent directory for binaries.", + false); + } + + // This is one of the three (non-hidden) info items that require a configuration, because the + // corresponding paths contain the short name. Maybe we should recommend using the symlinks + // or make them hidden by default? + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(configurationSupplier); + return print(configurationSupplier.get().getBinDirectory().getPath()); + } + } + + /** + * Info item for the {blaze,bazel}-genfiles directory. + */ + public static final class BlazeGenfilesInfoItem extends InfoItem { + public BlazeGenfilesInfoItem(String productName) { + super(productName + "-genfiles", + "Configuration dependent directory for generated files.", + false); + } + + // This is one of the three (non-hidden) info items that require a configuration, because the + // corresponding paths contain the short name. Maybe we should recommend using the symlinks + // or make them hidden by default? + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(configurationSupplier); + return print(configurationSupplier.get().getGenfilesDirectory().getPath()); + } + } + + /** + * Info item for the {blaze,bazel}-testlogs directory. + */ + public static final class BlazeTestlogsInfoItem extends InfoItem { + public BlazeTestlogsInfoItem(String productName) { + super(productName + "-testlogs", + "Configuration dependent directory for logs from a test run.", + false); + } + + // This is one of the three (non-hidden) info items that require a configuration, because the + // corresponding paths contain the short name. Maybe we should recommend using the symlinks + // or make them hidden by default? + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(configurationSupplier); + return print(configurationSupplier.get().getTestLogsDirectory().getPath()); + } + } + + /** + * Info item for the command log + */ + public static final class CommandLogInfoItem extends InfoItem { + public CommandLogInfoItem() { + super("command_log", + "Location of the log containg the output from the build commands.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(BlazeCommandDispatcher.getCommandLogPath( + env.getRuntime().getWorkspace().getOutputBase())); + } + } + + /** + * Info item for the message log + */ + public static final class MessageLogInfoItem extends InfoItem { + public MessageLogInfoItem() { + super("message_log" , + "Location of a log containing machine readable message in LogMessage protobuf format.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(configurationSupplier); + // NB: Duplicated in EventLogModule + return print(env.getRuntime().getWorkspace().getOutputBase().getRelative("message.log")); + } + } + + /** + * Info item for release + */ + public static final class ReleaseInfoItem extends InfoItem { + public ReleaseInfoItem(String productName) { + super("release", + productName + " release identifier", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + return print(BlazeVersionInfo.instance().getReleaseName()); + } + } + + /** + * Info item for server_pid + */ + public static final class ServerPidInfoItem extends InfoItem { + public ServerPidInfoItem(String productName) { + super("server_pid", + productName + " process id", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + return print(OsUtils.getpid()); + } + } + + /** + * Info item for package_path + */ + public static final class PackagePathInfoItem extends InfoItem { + private final OptionsProvider commandOptions; + + public PackagePathInfoItem(OptionsProvider commandOptions) { + super("package_path", + "The search path for resolving package labels.", + false); + this.commandOptions = commandOptions; + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(commandOptions); + PackageCacheOptions packageCacheOptions = + commandOptions.getOptions(PackageCacheOptions.class); + return print(Joiner.on(":").join(packageCacheOptions.packagePath)); + } + } + + private static MemoryUsage getMemoryUsage() { + MemoryMXBean memBean = ManagementFactory.getMemoryMXBean(); + return memBean.getHeapMemoryUsage(); + } + + /** + * Info item for the used heap size + */ + public static final class UsedHeapSizeInfoItem extends InfoItem { + public UsedHeapSizeInfoItem() { + super("used-heap-size", + "The amount of used memory in bytes. Note that this is not a " + + "good indicator of the actual memory use, as it includes any remaining inaccessible " + + "memory.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + return print(StringUtilities.prettyPrintBytes(getMemoryUsage().getUsed())); + } + } + + /** + * Info item for the used heap size after garbage collection + */ + public static final class UsedHeapSizeAfterGcInfoItem extends InfoItem { + public UsedHeapSizeAfterGcInfoItem() { + super("used-heap-size-after-gc", + "The amount of used memory in bytes after a call to System.gc().", + true); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + System.gc(); + return print(StringUtilities.prettyPrintBytes(getMemoryUsage().getUsed())); + } + } + + /** + * Info item for the committed heap size + */ + public static final class CommitedHeapSizeInfoItem extends InfoItem { + public CommitedHeapSizeInfoItem() { + super("committed-heap-size", + "The amount of memory in bytes that is committed for the Java virtual machine to use", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + return print(StringUtilities.prettyPrintBytes(getMemoryUsage().getCommitted())); + } + } + + /** + * Info item for the max heap size + */ + public static final class MaxHeapSizeInfoItem extends InfoItem { + public MaxHeapSizeInfoItem() { + super("max-heap-size", + "The maximum amount of memory in bytes that can be used for memory management.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + return print(StringUtilities.prettyPrintBytes(getMemoryUsage().getMax())); + } + } + + /** + * Info item for the gc-count + */ + public static final class GcCountInfoItem extends InfoItem { + public GcCountInfoItem() { + super("gc-count", + "Number of garbage collection runs.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + // The documentation is not very clear on what it means to have more than + // one GC MXBean, so we just sum them up. + int gcCount = 0; + for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { + gcCount += gcBean.getCollectionCount(); + } + return print(gcCount + ""); + } + } + + /** + * Info item for the gc-time + */ + public static final class GcTimeInfoItem extends InfoItem { + public GcTimeInfoItem() { + super("gc-time", + "The approximate accumulated time spend on garbage collection.", + false); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + // The documentation is not very clear on what it means to have more than + // one GC MXBean, so we just sum them up. + int gcTime = 0; + for (GarbageCollectorMXBean gcBean : ManagementFactory.getGarbageCollectorMXBeans()) { + gcTime += gcBean.getCollectionTime(); + } + return print(gcTime + "ms"); + } + } + + /** + * Info item for the default package. It is deprecated, it still works, when + * explicitly requested, but are not shown by default. It prints multi-line messages and thus + * don't play well with grep. We don't print them unless explicitly requested. + * @deprecated + */ + @Deprecated + public static final class DefaultsPackageInfoItem extends InfoItem { + public DefaultsPackageInfoItem() { + super("defaults-package", + "Default packages used as implicit dependencies", + true); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(env.getRuntime().getDefaultsPackageContent()); + } + } + + private static AllowedRuleClassInfo getAllowedRuleClasses( + Collection<RuleClass> ruleClasses, Attribute attr) { + AllowedRuleClassInfo.Builder info = AllowedRuleClassInfo.newBuilder(); + info.setPolicy(AllowedRuleClassInfo.AllowedRuleClasses.ANY); + + if (attr.isStrictLabelCheckingEnabled() + && attr.getAllowedRuleClassesPredicate() != Predicates.<RuleClass>alwaysTrue()) { + info.setPolicy(AllowedRuleClassInfo.AllowedRuleClasses.SPECIFIED); + Predicate<RuleClass> filter = attr.getAllowedRuleClassesPredicate(); + for (RuleClass otherClass : Iterables.filter(ruleClasses, filter)) { + if (otherClass.isDocumented()) { + info.addAllowedRuleClass(otherClass.getName()); + } + } + } + + return info.build(); + } + + /** + * Returns a byte array containing a proto-buffer describing the build language. + */ + private static byte[] getBuildLanguageDefinition(RuleClassProvider provider) { + BuildLanguage.Builder resultPb = BuildLanguage.newBuilder(); + Collection<RuleClass> ruleClasses = provider.getRuleClassMap().values(); + for (RuleClass ruleClass : ruleClasses) { + if (!ruleClass.isDocumented()) { + continue; + } + + RuleDefinition.Builder rulePb = RuleDefinition.newBuilder(); + rulePb.setName(ruleClass.getName()); + for (Attribute attr : ruleClass.getAttributes()) { + if (!attr.isDocumented()) { + continue; + } + + AttributeDefinition.Builder attrPb = AttributeDefinition.newBuilder(); + attrPb.setName(attr.getName()); + // The protocol compiler, in its infinite wisdom, generates the field as one of the + // integer type and the getTypeEnum() method is missing. WTF? + attrPb.setType(ProtoUtils.getDiscriminatorFromType(attr.getType())); + attrPb.setMandatory(attr.isMandatory()); + + if (BuildType.isLabelType(attr.getType())) { + attrPb.setAllowedRuleClasses(getAllowedRuleClasses(ruleClasses, attr)); + } + + rulePb.addAttribute(attrPb); + } + + resultPb.addRule(rulePb); + } + + return resultPb.build().toByteArray(); + } + + /** + * Info item for the build language. It is deprecated, it still works, when + * explicitly requested, but are not shown by default. It prints multi-line messages and thus + * don't play well with grep. We don't print them unless explicitly requested. + * @Deprecated + */ + @Deprecated + public static final class BuildLanguageInfoItem extends InfoItem { + public BuildLanguageInfoItem() { + super("build-language", + "A protobuffer with the build language structure", + true); + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(env); + return print(getBuildLanguageDefinition(env.getRuntime().getRuleClassProvider())); + } + } + + /** + * Info item for the default package path. It is deprecated, it still works, when + * explicitly requested, but are not shown by default. It prints multi-line messages and thus + * don't play well with grep. We don't print them unless explicitly requested. + * @deprecated + */ + @Deprecated + public static final class DefaultPackagePathInfoItem extends InfoItem { + private final OptionsProvider commandOptions; + + public DefaultPackagePathInfoItem(OptionsProvider commandOptions) { + super("default-package-path", + "The default package path", + true); + this.commandOptions = commandOptions; + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) + throws AbruptExitException { + checkNotNull(commandOptions); + return print(Joiner.on(":").join( + commandOptions.getOptions(PackageCacheOptions.class).packagePath)); + } + } + + /** + * Info item for the make environment. + */ + public static class MakeInfoItem extends InfoItem { + public MakeInfoItem(String name, String description) { + super(name, description, false); + } + @Override + public String getDescription() { + return "Make environment variable '" + name + "'"; + } + + @Override + public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env) { + return print(description); + } + } +}
\ No newline at end of file diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoKey.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoKey.java deleted file mode 100644 index 5dcf36f975..0000000000 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoKey.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2014 The Bazel Authors. 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.devtools.build.lib.Constants; - -/** - * An enumeration of all the valid info keys, excepting the make environment - * variables. - */ -public enum InfoKey { - // directories - WORKSPACE("workspace", "The working directory of the server."), - INSTALL_BASE("install_base", "The installation base directory."), - OUTPUT_BASE("output_base", - "A directory for shared " + Constants.PRODUCT_NAME + " state as well as tool and strategy " - + "specific subdirectories."), - EXECUTION_ROOT("execution_root", - "A directory that makes all input and output files visible to the build."), - OUTPUT_PATH("output_path", "Output directory"), - BLAZE_BIN(Constants.PRODUCT_NAME + "-bin", - "Configuration dependent directory for binaries."), - BLAZE_GENFILES(Constants.PRODUCT_NAME + "-genfiles", - "Configuration dependent directory for generated files."), - BLAZE_TESTLOGS(Constants.PRODUCT_NAME + "-testlogs", - "Configuration dependent directory for logs from a test run."), - - // logs - COMMAND_LOG("command_log", "Location of the log containg the output from the build commands."), - MESSAGE_LOG("message_log" , - "Location of a log containing machine readable message in LogMessage protobuf format."), - - // misc - RELEASE("release", Constants.PRODUCT_NAME + " release identifier"), - SERVER_PID("server_pid", Constants.PRODUCT_NAME + " process id"), - PACKAGE_PATH("package_path", "The search path for resolving package labels."), - - // memory statistics - USED_HEAP_SIZE("used-heap-size", "The amount of used memory in bytes. Note that this is not a " - + "good indicator of the actual memory use, as it includes any remaining inaccessible " - + "memory."), - USED_HEAP_SIZE_AFTER_GC("used-heap-size-after-gc", - "The amount of used memory in bytes after a call to System.gc().", true), - COMMITTED_HEAP_SIZE("committed-heap-size", - "The amount of memory in bytes that is committed for the Java virtual machine to use"), - MAX_HEAP_SIZE("max-heap-size", - "The maximum amount of memory in bytes that can be used for memory management."), - GC_COUNT("gc-count", "Number of garbage collection runs."), - GC_TIME("gc-time", "The approximate accumulated time spend on garbage collection."), - - // These are deprecated, they still work, when explicitly requested, but are not shown by default - - // These keys print multi-line messages and thus don't play well with grep. We don't print them - // unless explicitly requested - DEFAULTS_PACKAGE("defaults-package", "Default packages used as implicit dependencies", true), - BUILD_LANGUAGE("build-language", "A protobuffer with the build language structure", true), - DEFAULT_PACKAGE_PATH("default-package-path", "The default package path", true); - - private final String name; - private final String description; - private final boolean hidden; - - private InfoKey(String name, String description) { - this(name, description, false); - } - - private InfoKey(String name, String description, boolean hidden) { - this.name = name; - this.description = description; - this.hidden = hidden; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public boolean isHidden() { - return hidden; - } -} |