@@ -1066,4 +1066,163 @@ function test_aquery_incompatible_target() {
10661066 expect_log "target platform (//target_skipping:foo3_platform) didn't satisfy constraint //target_skipping:foo1"
10671067}
10681068
1069+ # Use aspects to interact with incompatible targets and validate the behaviour.
1070+ function test_aspect_skipping() {
1071+ cat >> target_skipping/BUILD <<EOF
1072+ load(":defs.bzl", "basic_rule", "rule_with_aspect")
1073+ # This target is compatible with all platforms and configurations. This target
1074+ # exists to validate the behaviour of aspects running against incompatible
1075+ # targets. The expectation is that the aspect should _not_ propagate to this
1076+ # compatible target from an incomaptible target. I.e. an aspect should _not_
1077+ # evaluate this target if "basic_foo3_target" is incompatible.
1078+ basic_rule(
1079+ name = "basic_universal_target",
1080+ )
1081+ # An alias to validate that incompatible target skipping works as expected with
1082+ # aliases and aspects.
1083+ alias(
1084+ name = "aliased_basic_universal_target",
1085+ actual = ":basic_universal_target",
1086+ )
1087+ basic_rule(
1088+ name = "basic_foo3_target",
1089+ deps = [
1090+ ":aliased_basic_universal_target",
1091+ ],
1092+ target_compatible_with = [
1093+ ":foo3",
1094+ ],
1095+ )
1096+ # This target is only compatible when "basic_foo3_target" is compatible. This
1097+ # target exists to validate the behaviour of aspects running against
1098+ # incompatible targets. The expectation is that the aspect should _not_
1099+ # evaluate this target when "basic_foo3_target" is incompatible.
1100+ basic_rule(
1101+ name = "other_basic_target",
1102+ deps = [
1103+ ":basic_foo3_target",
1104+ ],
1105+ )
1106+ alias(
1107+ name = "aliased_other_basic_target",
1108+ actual = ":other_basic_target",
1109+ )
1110+ rule_with_aspect(
1111+ name = "inspected_foo3_target",
1112+ inspect = ":aliased_other_basic_target",
1113+ )
1114+ basic_rule(
1115+ name = "previously_inspected_basic_target",
1116+ deps = [
1117+ ":inspected_foo3_target",
1118+ ],
1119+ )
1120+ rule_with_aspect(
1121+ name = "twice_inspected_foo3_target",
1122+ inspect = ":previously_inspected_basic_target",
1123+ )
1124+ genrule(
1125+ name = "generated_file",
1126+ outs = ["generated_file.txt"],
1127+ cmd = "echo '' > \$ (OUTS)",
1128+ target_compatible_with = [
1129+ ":foo1",
1130+ ],
1131+ )
1132+ rule_with_aspect(
1133+ name = "inspected_generated_file",
1134+ inspect = ":generated_file",
1135+ )
1136+ EOF
1137+ cat > target_skipping/defs.bzl <<EOF
1138+ BasicProvider = provider()
1139+ def _basic_rule_impl(ctx):
1140+ return [DefaultInfo(), BasicProvider()]
1141+ basic_rule = rule(
1142+ implementation = _basic_rule_impl,
1143+ attrs = {
1144+ "deps": attr.label_list(
1145+ providers = [BasicProvider],
1146+ ),
1147+ },
1148+ )
1149+ def _inspecting_aspect_impl(target, ctx):
1150+ print("Running aspect on " + str(target))
1151+ return []
1152+ _inspecting_aspect = aspect(
1153+ implementation = _inspecting_aspect_impl,
1154+ attr_aspects = ["deps"],
1155+ )
1156+ def _rule_with_aspect_impl(ctx):
1157+ out = ctx.actions.declare_file(ctx.label.name)
1158+ ctx.actions.write(out, "")
1159+ return [
1160+ DefaultInfo(files=depset([out])),
1161+ BasicProvider(),
1162+ ]
1163+ rule_with_aspect = rule(
1164+ implementation = _rule_with_aspect_impl,
1165+ attrs = {
1166+ "inspect": attr.label(
1167+ aspects = [_inspecting_aspect],
1168+ ),
1169+ },
1170+ )
1171+ EOF
1172+ cd target_skipping || fail "couldn't cd into workspace"
1173+ local debug_message1="Running aspect on <target //target_skipping:basic_universal_target>"
1174+ local debug_message2="Running aspect on <target //target_skipping:basic_foo3_target>"
1175+ local debug_message3="Running aspect on <target //target_skipping:other_basic_target>"
1176+ local debug_message4="Running aspect on <target //target_skipping:previously_inspected_basic_target>"
1177+ local debug_message5="Running aspect on <target //target_skipping:generated_file>"
1178+ # Validate that aspects run against compatible targets.
1179+ bazel build \
1180+ --show_result=10 \
1181+ --host_platform=@//target_skipping:foo3_platform \
1182+ --platforms=@//target_skipping:foo3_platform \
1183+ //target_skipping:all &> "${TEST_log} " \
1184+ || fail "Bazel failed unexpectedly."
1185+ expect_log "${debug_message1} "
1186+ expect_log "${debug_message2} "
1187+ expect_log "${debug_message3} "
1188+ expect_log "${debug_message4} "
1189+ expect_not_log "${debug_message5} "
1190+ # Invert the compatibility and validate that aspects run on the other targets
1191+ # now.
1192+ bazel build \
1193+ --show_result=10 \
1194+ --host_platform=@//target_skipping:foo1_bar1_platform \
1195+ --platforms=@//target_skipping:foo1_bar1_platform \
1196+ //target_skipping:all &> "${TEST_log} " \
1197+ || fail "Bazel failed unexpectedly."
1198+ expect_not_log "${debug_message1} "
1199+ expect_not_log "${debug_message2} "
1200+ expect_not_log "${debug_message3} "
1201+ expect_not_log "${debug_message4} "
1202+ expect_log "${debug_message5} "
1203+ # Validate that explicitly trying to build a target with an aspect against an
1204+ # incompatible target produces the normal error message.
1205+ bazel build \
1206+ --show_result=10 \
1207+ --host_platform=@//target_skipping:foo1_bar1_platform \
1208+ --platforms=@//target_skipping:foo1_bar1_platform \
1209+ //target_skipping:twice_inspected_foo3_target &> "${TEST_log} " \
1210+ && fail "Bazel passed unexpectedly."
1211+ # TODO(#15427): Should use expect_log_once here when the issue is fixed.
1212+ expect_log 'ERROR: Target //target_skipping:twice_inspected_foo3_target is incompatible and cannot be built, but was explicitly requested.'
1213+ expect_log '^Dependency chain:$'
1214+ expect_log '^ //target_skipping:twice_inspected_foo3_target$'
1215+ expect_log '^ //target_skipping:previously_inspected_basic_target$'
1216+ expect_log '^ //target_skipping:inspected_foo3_target$'
1217+ expect_log '^ //target_skipping:aliased_other_basic_target$'
1218+ expect_log '^ //target_skipping:other_basic_target$'
1219+ expect_log " //target_skipping:basic_foo3_target <-- target platform (//target_skipping:foo1_bar1_platform) didn't satisfy constraint //target_skipping:foo3$"
1220+ expect_log 'FAILED: Build did NOT complete successfully'
1221+ expect_not_log "${debug_message1} "
1222+ expect_not_log "${debug_message2} "
1223+ expect_not_log "${debug_message3} "
1224+ expect_not_log "${debug_message4} "
1225+ expect_not_log "${debug_message5} "
1226+ }
1227+
10691228run_suite "target_compatible_with tests"
0 commit comments