diff options
author | 2017-10-10 05:29:56 +0200 | |
---|---|---|
committer | 2017-10-10 11:24:42 +0200 | |
commit | ceb1013c1ca0238188e2714442fcfb2efb16bc6a (patch) | |
tree | 2cdd1a3a21e716a7653c8be61d39d8b2396c7bb0 /src/main/java/com/google/devtools | |
parent | 43edc92ac185ee2f1b8d0db31943ec1655b43434 (diff) |
Report the structured Bazel command line via the BEP.
This is part of the effort outlined in https://bazel.build/designs/2017/07/13/improved-command-line-reporting.html. The refactoring of the options parser is not yet complete, so we still do not have complete & correct information about the canonical command line. Where the information is blatantly incorrect, a best approximation was made, with comments and tests documenting the deficiencies.
Change the names of the initial CommandLine fields in the BEP to be explicitly identified as unstructured.
RELNOTES: None.
PiperOrigin-RevId: 171625377
Diffstat (limited to 'src/main/java/com/google/devtools')
12 files changed, 443 insertions, 25 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index c2848dbf3e..9dfb06ba1e 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -1007,10 +1007,12 @@ java_library( "//src/main/protobuf:action_cache_java_proto", "//src/main/protobuf:bazel_flags_java_proto", "//src/main/protobuf:build_java_proto", + "//src/main/protobuf:command_line_java_proto", "//src/main/protobuf:command_server_java_grpc", "//src/main/protobuf:command_server_java_proto", "//src/main/protobuf:extra_actions_base_java_proto", "//src/main/protobuf:invocation_policy_java_proto", + "//src/main/protobuf:option_filters_java_proto", "//src/main/protobuf:test_status_java_proto", "//third_party:guava", "//third_party:jsr305", diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java index 1e73efc3db..2479b59b3d 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/BuildEventId.java @@ -88,11 +88,24 @@ public final class BuildEventId implements Serializable { BuildEventStreamProtos.BuildEventId.newBuilder().setStarted(startedId).build()); } - public static BuildEventId commandlineId() { - BuildEventStreamProtos.BuildEventId.CommandLineId commandLineId = - BuildEventStreamProtos.BuildEventId.CommandLineId.getDefaultInstance(); + public static BuildEventId unstructuredCommandlineId() { + BuildEventStreamProtos.BuildEventId.UnstructuredCommandLineId commandLineId = + BuildEventStreamProtos.BuildEventId.UnstructuredCommandLineId.getDefaultInstance(); return new BuildEventId( - BuildEventStreamProtos.BuildEventId.newBuilder().setCommandLine(commandLineId).build()); + BuildEventStreamProtos.BuildEventId.newBuilder() + .setUnstructuredCommandLine(commandLineId) + .build()); + } + + public static BuildEventId structuredCommandlineId(String commandLineLabel) { + BuildEventStreamProtos.BuildEventId.StructuredCommandLineId commandLineId = + BuildEventStreamProtos.BuildEventId.StructuredCommandLineId.newBuilder() + .setCommandLineLabel(commandLineLabel) + .build(); + return new BuildEventId( + BuildEventStreamProtos.BuildEventId.newBuilder() + .setStructuredCommandLine(commandLineId) + .build()); } public static BuildEventId optionsParsedId() { diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/BUILD b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/BUILD index c1c65b2696..a4bd2ed85a 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/BUILD +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/BUILD @@ -22,6 +22,7 @@ proto_library( name = "build_event_stream_proto", srcs = ["build_event_stream.proto"], deps = [ + "//src/main/protobuf:command_line_proto", "//src/main/protobuf:invocation_policy_proto", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto index 472f104ecc..bbe9963ab9 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto @@ -20,6 +20,7 @@ option java_package = "com.google.devtools.build.lib.buildeventstream"; option java_outer_classname = "BuildEventStreamProtos"; import "src/main/protobuf/invocation_policy.proto"; +import "src/main/protobuf/command_line.proto"; // Identifier for a build event. It is deliberately structured to also provide // information about which build target etc the event is related to. @@ -53,7 +54,16 @@ message BuildEventId { // Identifier on an event indicating the original commandline received by // the bazel server. - message CommandLineId { + message UnstructuredCommandLineId { + } + + // Identifier on an event describing the commandline received by Bazel. + message StructuredCommandLineId { + // A title for this command line value, as there may be multiple. + // For example, a single invocation may wish to report both the literal and + // canonical command lines, and this label would be used to differentiate + // between both versions. + string command_line_label = 1; } // Identifier of an event indicating the workspace status. @@ -159,7 +169,8 @@ message BuildEventId { UnknownBuildEventId unknown = 1; ProgressId progress = 2; BuildStartedId started = 3; - CommandLineId command_line = 11; + UnstructuredCommandLineId unstructured_command_line = 11; + StructuredCommandLineId structured_command_line = 18; WorkspaceStatusId workspace_status = 14; OptionsParsedId options_parsed = 12; FetchId fetch = 17; @@ -260,7 +271,7 @@ message BuildStarted { // like name and relevant entries of rc-files and client environment variables. // However, it does contain enough information to reproduce the build // invocation. -message CommandLine { +message UnstructuredCommandLine { repeated string args = 1; } @@ -531,7 +542,8 @@ message BuildEvent { Progress progress = 3; Aborted aborted = 4; BuildStarted started = 5; - CommandLine command_line = 12; + UnstructuredCommandLine unstructured_command_line = 12; + command_line.CommandLine structured_command_line = 22; OptionsParsed options_parsed = 13; WorkspaceStatus workspace_status = 16; Fetch fetch = 21; diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java index e84df587de..df601bb1ca 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/buildevent/BuildStartingEvent.java @@ -82,7 +82,7 @@ public final class BuildStartingEvent implements BuildEvent { public Collection<BuildEventId> getChildrenEvents() { return ImmutableList.of( ProgressEvent.INITIAL_PROGRESS_UPDATE, - BuildEventId.commandlineId(), + BuildEventId.unstructuredCommandlineId(), BuildEventId.optionsParsedId(), BuildEventId.workspaceStatusId(), BuildEventId.targetPatternExpanded(request.getTargets()), diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java index 5bd9ad9f54..12d87af3ce 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java @@ -231,9 +231,14 @@ public class BlazeCommandDispatcher { parseOptionsForCommand(rcfileNotes, commandAnnotation, optionsParser, optionsMap, null, null); if (commandAnnotation.builds()) { + // splits project files from targets in the traditional sense ProjectFileSupport.handleProjectFiles( - eventHandler, runtime.getProjectFileProvider(), workspaceDirectory, workingDirectory, - optionsParser, commandAnnotation.name()); + eventHandler, + runtime.getProjectFileProvider(), + workspaceDirectory, + workingDirectory, + optionsParser, + commandAnnotation.name()); } // Fix-point iteration until all configs are loaded. @@ -276,7 +281,8 @@ public class BlazeCommandDispatcher { long firstContactTime, Optional<List<Pair<String, String>>> startupOptionsTaggedWithBazelRc) throws ShutdownBlazeServerException, InterruptedException { - OriginalCommandLineEvent originalCommandLine = new OriginalCommandLineEvent(args); + OriginalUnstructuredCommandLineEvent originalCommandLine = + new OriginalUnstructuredCommandLineEvent(args); Preconditions.checkNotNull(clientDescription); if (args.isEmpty()) { // Default to help command if no arguments specified. args = HELP_COMMAND; @@ -370,7 +376,7 @@ public class BlazeCommandDispatcher { } private int execExclusively( - OriginalCommandLineEvent originalCommandLine, + OriginalUnstructuredCommandLineEvent unstructuredServerCommandLineEvent, InvocationPolicy invocationPolicy, List<String> args, OutErr outErr, @@ -395,7 +401,11 @@ public class BlazeCommandDispatcher { eventHandler, workspace, command, commandAnnotation, commandName, invocationPolicy, args, optionsResult, rcfileNotes); OptionsProvider options = optionsResult.get(); - + CommandLineEvent originalCommandLineEvent = + new CommandLineEvent.OriginalCommandLineEvent( + runtime, commandName, options, startupOptionsTaggedWithBazelRc); + CommandLineEvent canonicalCommandLineEvent = + new CommandLineEvent.CanonicalCommandLineEvent(runtime, commandName, options); // The initCommand call also records the start time for the timestamp granularity monitor. CommandEnvironment env = workspace.initCommand(commandAnnotation, options); // Record the command's starting time for use by the commands themselves. @@ -591,7 +601,11 @@ public class BlazeCommandDispatcher { return e.getExitCode().getNumericExitCode(); } - env.getEventBus().post(originalCommandLine); + // Log the command line now that the modules have all had a change to register their listeners + // to the event bus. + env.getEventBus().post(unstructuredServerCommandLineEvent); + env.getEventBus().post(originalCommandLineEvent); + env.getEventBus().post(canonicalCommandLineEvent); for (BlazeModule module : runtime.getBlazeModules()) { env.getSkyframeExecutor().injectExtraPrecomputedValues(module.getPrecomputedValues()); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandLineEvent.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandLineEvent.java new file mode 100644 index 0000000000..232aa45123 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandLineEvent.java @@ -0,0 +1,369 @@ +// Copyright 2017 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; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.buildeventstream.BuildEventConverters; +import com.google.devtools.build.lib.buildeventstream.BuildEventId; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos; +import com.google.devtools.build.lib.buildeventstream.BuildEventWithOrderConstraint; +import com.google.devtools.build.lib.buildeventstream.GenericBuildEvent; +import com.google.devtools.build.lib.runtime.proto.CommandLineOuterClass.ChunkList; +import com.google.devtools.build.lib.runtime.proto.CommandLineOuterClass.CommandLine; +import com.google.devtools.build.lib.runtime.proto.CommandLineOuterClass.CommandLineSection; +import com.google.devtools.build.lib.runtime.proto.CommandLineOuterClass.Option; +import com.google.devtools.build.lib.runtime.proto.CommandLineOuterClass.OptionList; +import com.google.devtools.build.lib.util.Pair; +import com.google.devtools.common.options.OptionDefinition; +import com.google.devtools.common.options.OptionEffectTag; +import com.google.devtools.common.options.OptionMetadataTag; +import com.google.devtools.common.options.OptionPriority; +import com.google.devtools.common.options.OptionsParser; +import com.google.devtools.common.options.OptionsParsingException; +import com.google.devtools.common.options.OptionsProvider; +import com.google.devtools.common.options.ParsedOptionDescription; +import com.google.devtools.common.options.proto.OptionFilters; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +/** A build event reporting the command line by which Bazel was invoked. */ +public abstract class CommandLineEvent implements BuildEventWithOrderConstraint { + protected final String productName; + protected final OptionsProvider activeStartupOptions; + protected final String commandName; + protected final OptionsProvider commandOptions; + + CommandLineEvent( + String productName, + OptionsProvider activeStartupOptions, + String commandName, + OptionsProvider commandOptions) { + this.productName = productName; + this.activeStartupOptions = activeStartupOptions; + this.commandName = commandName; + this.commandOptions = commandOptions; + } + + @Override + public Collection<BuildEventId> getChildrenEvents() { + return ImmutableList.of(); + } + + @Override + public Collection<BuildEventId> postedAfter() { + return ImmutableList.of(BuildEventId.buildStartedId()); + } + + CommandLineSection getExecutableSection() { + return CommandLineSection.newBuilder() + .setSectionLabel("executable") + .setChunkList(ChunkList.newBuilder().addChunk(productName)) + .build(); + } + + CommandLineSection getCommandSection() { + return CommandLineSection.newBuilder() + .setSectionLabel("command") + .setChunkList(ChunkList.newBuilder().addChunk(commandName)) + .build(); + } + + /** + * Convert an array of tags to the equivalent proto-generated enum values. + * + * <p>The proto type is duplicate in order to not burden the OptionsParser with the proto + * dependency. A test guarantees that the two enum types are kept in sync with matching indices. + */ + static List<OptionFilters.OptionEffectTag> getProtoEffectTags(OptionEffectTag[] tagArray) { + ArrayList<OptionFilters.OptionEffectTag> effectTags = new ArrayList<>(tagArray.length); + for (OptionEffectTag tag : tagArray) { + effectTags.add(OptionFilters.OptionEffectTag.forNumber(tag.getValue())); + } + return effectTags; + } + + /** + * Convert an array of tags to the equivalent proto-generated enum values. + * + * <p>The proto type is duplicate in order to not burden the OptionsParser with the proto + * dependency. A test guarantees that the two enum types are kept in sync with matching indices. + */ + static List<OptionFilters.OptionMetadataTag> getProtoMetadataTags(OptionMetadataTag[] tagArray) { + ArrayList<OptionFilters.OptionMetadataTag> metadataTags = new ArrayList<>(tagArray.length); + for (OptionMetadataTag tag : tagArray) { + metadataTags.add(OptionFilters.OptionMetadataTag.forNumber(tag.getValue())); + } + return metadataTags; + } + + List<Option> getOptionListFromParsedOptionDescriptions( + List<ParsedOptionDescription> parsedOptionDescriptions) { + List<Option> options = new ArrayList<>(); + for (ParsedOptionDescription parsedOption : parsedOptionDescriptions) { + options.add( + createOption( + parsedOption.getOptionDefinition(), + parsedOption.getCommandLineForm(), + parsedOption.getUnconvertedValue())); + } + return options; + } + + private Option createOption( + OptionDefinition optionDefinition, String combinedForm, @Nullable String value) { + Option.Builder option = Option.newBuilder(); + option.setCombinedForm(combinedForm); + option.setOptionName(optionDefinition.getOptionName()); + if (value != null) { + option.setOptionValue(value); + } + option.addAllEffectTags(getProtoEffectTags(optionDefinition.getOptionEffectTags())); + option.addAllMetadataTags(getProtoMetadataTags(optionDefinition.getOptionMetadataTags())); + return option.build(); + } + + /** + * Returns the startup option section of the command line for the startup options as the server + * received them at its startup. Since not all client options get passed to the server as startup + * options, this might not represent the actual list of startup options as the user provided them. + */ + CommandLineSection getActiveStartupOptions() { + return CommandLineSection.newBuilder() + .setSectionLabel("startup options") + .setOptionList( + OptionList.newBuilder() + .addAllOption( + getOptionListFromParsedOptionDescriptions( + activeStartupOptions.asCompleteListOfParsedOptions()))) + .build(); + } + + /** + * Returns the final part of the command line, containing whatever was left after obtaining the + * command and its options. + */ + CommandLineSection getResidual() { + // Potential further split: how the residual, if any is accepted, gets interpreted depends on + // the command. For example, for build commands, we might want to consider separating out + // project files, as in runtime.commands.ProjectFileSupport. To properly report this, we would + // need to let the command customize how the residual is listed. This catch-all could serve + // as a default in this case. + return CommandLineSection.newBuilder() + .setSectionLabel("residual") + .setChunkList(ChunkList.newBuilder().addAllChunk(commandOptions.getResidue())) + .build(); + } + + /** This reports a reassembled version of the command line as Bazel received it. */ + public static class OriginalCommandLineEvent extends CommandLineEvent { + private static final String LABEL = "original"; + private final Optional<List<Pair<String, String>>> originalStartupOptions; + + public OriginalCommandLineEvent( + BlazeRuntime runtime, + String commandName, + OptionsProvider commandOptions, + Optional<List<Pair<String, String>>> originalStartupOptions) { + this( + runtime.getProductName(), + runtime.getStartupOptionsProvider(), + commandName, + commandOptions, + originalStartupOptions); + } + + @VisibleForTesting + OriginalCommandLineEvent( + String productName, + OptionsProvider activeStartupOptions, + String commandName, + OptionsProvider commandOptions, + Optional<List<Pair<String, String>>> originalStartupOptions) { + super(productName, activeStartupOptions, commandName, commandOptions); + this.originalStartupOptions = originalStartupOptions; + } + + @Override + public BuildEventId getEventId() { + return BuildEventId.structuredCommandlineId(LABEL); + } + + /** + * Returns the literal command line options as received. These are not the final parsed values, + * but are passed as is from the client, so we do not have the full OptionDefinition + * information. In this form, only set the "combinedForm" field. + */ + private CommandLineSection getStartupOptionSection() { + if (originalStartupOptions.isPresent()) { + List<Option> options = new ArrayList<>(); + for (Pair<String, String> sourceToOptionPair : originalStartupOptions.get()) { + // Only add the options that were added by the command line. + // TODO(b/19881919) decide the format that option source information should take and then + // add all options, tagged with the source, instead of filtering out the rc options. + if (sourceToOptionPair.first != null && sourceToOptionPair.first.isEmpty()) { + options.add( + Option.newBuilder().setCombinedForm(sourceToOptionPair.getSecond()).build()); + } + } + return CommandLineSection.newBuilder() + .setSectionLabel("startup options") + .setOptionList(OptionList.newBuilder().addAllOption(options)) + .build(); + } else { + // If we were not provided with the startup options, fallback to reporting the active ones + // stored by the Bazel Runtime. + return getActiveStartupOptions(); + } + } + + private CommandLineSection getExplicitCommandOptions() { + List<ParsedOptionDescription> explicitOptions = + commandOptions + .asListOfExplicitOptions() + .stream() + .filter( + parsedOptionDescription -> + parsedOptionDescription.getPriority() == OptionPriority.COMMAND_LINE) + .collect(Collectors.toList()); + return CommandLineSection.newBuilder() + .setSectionLabel("command options") + .setOptionList( + OptionList.newBuilder() + .addAllOption(getOptionListFromParsedOptionDescriptions(explicitOptions))) + .build(); + } + + @Override + public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) { + return GenericBuildEvent.protoChaining(this) + .setStructuredCommandLine( + CommandLine.newBuilder() + .setCommandLineLabel(LABEL) + .addSections(getExecutableSection()) + .addSections(getStartupOptionSection()) + .addSections(getCommandSection()) + .addSections(getExplicitCommandOptions()) + .addSections(getResidual()) + .build()) + .build(); + } + } + + /** This reports the canonical form of the command line. */ + public static class CanonicalCommandLineEvent extends CommandLineEvent { + private static final String LABEL = "canonical"; + + public CanonicalCommandLineEvent( + BlazeRuntime runtime, String commandName, OptionsProvider commandOptions) { + this( + runtime.getProductName(), + runtime.getStartupOptionsProvider(), + commandName, + commandOptions); + } + + @VisibleForTesting + CanonicalCommandLineEvent( + String productName, + OptionsProvider activeStartupOptions, + String commandName, + OptionsProvider commandOptions) { + super(productName, activeStartupOptions, commandName, commandOptions); + } + + @Override + public BuildEventId getEventId() { + return BuildEventId.structuredCommandlineId(LABEL); + } + + /** + * Returns the effective startup options. + * + * <p>Since in this command line the command options include invocation policy's and blazercs' + * contents expanded fully, the list of startup options should prevent reapplication of these + * contents. + * + * <p>The options parser does not understand the effect of these flags, since the relationship + * between these startup options and the command options is not held within the options parser, + * so instead, we add a small hack. Remove any explicit mentions of these flags, and explicitly + * add the options that prevent Blaze from looking for the default rc files. + */ + private CommandLineSection getCanonicalStartupOptions() { + List<Option> unfilteredOptions = getActiveStartupOptions().getOptionList().getOptionList(); + // Create the fake ones to prevent reapplication of the original rc file contents. + OptionsParser fakeOptions = OptionsParser.newOptionsParser(BlazeServerStartupOptions.class); + try { + fakeOptions.parse("--nomaster_blazerc", "--blazerc=/dev/null"); + } catch (OptionsParsingException e) { + // Unless someone changes the definition of these flags, this is impossible. + throw new IllegalStateException(e); + } + + // Remove any instances of the applied, and add the new blocking ones. + return CommandLineSection.newBuilder() + .setSectionLabel("startup options") + .setOptionList( + OptionList.newBuilder() + .addAllOption( + unfilteredOptions + .stream() + .filter( + option -> { + String optionName = option.getOptionName(); + return !optionName.equals("blazerc") + && !optionName.equals("master_blazerc") + && !optionName.equals("invocation_policy"); + }) + .collect(Collectors.toList())) + .addAllOption( + getOptionListFromParsedOptionDescriptions( + fakeOptions.asCompleteListOfParsedOptions()))) + .build(); + } + + /** Returns the canonical command options, overridden and default values are not listed. */ + // TODO(b/19881919) this should use OptionValueDescription's tracking of relevant option + // instances, but as this is not yet possible, list the full options list. + private CommandLineSection getCanonicalCommandOptions() { + return CommandLineSection.newBuilder() + .setSectionLabel("command options") + .setOptionList( + OptionList.newBuilder() + .addAllOption( + getOptionListFromParsedOptionDescriptions( + commandOptions.asCompleteListOfParsedOptions()))) + .build(); + } + + @Override + public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) { + return GenericBuildEvent.protoChaining(this) + .setStructuredCommandLine( + CommandLine.newBuilder() + .setCommandLineLabel(LABEL) + .addSections(getExecutableSection()) + .addSections(getCanonicalStartupOptions()) + .addSections(getCommandSection()) + .addSections(getCanonicalCommandOptions()) + .addSections(getResidual()) + .build()) + .build(); + } + } +} diff --git a/src/main/java/com/google/devtools/build/lib/runtime/GotOptionsEvent.java b/src/main/java/com/google/devtools/build/lib/runtime/GotOptionsEvent.java index cf7c363872..2193761000 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/GotOptionsEvent.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/GotOptionsEvent.java @@ -105,6 +105,7 @@ public class GotOptionsEvent implements BuildEventWithOrderConstraint { @Override public Collection<BuildEventId> postedAfter() { - return ImmutableList.of(BuildEventId.buildStartedId(), BuildEventId.commandlineId()); + return ImmutableList.of( + BuildEventId.buildStartedId(), BuildEventId.unstructuredCommandlineId()); } } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/OriginalCommandLineEvent.java b/src/main/java/com/google/devtools/build/lib/runtime/OriginalUnstructuredCommandLineEvent.java index e6b02ba101..291f1e6f4a 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/OriginalCommandLineEvent.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/OriginalUnstructuredCommandLineEvent.java @@ -24,17 +24,17 @@ import java.util.Collection; import java.util.List; /** A build event reporting the original commandline by which bazel was invoked. */ -public class OriginalCommandLineEvent implements BuildEventWithOrderConstraint { +public class OriginalUnstructuredCommandLineEvent implements BuildEventWithOrderConstraint { private final ImmutableList<String> args; - public OriginalCommandLineEvent(List<String> args) { + public OriginalUnstructuredCommandLineEvent(List<String> args) { this.args = ImmutableList.copyOf(args); } @Override public BuildEventId getEventId() { - return BuildEventId.commandlineId(); + return BuildEventId.unstructuredCommandlineId(); } @Override @@ -50,7 +50,8 @@ public class OriginalCommandLineEvent implements BuildEventWithOrderConstraint { @Override public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventConverters converters) { return GenericBuildEvent.protoChaining(this) - .setCommandLine(BuildEventStreamProtos.CommandLine.newBuilder().addAllArgs(args).build()) + .setUnstructuredCommandLine( + BuildEventStreamProtos.UnstructuredCommandLine.newBuilder().addAllArgs(args).build()) .build(); } } diff --git a/src/main/java/com/google/devtools/common/options/OptionValueDescription.java b/src/main/java/com/google/devtools/common/options/OptionValueDescription.java index 0d81d49a84..aa808e2141 100644 --- a/src/main/java/com/google/devtools/common/options/OptionValueDescription.java +++ b/src/main/java/com/google/devtools/common/options/OptionValueDescription.java @@ -208,8 +208,11 @@ public abstract class OptionValueDescription { // The new value does not override the old value, as it has lower priority. warnings.add( String.format( - "The lower priority option '%s' does not override the previous value '%s'", - parsedOption.getCommandLineForm(), effectiveOptionInstance.getCommandLineForm())); + "The lower priority option '%s' (source %s) does not override the previous value " + + "'%s'", + parsedOption.getCommandLineForm(), + parsedOption.getSource(), + effectiveOptionInstance.getCommandLineForm())); } } diff --git a/src/main/java/com/google/devtools/common/options/OptionsProvider.java b/src/main/java/com/google/devtools/common/options/OptionsProvider.java index 1c7737fbda..5fd8ac00c1 100644 --- a/src/main/java/com/google/devtools/common/options/OptionsProvider.java +++ b/src/main/java/com/google/devtools/common/options/OptionsProvider.java @@ -39,8 +39,10 @@ public interface OptionsProvider extends OptionsClassProvider { * specified. If an option was specified multiple times, it is included in the result multiple * times. Does not include the residue. * - * <p>The returned list can be filtered if undocumented, hidden or implicit options should not be - * displayed. + * <p>The returned list includes undocumented, hidden or implicit options, and should be filtered + * as needed. Since it includes all options parsed, it will also include both an expansion option + * and the options it expanded to, and so blindly using this list for a new invocation will cause + * double-application of these options. */ List<ParsedOptionDescription> asCompleteListOfParsedOptions(); diff --git a/src/main/java/com/google/devtools/common/options/ParsedOptionDescription.java b/src/main/java/com/google/devtools/common/options/ParsedOptionDescription.java index 1f43172fb2..d5582635e3 100644 --- a/src/main/java/com/google/devtools/common/options/ParsedOptionDescription.java +++ b/src/main/java/com/google/devtools/common/options/ParsedOptionDescription.java @@ -115,7 +115,7 @@ public final class ParsedOptionDescription { return unconvertedValue; } - OptionPriority getPriority() { + public OptionPriority getPriority() { return origin.getPriority(); } |