aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis/whitelisting
diff options
context:
space:
mode:
authorGravatar plf <plf@google.com>2017-07-26 15:43:59 +0200
committerGravatar Jakob Buchgraber <buchgr@google.com>2017-07-26 16:22:28 +0200
commitb344e2c5a97b0eeacb796db20bb894f21283d358 (patch)
treef9c10b7fcf10bba3ce6f5a3b2da9fd45397451f3 /src/main/java/com/google/devtools/build/lib/analysis/whitelisting
parent2f8b1e519ccc4ead62be57d245d559029265a9a7 (diff)
Package whitelisting: New implementation for feature whitelisting
This builds on top of mstaib's idea to use package groups to whitelist projects which can use certain features in the analysis phase. Instead of using configurations and a flag, this way of implementing whitelists requires using two helper methods, one that adds an implicit attribute to every rule that has functionality that must be whitelisted and a different method to check whether a given package is whitelisted to use that feature. RELNOTES:none PiperOrigin-RevId: 163200890
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis/whitelisting')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD26
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/whitelisting/Whitelist.java80
2 files changed, 106 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD b/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD
new file mode 100644
index 0000000000..b31e3c224b
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/BUILD
@@ -0,0 +1,26 @@
+# Description:
+# Whitelisting mechanism for rolling out and deprecating pieces of Bazel functionality.
+
+package(
+ default_visibility = ["//src:__subpackages__"],
+)
+
+filegroup(
+ name = "srcs",
+ srcs = glob(["**"]),
+)
+
+java_library(
+ name = "whitelisting",
+ srcs = glob(["*.java"]),
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib:build-base",
+ "//src/main/java/com/google/devtools/build/lib:packages-internal",
+ "//src/main/java/com/google/devtools/build/lib:preconditions",
+ "//src/main/java/com/google/devtools/build/lib/cmdline",
+ "//src/main/java/com/google/devtools/common/options",
+ "//third_party:auto_value",
+ "//third_party:guava",
+ "//third_party:jsr305",
+ ],
+)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/Whitelist.java b/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/Whitelist.java
new file mode 100644
index 0000000000..0da6e4d362
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/whitelisting/Whitelist.java
@@ -0,0 +1,80 @@
+// 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.analysis.whitelisting;
+
+import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST;
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.BuildType.LABEL;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.PackageSpecificationProvider;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
+import com.google.devtools.build.lib.analysis.RuleContext;
+import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.Attribute;
+import com.google.devtools.build.lib.util.Preconditions;
+
+/**
+ * Class used for implementing whitelists using package groups.
+ *
+ * <p>To use add an attribute {@link getAttributeFromWhitelistName(String,Label) to the rule class
+ * which needs the whitelisting mechanism and use {@link isAvailable(RuleContext,String)} to check
+ * during analysis if a rule is present
+ */
+public final class Whitelist {
+
+ private Whitelist() {}
+
+ /**
+ * Returns an Attribute.Builder that can be used to add an implicit attribute to a rule containing
+ * a package group whitelist.
+ *
+ * @param whitelistName The name of the whitelist. This has to comply with attribute naming
+ * standards and will be used as a suffix for the attribute name.
+ * @param packageGroupWhitelist Label for the package group with the whitelist.
+ */
+ public static Attribute.Builder<Label> getAttributeFromWhitelistName(
+ String whitelistName, Label packageGroupWhitelist) {
+ String attributeName = getAttributeNameFromWhitelistName(whitelistName);
+ return attr(attributeName, LABEL)
+ .value(packageGroupWhitelist)
+ .cfg(HOST)
+ .mandatoryNativeProviders(ImmutableList.of(PackageSpecificationProvider.class));
+ }
+
+ /**
+ * Returns whether the rule in the given RuleContext is in a whitelist.
+ *
+ * @param ruleContext The context in which this check is being executed.
+ * @param whitelistName The name of the whitelist being used.
+ */
+ public static boolean isAvailable(RuleContext ruleContext, String whitelistName) {
+ String attributeName = getAttributeNameFromWhitelistName(whitelistName);
+ Preconditions.checkArgument(ruleContext.isAttrDefined(attributeName, LABEL));
+ TransitiveInfoCollection packageGroup = ruleContext.getPrerequisite(attributeName, Mode.HOST);
+ Label label = ruleContext.getLabel();
+ return packageGroup
+ .getProvider(PackageSpecificationProvider.class)
+ .getPackageSpecifications()
+ .toList()
+ .stream()
+ .anyMatch(p -> p.containsPackage(label.getPackageIdentifier()));
+ }
+
+ private static String getAttributeNameFromWhitelistName(String whitelistName) {
+ return String.format("$whitelist_%s", whitelistName);
+ }
+}