Add --incompatible_disable_third_party_license_checking.
This flag makes all license-related BUILD syntax no-ops.
After this flag is permanently turned on in Bazel, we can start
stripping out the syntax.
This is unfortunately complex because it has to coherently interplay
with the related flag --check_third_party_targets_have_licenses.
See #7444 and #7553.
PiperOrigin-RevId: 235779781
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index f24fb4d..56ce67b 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -49,6 +49,7 @@
import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.packages.RuleTransitionFactory;
@@ -261,6 +262,9 @@
(BuildOptions options) -> ActionEnvironment.EMPTY;
private ConstraintSemantics constraintSemantics = new ConstraintSemantics();
+ private ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy =
+ ThirdPartyLicenseExistencePolicy.USER_CONTROLLABLE;
+
public Builder addWorkspaceFilePrefix(String contents) {
defaultWorkspaceFilePrefix.append(contents);
return this;
@@ -385,6 +389,15 @@
}
/**
+ * Sets the policy for checking if third_party rules declare <code>licenses()</code>. See {@link
+ * #thirdPartyLicenseExistencePolicy} for the default value.
+ */
+ public Builder setThirdPartyLicenseExistencePolicy(ThirdPartyLicenseExistencePolicy policy) {
+ this.thirdPartyLicenseExistencePolicy = policy;
+ return this;
+ }
+
+ /**
* Adds a transition factory that produces a trimming transition to be run over all targets
* after other transitions.
*
@@ -486,6 +499,7 @@
RuleClass.Builder builder = new RuleClass.Builder(
metadata.name(), metadata.type(), false, ancestorClasses);
builder.factory(factory);
+ builder.setThirdPartyLicenseExistencePolicy(thirdPartyLicenseExistencePolicy);
RuleClass ruleClass = instance.build(builder, this);
ruleMap.put(definitionClass, ruleClass);
ruleClassMap.put(ruleClass.getName(), ruleClass);
@@ -520,7 +534,8 @@
skylarkBootstraps.build(),
ImmutableSet.copyOf(reservedActionMnemonics),
actionEnvironmentProvider,
- constraintSemantics);
+ constraintSemantics,
+ thirdPartyLicenseExistencePolicy);
}
@Override
@@ -609,6 +624,8 @@
private final ConstraintSemantics constraintSemantics;
+ private final ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy;
+
private ConfiguredRuleClassProvider(
Label preludeLabel,
String runfilesPrefix,
@@ -629,7 +646,8 @@
ImmutableList<Bootstrap> skylarkBootstraps,
ImmutableSet<String> reservedActionMnemonics,
BuildConfiguration.ActionEnvironmentProvider actionEnvironmentProvider,
- ConstraintSemantics constraintSemantics) {
+ ConstraintSemantics constraintSemantics,
+ ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy) {
this.preludeLabel = preludeLabel;
this.runfilesPrefix = runfilesPrefix;
this.toolsRepository = toolsRepository;
@@ -650,6 +668,7 @@
this.actionEnvironmentProvider = actionEnvironmentProvider;
this.configurationFragmentMap = createFragmentMap(configurationFragmentFactories);
this.constraintSemantics = constraintSemantics;
+ this.thirdPartyLicenseExistencePolicy = thirdPartyLicenseExistencePolicy;
}
public PrerequisiteValidator getPrerequisiteValidator() {
@@ -841,6 +860,11 @@
return constraintSemantics;
}
+ @Override
+ public ThirdPartyLicenseExistencePolicy getThirdPartyLicenseExistencePolicy() {
+ return thirdPartyLicenseExistencePolicy;
+ }
+
/** Returns all skylark objects in global scope for this RuleClassProvider. */
public Map<String, Object> getTransitiveGlobalBindings() {
return globals.getTransitiveBindings();
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/LicenseCheckingModule.java b/src/main/java/com/google/devtools/build/lib/bazel/LicenseCheckingModule.java
index 869b9a0..6cb5025 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/LicenseCheckingModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/LicenseCheckingModule.java
@@ -38,6 +38,7 @@
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Rule;
+import com.google.devtools.build.lib.packages.StarlarkSemanticsOptions;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.profiler.ProfilePhase;
@@ -56,7 +57,11 @@
*/
public class LicenseCheckingModule extends BlazeModule {
- private boolean shouldCheckLicenses(BuildOptions buildOptions) {
+ protected boolean shouldCheckLicenses(BuildRequest request, BuildOptions buildOptions) {
+ if (request.getOptions(StarlarkSemanticsOptions.class)
+ .incompatibleDisableThirdPartyLicenseChecking) {
+ return false;
+ }
return buildOptions.get(BuildConfiguration.Options.class).checkLicenses;
}
@@ -71,7 +76,7 @@
// We check licenses if the first target configuration has license checking enabled. Right
// now, it is not possible to have multiple target configurations with different settings
// for this flag, which allows us to take this short cut.
- if (shouldCheckLicenses(buildOptions)) {
+ if (shouldCheckLicenses(request, buildOptions)) {
Profiler.instance().markPhase(ProfilePhase.LICENSE);
try (SilentCloseable c = Profiler.instance().profile("validateLicensingForTargets")) {
validateLicensingForTargets(env, configuredTargets, request.getKeepGoing());
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
index 223b932..dea4426 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java
@@ -187,6 +187,9 @@
public static ConfiguredRuleClassProvider create() {
ConfiguredRuleClassProvider.Builder builder = new ConfiguredRuleClassProvider.Builder();
builder.setToolsRepository(TOOLS_REPOSITORY);
+ // TODO(gregce): uncomment the below line in the same change that retires
+ // --incompatible_disable_third_party_license_checking. See the flag's comments for details.
+ // builder.setThirdPartyLicenseExistencePolicy(ThirdPartyLicenseExistencePolicy.NEVER_CHECK);
setup(builder);
return builder.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Package.java b/src/main/java/com/google/devtools/build/lib/packages/Package.java
index a6f55ec..290883b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Package.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Package.java
@@ -36,6 +36,7 @@
import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.License.DistributionType;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.skyframe.serialization.DeserializationContext;
import com.google.devtools.build.lib.skyframe.serialization.ObjectCodec;
import com.google.devtools.build.lib.skyframe.serialization.SerializationContext;
@@ -837,6 +838,9 @@
private final List<String> registeredExecutionPlatforms = new ArrayList<>();
private final List<String> registeredToolchains = new ArrayList<>();
+ private ThirdPartyLicenseExistencePolicy thirdPartyLicenceExistencePolicy =
+ ThirdPartyLicenseExistencePolicy.USER_CONTROLLABLE;
+
/**
* True iff the "package" function has already been called in this package.
*/
@@ -1016,6 +1020,15 @@
return this;
}
+ public Builder setThirdPartyLicenceExistencePolicy(ThirdPartyLicenseExistencePolicy policy) {
+ this.thirdPartyLicenceExistencePolicy = policy;
+ return this;
+ }
+
+ public ThirdPartyLicenseExistencePolicy getThirdPartyLicenseExistencePolicy() {
+ return thirdPartyLicenceExistencePolicy;
+ }
+
/**
* Returns whether the "package" function has been called yet
*/
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 5887300..a7d83c6 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -36,6 +36,7 @@
import com.google.devtools.build.lib.events.StoredEventHandler;
import com.google.devtools.build.lib.packages.Globber.BadGlobException;
import com.google.devtools.build.lib.packages.License.DistributionType;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
@@ -735,7 +736,23 @@
String.format("licenses for exported file '%s' declared twice",
inputFile.getName()));
}
- if (env.getSemantics().checkThirdPartyTargetsHaveLicenses()
+
+ // See if we should check third-party licenses: first checking for any hard-coded policy,
+ // then falling back to user-settable flags.
+ boolean checkLicenses;
+ if (pkgBuilder.getThirdPartyLicenseExistencePolicy()
+ == ThirdPartyLicenseExistencePolicy.ALWAYS_CHECK) {
+ checkLicenses = true;
+ } else if (pkgBuilder.getThirdPartyLicenseExistencePolicy()
+ == ThirdPartyLicenseExistencePolicy.NEVER_CHECK) {
+ checkLicenses = false;
+ } else {
+ checkLicenses =
+ env.getSemantics().checkThirdPartyTargetsHaveLicenses()
+ && !env.getSemantics().incompatibleDisableThirdPartyLicenseChecking();
+ }
+
+ if (checkLicenses
&& license == null
&& !pkgBuilder.getDefaultLicense().isSpecified()
&& RuleClass.isThirdPartyPackage(pkgBuilder.getPackageIdentifier())) {
@@ -1666,6 +1683,9 @@
pkgBuilder.setContainsErrors();
}
+ pkgBuilder.setThirdPartyLicenceExistencePolicy(
+ ruleClassProvider.getThirdPartyLicenseExistencePolicy());
+
if (maxDirectoriesToEagerlyVisitInGlobbing == -2) {
GlobPatternExtractor extractor = new GlobPatternExtractor();
extractor.visit(buildFileAST);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 7f96fc4..a71cdaa 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -48,6 +48,7 @@
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleFactory.AttributeValues;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
@@ -671,6 +672,31 @@
private boolean supportsConstraintChecking = true;
+ /**
+ * The policy on whether Bazel should enforce that third_party rules declare <code>licenses().
+ * </code>. This is only intended for the migration of <a
+ * href="https://github.com/bazelbuild/bazel/issues/7444">GitHub #7444</a>. Our final end state
+ * is to have no license-related logic whatsoever. But that's going to take some time.
+ */
+ public enum ThirdPartyLicenseExistencePolicy {
+ /**
+ * Always do this check, overriding whatever {@link
+ * StarlarkSemanticsOptions#checkThirdPartyTargetsHaveLicenses} says.
+ */
+ ALWAYS_CHECK,
+
+ /**
+ * Never do this check, overriding whatever {@link
+ * StarlarkSemanticsOptions#checkThirdPartyTargetsHaveLicenses} says.
+ */
+ NEVER_CHECK,
+
+ /** Do whatever {@link StarlarkSemanticsOptions#checkThirdPartyTargetsHaveLicenses} says. */
+ USER_CONTROLLABLE
+ }
+
+ private ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy;
+
private final Map<String, Attribute> attributes = new LinkedHashMap<>();
private final Set<Label> requiredToolchains = new HashSet<>();
private boolean supportsPlatforms = true;
@@ -826,6 +852,7 @@
ruleDefinitionEnvironmentHashCode,
configurationFragmentPolicy.build(),
supportsConstraintChecking,
+ thirdPartyLicenseExistencePolicy,
requiredToolchains,
supportsPlatforms,
executionPlatformConstraintsAllowed,
@@ -1026,6 +1053,11 @@
return this;
}
+ public Builder setThirdPartyLicenseExistencePolicy(ThirdPartyLicenseExistencePolicy policy) {
+ this.thirdPartyLicenseExistencePolicy = policy;
+ return this;
+ }
+
public Builder setValidityPredicate(PredicateWithMessage<Rule> predicate) {
this.validityPredicate = predicate;
return this;
@@ -1497,6 +1529,8 @@
*/
private final boolean supportsConstraintChecking;
+ private final ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy;
+
private final ImmutableSet<Label> requiredToolchains;
private final boolean supportsPlatforms;
private final ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed;
@@ -1552,6 +1586,7 @@
String ruleDefinitionEnvironmentHashCode,
ConfigurationFragmentPolicy configurationFragmentPolicy,
boolean supportsConstraintChecking,
+ ThirdPartyLicenseExistencePolicy thirdPartyLicenseExistencePolicy,
Set<Label> requiredToolchains,
boolean supportsPlatforms,
ExecutionPlatformConstraintsAllowed executionPlatformConstraintsAllowed,
@@ -1591,6 +1626,7 @@
this.ignorePackageLicenses = ignorePackageLicenses;
this.configurationFragmentPolicy = configurationFragmentPolicy;
this.supportsConstraintChecking = supportsConstraintChecking;
+ this.thirdPartyLicenseExistencePolicy = thirdPartyLicenseExistencePolicy;
this.requiredToolchains = ImmutableSet.copyOf(requiredToolchains);
this.supportsPlatforms = supportsPlatforms;
this.executionPlatformConstraintsAllowed = executionPlatformConstraintsAllowed;
@@ -1835,7 +1871,17 @@
populateAttributeLocations(rule, ast);
}
checkForDuplicateLabels(rule, eventHandler);
- if (checkThirdPartyRulesHaveLicenses) {
+
+ boolean actuallyCheckLicense;
+ if (thirdPartyLicenseExistencePolicy == ThirdPartyLicenseExistencePolicy.ALWAYS_CHECK) {
+ actuallyCheckLicense = true;
+ } else if (thirdPartyLicenseExistencePolicy == ThirdPartyLicenseExistencePolicy.NEVER_CHECK) {
+ actuallyCheckLicense = false;
+ } else {
+ actuallyCheckLicense = checkThirdPartyRulesHaveLicenses;
+ }
+
+ if (actuallyCheckLicense) {
checkThirdPartyRuleHasLicense(rule, pkgBuilder, eventHandler);
}
checkForValidSizeAndTimeoutValues(rule, eventHandler);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
index e4cedd4..49b830e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
@@ -18,6 +18,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Extension;
import com.google.devtools.build.lib.syntax.Mutability;
@@ -103,4 +104,7 @@
* class.
*/
Map<String, Class<?>> getConfigurationFragmentMap();
+
+ /** Returns the policy on checking that third-party rules have licenses. */
+ ThirdPartyLicenseExistencePolicy getThirdPartyLicenseExistencePolicy();
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
index 1bbb1de..efea73a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
@@ -128,6 +128,20 @@
AttributesAndLocation generator =
generatorAttributesForMacros(attributeValues, env, location, label);
try {
+ // Examines --check_third_party_targets_have_licenses and
+ // --incompatible_disable_third_party_license_checking to see if we should check third_party
+ // targets for license existence. The latter flag overrides the former.
+ //
+ // Note that *both* flags are overridable by RuleClass.ThirdPartyLicenseEnforcementPolicy
+ // (which is checked in RuleClass). This lets Bazel and Blaze migrate away from license logic
+ // on independent timelines. See --incompatible_disable_third_party_license_checking comments
+ // for details.
+ boolean checkThirdPartyLicenses;
+ if (env == null || env.getSemantics().incompatibleDisableThirdPartyLicenseChecking()) {
+ checkThirdPartyLicenses = false;
+ } else {
+ checkThirdPartyLicenses = env.getSemantics().checkThirdPartyTargetsHaveLicenses();
+ }
return ruleClass.createRule(
pkgBuilder,
label,
@@ -136,7 +150,7 @@
ast,
generator.location,
attributeContainer,
- env == null ? false : env.getSemantics().checkThirdPartyTargetsHaveLicenses());
+ checkThirdPartyLicenses);
} catch (LabelSyntaxException | CannotPrecomputeDefaultsException e) {
throw new RuleFactory.InvalidRuleException(ruleClass + " " + e.getMessage());
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
index 18883dc..3d639c0 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/StarlarkSemanticsOptions.java
@@ -60,8 +60,10 @@
// <== Add new options here in alphabetic order ==>
- // TODO(gregce): remove license checking completely from Bazel. aiuto@ is working on replacing
- // this with a new and more useful model.
+ /**
+ * This can be overridden by {@link RuleClass.Builder.ThirdPartyLicenseExistencePolicy} and {@link
+ * #incompatibleDisableThirdPartyLicenseChecking}.
+ */
@Option(
name = "check_third_party_targets_have_licenses",
defaultValue = "true",
@@ -244,6 +246,36 @@
help = "If set to true, disallow use of deprecated resource fields on the Objc provider.")
public boolean incompatibleDisableObjcProviderResources;
+ // Once this migration is complete, instead of removing this flag we need to make it a no-op.
+ // This is because we'll need to keep it around for a while so Google's migration can complete
+ // after Bazel's. This is an example of Bazel's Google roots being methodically torn out:
+ // because this functionality was introduced for Google before Bazel existed, Google's
+ // dependency on it is deeper. We don't want this to add unnecessary baggage to Bazel or slow
+ // down Bazel's development. So this approach, while slightly awkward, relieves Bazel of
+ // Google's technical debt (which shouldn't be Bazel's problem). This means you as a Bazel
+ // user are getting better code than Google has! (for a while, at least)
+ //
+ // Track migration at https://github.com/bazelbuild/bazel/issues/7444. When we're ready to
+ // remove Bazel support, instead of removing the flag we should do these things:
+ //
+ // 1) BazelRuleClassProvider: set the third party license existence policy to NEVER_CHECK (see
+ // the related TODO(gregce) comment in that file).
+ // 2) Remove LicenseCheckingModule.
+ // 3) Remove --check_third_party_targets_have_licenses.
+ @Option(
+ name = "incompatible_disable_third_party_license_checking",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
+ effectTags = OptionEffectTag.BUILD_FILE_SEMANTICS,
+ metadataTags = {
+ OptionMetadataTag.INCOMPATIBLE_CHANGE,
+ OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+ },
+ help =
+ "If true, disables all license checking logic. This overrides "
+ + "--check_third_party_targets_have_licenses")
+ public boolean incompatibleDisableThirdPartyLicenseChecking;
+
@Option(
name = "incompatible_disallow_data_transition",
defaultValue = "true",
@@ -537,6 +569,7 @@
.incompatibleBzlDisallowLoadAfterStatement(incompatibleBzlDisallowLoadAfterStatement)
.incompatibleDepsetIsNotIterable(incompatibleDepsetIsNotIterable)
.incompatibleDepsetUnion(incompatibleDepsetUnion)
+ .incompatibleDisableThirdPartyLicenseChecking(incompatibleDisableThirdPartyLicenseChecking)
.incompatibleDisableDeprecatedAttrParams(incompatibleDisableDeprecatedAttrParams)
.incompatibleDisableObjcProviderResources(incompatibleDisableObjcProviderResources)
.incompatibleDisallowDataTransition(incompatibleDisallowDataTransition)
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
index 775289e..b66b6ac 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StarlarkSemantics.java
@@ -139,6 +139,8 @@
public abstract boolean incompatibleDepsetUnion();
+ public abstract boolean incompatibleDisableThirdPartyLicenseChecking();
+
public abstract boolean incompatibleDisableDeprecatedAttrParams();
public abstract boolean incompatibleDisableObjcProviderResources();
@@ -215,6 +217,7 @@
.incompatibleBzlDisallowLoadAfterStatement(false)
.incompatibleDepsetIsNotIterable(false)
.incompatibleDepsetUnion(false)
+ .incompatibleDisableThirdPartyLicenseChecking(false)
.incompatibleDisableDeprecatedAttrParams(false)
.incompatibleDisableObjcProviderResources(false)
.incompatibleDisallowDataTransition(true)
@@ -269,6 +272,8 @@
public abstract Builder incompatibleDepsetUnion(boolean value);
+ public abstract Builder incompatibleDisableThirdPartyLicenseChecking(boolean value);
+
public abstract Builder incompatibleDisableDeprecatedAttrParams(boolean value);
public abstract Builder incompatibleRequireFeatureConfigurationForPic(boolean value);
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
index 4cbb2fe..122c7ff 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -50,6 +50,7 @@
import com.google.devtools.build.lib.packages.Attribute.ValidityPredicate;
import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
+import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory;
import com.google.devtools.build.lib.packages.RuleClass.ExecutionPlatformConstraintsAllowed;
import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
@@ -910,6 +911,7 @@
.setMissingFragmentPolicy(missingFragmentPolicy)
.build(),
supportsConstraintChecking,
+ ThirdPartyLicenseExistencePolicy.USER_CONTROLLABLE,
/*requiredToolchains=*/ ImmutableSet.of(),
/*supportsPlatforms=*/ true,
ExecutionPlatformConstraintsAllowed.PER_RULE,
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index 70dde2c..34fe7a5 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -138,6 +138,7 @@
"--incompatible_depset_union=" + rand.nextBoolean(),
"--incompatible_disable_deprecated_attr_params=" + rand.nextBoolean(),
"--incompatible_disable_objc_provider_resources=" + rand.nextBoolean(),
+ "--incompatible_disable_third_party_license_checking=" + rand.nextBoolean(),
"--incompatible_disallow_data_transition=" + rand.nextBoolean(),
"--incompatible_disallow_dict_plus=" + rand.nextBoolean(),
"--incompatible_disallow_filetype=" + rand.nextBoolean(),
@@ -185,6 +186,7 @@
.incompatibleDepsetUnion(rand.nextBoolean())
.incompatibleDisableDeprecatedAttrParams(rand.nextBoolean())
.incompatibleDisableObjcProviderResources(rand.nextBoolean())
+ .incompatibleDisableThirdPartyLicenseChecking(rand.nextBoolean())
.incompatibleDisallowDataTransition(rand.nextBoolean())
.incompatibleDisallowDictPlus(rand.nextBoolean())
.incompatibleDisallowFileType(rand.nextBoolean())
diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD
index 885836b..c07eba8 100644
--- a/src/test/shell/bazel/BUILD
+++ b/src/test/shell/bazel/BUILD
@@ -647,6 +647,14 @@
)
sh_test(
+ name = "license_checking_test",
+ size = "medium",
+ srcs = ["license_checking_test.sh"],
+ data = [":test-deps"],
+ tags = ["no_windows"],
+)
+
+sh_test(
name = "bazel_bootstrap_distfile_test",
timeout = "eternal",
srcs = ["bazel_bootstrap_distfile_test.sh"],
diff --git a/src/test/shell/bazel/license_checking_test.sh b/src/test/shell/bazel/license_checking_test.sh
new file mode 100755
index 0000000..95526f0
--- /dev/null
+++ b/src/test/shell/bazel/license_checking_test.sh
@@ -0,0 +1,109 @@
+#!/bin/bash
+#
+# Copyright 2019 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.
+#
+# Tests Bazel's license checking semantics.
+#
+# This is a temporary test supporting the migration away from any license
+# checking at all. When https://github.com/bazelbuild/bazel/issues/7444 is
+# fixed this test can be deleted.
+
+# Load the test setup defined in the parent directory
+CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "${CURRENT_DIR}/../integration_test_setup.sh" \
+ || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+function write_rules {
+ mkdir -p third_party/restrictive
+ cat <<EOF > third_party/restrictive/BUILD
+licenses(['restricted'])
+genrule(
+ name = 'lib',
+ srcs = [],
+ outs = ['lib.out'],
+ cmd = 'echo hi > $@',
+ licenses = ['restricted'],
+ visibility = ['//bad:__pkg__']
+)
+exports_files(['file'])
+EOF
+
+ mkdir -p bad
+ cat <<EOF > bad/BUILD
+distribs(['client'])
+genrule(
+ name = 'main',
+ srcs = [],
+ outs = ['bad.out'],
+ tools = ['//third_party/restrictive:lib'],
+ cmd = 'echo hi > $@'
+)
+EOF
+
+ mkdir -p third_party/missing_license
+ cat <<EOF > third_party/missing_license/BUILD
+genrule(
+ name = 'lib',
+ srcs = [],
+ outs = ['lib.out'],
+ cmd = 'echo hi > $@'
+)
+exports_files(['file'])
+EOF
+}
+
+function test_default_mode {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //bad:main >& $TEST_log || fail "build should succeed"
+}
+
+function test_license_checking {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //bad:main --check_licenses >& $TEST_log && fail "build shouldn't succeed"
+ expect_log "Build target '//bad:main' is not compatible with license '\[restricted\]' from target '//third_party/restrictive:lib'"
+}
+
+function test_disable_license_checking_override {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //bad:main --check_licenses --incompatible_disable_third_party_license_checking \
+ >& $TEST_log || fail "build should succeed"
+}
+
+function test_third_party_no_license_is_checked {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //third_party/missing_license:lib >& $TEST_log && fail "build shouldn't succeed"
+ expect_log "third-party rule '//third_party/missing_license:lib' lacks a license declaration"
+}
+
+function test_third_party_no_license_no_check {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //third_party/missing_license:lib --nocheck_third_party_targets_have_licenses \
+ || fail "build should succeed"
+}
+
+function test_third_party_no_license_disable_license_checking_override {
+ create_new_workspace
+ write_rules
+ bazel build --nobuild //third_party/missing_license:lib --incompatible_disable_third_party_license_checking \
+ || fail "build should succeed"
+}
+
+run_suite "license checking tests"
+