diff options
3 files changed, 49 insertions, 6 deletions
diff --git a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html index ed26e6198f..8d3efe9b94 100644 --- a/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html +++ b/src/main/java/com/google/devtools/build/docgen/templates/attributes/common/testonly.html @@ -16,12 +16,6 @@ are <code>testonly</code> by default. </p> <p> -By virtue of -<a href="${link package.default_testonly}"><code>default_testonly</code></a>, -targets under <code>javatests</code> are <code>testonly</code> by default. -</p> - -<p> This attribute is intended to mean that the target should not be contained in binaries that are released to production. </p> 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 0fae32d39c..44d194dedd 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 @@ -77,6 +77,7 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.ideinfo.AndroidStudioInfoAspect; import com.google.devtools.build.lib.ideinfo.BazelAndroidStudioInfoSemantics; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper; import com.google.devtools.build.lib.packages.PackageGroup; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; @@ -153,6 +154,7 @@ import com.google.devtools.build.lib.rules.repository.BindRule; import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule; import com.google.devtools.build.lib.rules.repository.NewLocalRepositoryRule; import com.google.devtools.build.lib.rules.repository.WorkspaceBaseRule; +import com.google.devtools.build.lib.syntax.Type; import com.google.devtools.build.lib.util.ResourceFileLoader; import java.io.IOException; @@ -188,6 +190,7 @@ public class BazelRuleClassProvider { public void validate(RuleContext.Builder context, ConfiguredTarget prerequisite, Attribute attribute) { validateDirectPrerequisiteVisibility(context, prerequisite, attribute.getName()); + validateDirectPrerequisiteForTestOnly(context, prerequisite); DeprecationValidator.validateDirectPrerequisiteForDeprecation( context, context.getRule(), prerequisite, context.forAspect()); } @@ -236,6 +239,29 @@ public class BazelRuleClassProvider { + "(they are only allowed in the visibility attribute)"); } } + + private void validateDirectPrerequisiteForTestOnly( + RuleContext.Builder context, ConfiguredTarget prerequisite) { + Rule rule = context.getRule(); + Target prerequisiteTarget = prerequisite.getTarget(); + Label prerequisiteLabel = prerequisiteTarget.getLabel(); + String thisPackage = rule.getLabel().getPackageName(); + + if (isTestOnlyRule(prerequisiteTarget) && !isTestOnlyRule(rule)) { + String message = "non-test target '" + rule.getLabel() + "' depends on testonly target '" + + prerequisiteLabel + "' and doesn't have testonly attribute set"; + if (thisPackage.startsWith("experimental/")) { + context.ruleWarning(message); + } else { + context.ruleError(message); + } + } + } + + private static boolean isTestOnlyRule(Target target) { + return (target instanceof Rule) + && (NonconfigurableAttributeMapper.of((Rule) target)).get("testonly", Type.BOOLEAN); + } } public static void setup(ConfiguredRuleClassProvider.Builder builder) { diff --git a/src/test/shell/bazel/bazel_test_test.sh b/src/test/shell/bazel/bazel_test_test.sh index 073a3a6949..b82562d6e7 100755 --- a/src/test/shell/bazel/bazel_test_test.sh +++ b/src/test/shell/bazel/bazel_test_test.sh @@ -293,6 +293,29 @@ EOF [ -s $xml_log ] || fail "$xml_log was not present after test" } +# Simple test that we actually enforce testonly, see #1923. +function test_testonly_is_enforced() { + mkdir -p testonly + cat <<'EOF' >testonly/BUILD +genrule( + name = "testonly", + srcs = [], + cmd = "echo testonly | tee $@", + outs = ["testonly.txt"], + testonly = 1, +) +genrule( + name = "not-testonly", + srcs = [":testonly"], + cmd = "echo should fail | tee $@", + outs = ["not-testonly.txt"], +) +EOF + bazel build //testonly &>$TEST_log || fail "Building //testonly failed" + bazel build //testonly:not-testonly &>$TEST_log && fail "Should have failed" || true + expect_log "'//testonly:not-testonly' depends on testonly target '//testonly:testonly'" +} + function test_always_xml_output() { mkdir -p dir |