| // 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.rules.extra; |
| |
| import com.google.common.collect.Multimap; |
| import com.google.common.collect.Sets; |
| import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; |
| import com.google.devtools.build.lib.analysis.ConfiguredTarget; |
| import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder; |
| import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory; |
| import com.google.devtools.build.lib.analysis.RuleContext; |
| import com.google.devtools.build.lib.analysis.Runfiles; |
| import com.google.devtools.build.lib.analysis.RunfilesProvider; |
| import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; |
| import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; |
| import com.google.devtools.build.lib.analysis.extra.ExtraActionMapProvider; |
| import com.google.devtools.build.lib.analysis.extra.ExtraActionSpec; |
| import com.google.devtools.build.lib.collect.ImmutableSortedKeyListMultimap; |
| import com.google.devtools.build.lib.packages.Type; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Implementation for the 'action_listener' rule. |
| */ |
| public final class ActionListener implements RuleConfiguredTargetFactory { |
| @Override |
| public ConfiguredTarget create(RuleContext ruleContext) |
| throws InterruptedException, RuleErrorException, ActionConflictException { |
| // This rule doesn't produce any output when listed as a build target. |
| // Only when used via the --experimental_action_listener flag, |
| // this rule instructs the build system to add additional outputs. |
| |
| List<ExtraActionSpec> extraActions; |
| |
| Multimap<String, ExtraActionSpec> extraActionMap; |
| |
| Set<String> mnemonics = Sets.newHashSet( |
| ruleContext.attributes().get("mnemonics", Type.STRING_LIST)); |
| extraActions = retrieveAndValidateExtraActions(ruleContext); |
| ImmutableSortedKeyListMultimap.Builder<String, ExtraActionSpec> |
| extraActionMapBuilder = ImmutableSortedKeyListMultimap.builder(); |
| for (String mnemonic : mnemonics) { |
| extraActionMapBuilder.putAll(mnemonic, extraActions); |
| } |
| extraActionMap = extraActionMapBuilder.build(); |
| return new RuleConfiguredTargetBuilder(ruleContext) |
| .add(RunfilesProvider.class, RunfilesProvider.simple(Runfiles.EMPTY)) |
| .add(ExtraActionMapProvider.class, new ExtraActionMapProvider(extraActionMap)) |
| .build(); |
| } |
| |
| /** |
| * Loads the targets listed in the 'extra_actions' attribute of this rule. |
| * Validates these targets to be extra_actions indeed. And checks if the |
| * blaze version number is in the range of the blaze_version restrictions on the rule. |
| */ |
| private List<ExtraActionSpec> retrieveAndValidateExtraActions(RuleContext ruleContext) { |
| List<ExtraActionSpec> extraActions = new ArrayList<>(); |
| for (TransitiveInfoCollection prerequisite : |
| ruleContext.getPrerequisites("extra_actions", Mode.TARGET)) { |
| ExtraActionSpec spec = prerequisite.getProvider(ExtraActionSpec.class); |
| if (spec == null) { |
| ruleContext.attributeError("extra_actions", String.format("target %s is not an " |
| + "extra_action rule", prerequisite.getLabel().toString())); |
| } else { |
| extraActions.add(spec); |
| } |
| } |
| if (extraActions.isEmpty()) { |
| ruleContext.attributeWarning( |
| "extra_actions", "No extra_action is specified for this version of bazel."); |
| } |
| return extraActions; |
| } |
| } |