Restrict direct dependency propagation to INCLUDE items
The only remaining intended use of this feature is for
objc_proto_library strict dependency includes, internal to Google. I
would like to lock this down to avoid unintended usage.
RELNOTES: None
PiperOrigin-RevId: 292189451
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
index f4d502e..7f446cc 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AppleSkylarkCommon.java
@@ -80,6 +80,10 @@
+ "iterable with %s.";
@VisibleForTesting
+ public static final String BAD_DIRECT_DEPENDENCY_KEY_ERROR =
+ "Key %s not allowed to be in direct_dep_provider.";
+
+ @VisibleForTesting
public static final String NOT_SET_ERROR = "Value for key %s must be a set, instead found %s.";
@VisibleForTesting
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index e9c5296..07468c7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -373,6 +373,9 @@
UMBRELLA_HEADER,
WEAK_SDK_FRAMEWORK);
+ /** A white list of keys we support for strict-dependency / non-propagated items. */
+ static final ImmutableList<Key<?>> STRICT_DEPENDENCY_KEYS = ImmutableList.<Key<?>>of(INCLUDE);
+
/**
* Keys that should be kept as directItems. This is limited to a few keys that have larger
* performance implications when flattened in a transitive fashion and/or require non-transitive
@@ -1081,17 +1084,31 @@
return this;
}
+ private static <E> EvalException badDirectDependencyKeyError(Key<E> key) {
+ return new EvalException(
+ null,
+ String.format(
+ AppleSkylarkCommon.BAD_DIRECT_DEPENDENCY_KEY_ERROR, key.getSkylarkKeyName()));
+ }
+
/**
* Add all keys and values from the given provider, but propagate any normally-propagated items
* only to direct dependers of this ObjcProvider.
*/
- public Builder addAsDirectDeps(ObjcProvider provider) {
+ public Builder addAsDirectDeps(ObjcProvider provider) throws EvalException {
for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.items.entrySet()) {
- uncheckedAddTransitive(
- typeEntry.getKey(), typeEntry.getValue(), this.strictDependencyItems);
+ Key<?> key = typeEntry.getKey();
+ if (!ObjcProvider.STRICT_DEPENDENCY_KEYS.contains(key)) {
+ throw badDirectDependencyKeyError(key);
+ }
+ uncheckedAddTransitive(key, typeEntry.getValue(), this.strictDependencyItems);
}
for (Map.Entry<Key<?>, NestedSet<?>> typeEntry : provider.strictDependencyItems.entrySet()) {
- uncheckedAddTransitive(typeEntry.getKey(), typeEntry.getValue(), this.nonPropagatedItems);
+ Key<?> key = typeEntry.getKey();
+ if (!ObjcProvider.STRICT_DEPENDENCY_KEYS.contains(key)) {
+ throw badDirectDependencyKeyError(key);
+ }
+ uncheckedAddTransitive(key, typeEntry.getValue(), this.nonPropagatedItems);
}
return this;
}
@@ -1129,6 +1146,7 @@
* Add elements in toAdd, and do not propagate to dependents of this provider.
*/
public <E> Builder addAllNonPropagable(Key<E> key, Iterable<? extends E> toAdd) {
+ Preconditions.checkState(ObjcProvider.STRICT_DEPENDENCY_KEYS.contains(key));
uncheckedAddAll(key, toAdd, this.nonPropagatedItems);
return this;
}
@@ -1137,6 +1155,7 @@
* Add element toAdd, and propagate it only to direct dependents of this provider.
*/
public <E> Builder addForDirectDependents(Key<E> key, E toAdd) {
+ Preconditions.checkState(ObjcProvider.STRICT_DEPENDENCY_KEYS.contains(key));
uncheckedAddAll(key, ImmutableList.of(toAdd), this.strictDependencyItems);
return this;
}
@@ -1145,6 +1164,7 @@
* Add elements in toAdd, and propagate them only to direct dependents of this provider.
*/
public <E> Builder addAllForDirectDependents(Key<E> key, Iterable<? extends E> toAdd) {
+ Preconditions.checkState(ObjcProvider.STRICT_DEPENDENCY_KEYS.contains(key));
uncheckedAddAll(key, toAdd, this.strictDependencyItems);
return this;
}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
index 49b5019..3043343 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/ObjcSkylarkTest.java
@@ -1008,6 +1008,24 @@
}
@Test
+ public void testSkylarkStrictDepsWhitelist() throws Exception {
+ AssertionError e =
+ assertThrows(
+ AssertionError.class,
+ () ->
+ createObjcProviderSkylarkTarget(
+ " strict_defines = depset(['def1'])",
+ " strict_provider = apple_common.new_objc_provider\\",
+ "(define=strict_defines)",
+ " created_provider = apple_common.new_objc_provider\\",
+ "(direct_dep_providers=[strict_provider])",
+ " return [created_provider]"));
+ assertThat(e)
+ .hasMessageThat()
+ .contains(String.format(AppleSkylarkCommon.BAD_DIRECT_DEPENDENCY_KEY_ERROR, "define"));
+ }
+
+ @Test
public void testSkylarkCanCreateObjcProviderFromObjcProvider() throws Exception {
ConfiguredTarget skylarkTarget =
createObjcProviderSkylarkTarget(