Changed mandatoryProviders to mandatoryProvidersList
"mandatoryProvidersList" is a list of sets of providers. For any rule, if it provides
all the providers from one of those sets, we consider the dependency valid.
--
MOS_MIGRATED_REVID=115221394
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index f0fecff..9fd4fd4 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.analysis;
+import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
@@ -1660,12 +1661,40 @@
}
private void validateMandatoryProviders(ConfiguredTarget prerequisite, Attribute attribute) {
- for (String provider : attribute.getMandatoryProviders()) {
- if (prerequisite.get(provider) == null) {
- attributeError(attribute.getName(), "'" + prerequisite.getLabel()
- + "' does not have mandatory provider '" + provider + "'");
+ List<ImmutableSet<String>> mandatoryProvidersList = attribute.getMandatoryProvidersList();
+ if (mandatoryProvidersList.isEmpty()) {
+ return;
+ }
+ List<List<String>> missingProvidersList = new ArrayList<>();
+ for (ImmutableSet<String> providers : mandatoryProvidersList) {
+ List<String> missing = new ArrayList<>();
+ for (String provider : providers) {
+ if (prerequisite.get(provider) == null) {
+ missing.add(provider);
+ }
+ }
+ if (missing.isEmpty()) {
+ return;
+ } else {
+ missingProvidersList.add(missing);
}
}
+ StringBuilder missingProviders = new StringBuilder();
+ Joiner joinProvider = Joiner.on("', '");
+ for (List<String> providers : missingProvidersList) {
+ if (missingProviders.length() > 0) {
+ missingProviders.append(" or ");
+ }
+ missingProviders.append((providers.size() > 1) ? "[" : "")
+ .append("'");
+ joinProvider.appendTo(missingProviders, providers);
+ missingProviders.append("'")
+ .append((providers.size() > 1) ? "]" : "");
+ }
+ attributeError(
+ attribute.getName(),
+ "'" + prerequisite.getLabel() + "' does not have mandatory provider "
+ + missingProviders);
}
private void validateDirectPrerequisite(Attribute attribute, ConfiguredTarget prerequisite) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index cd808c5..f8923e7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -314,7 +314,8 @@
private Predicate<AttributeMap> condition;
private Set<PropertyFlag> propertyFlags = EnumSet.noneOf(PropertyFlag.class);
private PredicateWithMessage<Object> allowedValues = null;
- private ImmutableSet<String> mandatoryProviders = ImmutableSet.<String>of();
+ private ImmutableList<ImmutableSet<String>> mandatoryProvidersList =
+ ImmutableList.<ImmutableSet<String>>of();
private Set<RuleAspect> aspects = new LinkedHashSet<>();
/**
@@ -696,14 +697,23 @@
}
/**
- * Sets a set of mandatory Skylark providers. Every configured target occurring in
- * this label type attribute has to provide all of these providers, otherwise an
- * error is produces during the analysis phase for every missing provider.
+ * Sets a list of sets of mandatory Skylark providers. Every configured target occurring in
+ * this label type attribute has to provide all the providers from one of those sets,
+ * otherwise an error is produces during the analysis phase.
*/
- public Builder<TYPE> mandatoryProviders(Iterable<String> providers) {
+ public Builder<TYPE> mandatoryProvidersList(Iterable<? extends Iterable<String>> providersList){
Preconditions.checkState((type == BuildType.LABEL) || (type == BuildType.LABEL_LIST),
"must be a label-valued type");
- this.mandatoryProviders = ImmutableSet.copyOf(providers);
+ ImmutableList.Builder<ImmutableSet<String>> listBuilder = ImmutableList.builder();
+ for (Iterable<String> providers : providersList) {
+ listBuilder.add(ImmutableSet.copyOf(providers));
+ }
+ this.mandatoryProvidersList = listBuilder.build();
+ return this;
+ }
+
+ public Builder<TYPE> mandatoryProviders(Iterable<String> providers) {
+ mandatoryProvidersList(ImmutableList.of(providers));
return this;
}
@@ -826,11 +836,21 @@
allowedFileTypesForLabels = FileTypeSet.ANY_FILE;
}
}
- return new Attribute(name, type, Sets.immutableEnumSet(propertyFlags),
- valueSet ? value : type.getDefaultValue(), configTransition, configurator,
- allowedRuleClassesForLabels, allowedRuleClassesForLabelsWarning,
- allowedFileTypesForLabels, validityPredicate, condition,
- allowedValues, mandatoryProviders, ImmutableSet.copyOf(aspects));
+ return new Attribute(
+ name,
+ type,
+ Sets.immutableEnumSet(propertyFlags),
+ valueSet ? value : type.getDefaultValue(),
+ configTransition,
+ configurator,
+ allowedRuleClassesForLabels,
+ allowedRuleClassesForLabelsWarning,
+ allowedFileTypesForLabels,
+ validityPredicate,
+ condition,
+ allowedValues,
+ mandatoryProvidersList,
+ ImmutableSet.copyOf(aspects));
}
}
@@ -1112,7 +1132,7 @@
private final PredicateWithMessage<Object> allowedValues;
- private final ImmutableSet<String> mandatoryProviders;
+ private final ImmutableList<ImmutableSet<String>> mandatoryProvidersList;
private final ImmutableSet<RuleAspect> aspects;
@@ -1131,8 +1151,12 @@
* (which must be of type LABEL, LABEL_LIST, NODEP_LABEL or
* NODEP_LABEL_LIST).
*/
- private Attribute(String name, Type<?> type, Set<PropertyFlag> propertyFlags,
- Object defaultValue, Transition configTransition,
+ private Attribute(
+ String name,
+ Type<?> type,
+ Set<PropertyFlag> propertyFlags,
+ Object defaultValue,
+ Transition configTransition,
Configurator<?, ?> configurator,
Predicate<RuleClass> allowedRuleClassesForLabels,
Predicate<RuleClass> allowedRuleClassesForLabelsWarning,
@@ -1140,7 +1164,7 @@
ValidityPredicate validityPredicate,
Predicate<AttributeMap> condition,
PredicateWithMessage<Object> allowedValues,
- ImmutableSet<String> mandatoryProviders,
+ ImmutableList<ImmutableSet<String>> mandatoryProvidersList,
ImmutableSet<RuleAspect> aspects) {
Preconditions.checkNotNull(configTransition);
Preconditions.checkArgument(
@@ -1173,7 +1197,7 @@
this.validityPredicate = validityPredicate;
this.condition = condition;
this.allowedValues = allowedValues;
- this.mandatoryProviders = mandatoryProviders;
+ this.mandatoryProvidersList = mandatoryProvidersList;
this.aspects = aspects;
}
@@ -1347,10 +1371,10 @@
}
/**
- * Returns the set of mandatory Skylark providers.
+ * Returns the list of sets of mandatory Skylark providers.
*/
- public ImmutableSet<String> getMandatoryProviders() {
- return mandatoryProviders;
+ public ImmutableList<ImmutableSet<String>> getMandatoryProvidersList() {
+ return mandatoryProvidersList;
}
public FileTypeSet getAllowedFileTypesPredicate() {