Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

query: expose is_executable #15948

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy;
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.RuleClassType;
import com.google.devtools.build.lib.packages.TargetUtils;
Expand Down Expand Up @@ -208,6 +209,10 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
.add(attr("args", STRING_LIST))
.add(attr("env", STRING_DICT))
.add(attr("env_inherit", STRING_LIST))
.add(
attr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, BOOLEAN)
.value(true)
.nonconfigurable("Called from RunCommand.isExecutable, which takes a Target"))
// Input files for every test action
.add(
attr("$test_wrapper", LABEL)
Expand Down Expand Up @@ -500,7 +505,7 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
.add(attr("env", STRING_DICT))
.add(attr("output_licenses", LICENSE))
.add(
attr("$is_executable", BOOLEAN)
attr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, BOOLEAN)
.value(true)
.nonconfigurable("Called from RunCommand.isExecutable, which takes a Target"))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import com.google.devtools.build.lib.packages.MacroInstance;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PredicateWithMessage;
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.RuleClassType;
import com.google.devtools.build.lib.packages.RuleFactory;
Expand Down Expand Up @@ -170,7 +171,7 @@ public class StarlarkRuleClassFunctions implements StarlarkRuleFunctionsApi {
.add(attr("args", STRING_LIST))
.add(attr("output_licenses", LICENSE))
.addAttribute(
attr("$is_executable", BOOLEAN)
attr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, BOOLEAN)
.value(true)
.nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
.build())
Expand Down Expand Up @@ -268,7 +269,7 @@ public static RuleClass getTestBaseRule(RuleDefinitionEnvironment env) {
+ BaseRuleClasses.DEFAULT_COVERAGE_REPORT_GENERATOR_VALUE))))
.add(attr(":run_under", LABEL).value(RUN_UNDER))
.addAttribute(
attr("$is_executable", BOOLEAN)
attr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, BOOLEAN)
.value(true)
.nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
.build());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ public class Rule implements Target, DependencyFilter.AttributeInfoProvider {

private static final OutputFile[] NO_OUTPUTS = new OutputFile[0];

public static final String IS_EXECUTABLE_ATTRIBUTE_NAME = "$is_executable";

private final Package pkg;
private final Label label;
private final RuleClass ruleClass;
Expand Down Expand Up @@ -1281,6 +1283,13 @@ public boolean useToolchainResolution() {
}
}

public boolean isExecutable() {
if (getRuleClassObject().hasAttr(IS_EXECUTABLE_ATTRIBUTE_NAME, Type.BOOLEAN)) {
return NonconfigurableAttributeMapper.of(this).get(IS_EXECUTABLE_ATTRIBUTE_NAME, Type.BOOLEAN);
}
return false;
}

public RepositoryName getRepository() {
return label.getPackageIdentifier().getRepository();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.google.devtools.build.lib.packages.ProtoUtils;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.Type;
import com.google.devtools.build.lib.packages.Types;
import com.google.devtools.build.lib.query2.common.CommonQueryOptions;
Expand Down Expand Up @@ -201,6 +202,8 @@ public Build.Target toTargetProtoBuffer(
BaseEncoding.base16().lowerCase().encode(transitiveDigest))); // hexify
}

rulePb.setIsExecutable(rule.isExecutable());

ImmutableMap<Aspect, ImmutableMultimap<Attribute, Label>> aspectsDependencies =
aspectResolver.computeAspectDependencies(target, dependencyFilter);
if (!aspectsDependencies.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.BuildType;
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.RuleClassType;
import com.google.devtools.build.lib.util.FileTypeSet;
Expand Down Expand Up @@ -276,12 +277,13 @@ expanded to Windows style paths (with backslash).
attr("executable", BOOLEAN)
.value(false)
.nonconfigurable(
"Used in computed default for $is_executable, which is itself non-configurable"
"Used in computed default for " + Rule.IS_EXECUTABLE_ATTRIBUTE_NAME
+ " which is itself non-configurable"
+ " (and thus expects its dependencies to be non-configurable), because"
+ " $is_executable is called from RunCommand.isExecutable, which has no"
+ " configuration context"))
+ " " + Rule.IS_EXECUTABLE_ATTRIBUTE_NAME + " is called from "
+ " RunCommand.isExecutable, which has no configuration context"))
.add(
attr("$is_executable", BOOLEAN)
attr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, BOOLEAN)
.nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")
.value(
new Attribute.ComputedDefault() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.MacroClass;
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.RuleClassType;
import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
Expand Down Expand Up @@ -401,7 +402,7 @@ protected void visitRule(String qualifiedName, StarlarkRuleFunction ruleFunction
if (ruleClass.getRuleClassType() == RuleClassType.TEST) {
ruleInfoBuilder.setTest(true);
}
if (ruleClass.hasAttr("$is_executable", Type.BOOLEAN)) {
if (ruleClass.hasAttr(Rule.IS_EXECUTABLE_ATTRIBUTE_NAME, Type.BOOLEAN)) {
ruleInfoBuilder.setExecutable(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1123,10 +1123,7 @@ private static boolean isExecutableNonTestRule(Target target) {
if (!(target instanceof Rule rule)) {
return false;
}
if (rule.getRuleClassObject().hasAttr("$is_executable", Type.BOOLEAN)) {
return NonconfigurableAttributeMapper.of(rule).get("$is_executable", Type.BOOLEAN);
}
return false;
return rule.isExecutable();
}

private static boolean isPlainFile(Target target) {
Expand Down
5 changes: 5 additions & 0 deletions src/main/protobuf/build.proto
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ message Rule {
// The rule class (e.g., java_library)
required string rule_class = 2;

// Whether the rule can be `bazel run` (i.e. is a binary or test rule).
// Note: This is optional for compatibility requirements.
// TODO: Make this required after Bazel 8 ships.
optional bool is_executable = 16;
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

// The BUILD file and line number of the location (formatted as
// <absolute_path>:<line_number>:<column_number>) in the rule's package's
// BUILD file where the rule instance was instantiated. The line number will
Expand Down
18 changes: 18 additions & 0 deletions src/test/java/com/google/devtools/build/lib/packages/RuleTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,22 @@ private TargetData roundTrip(Target target) throws SerializationException, IOExc
ImmutableClassToInstanceMap.of(
RuleClassProvider.class, skyframeExecutor.getRuleClassProviderForTesting()));
}

@Test
public void testIsExecutable() throws Exception {
scratch.file(
"x/BUILD",
"cc_binary(name = 'cb')",
"cc_library(name = 'cl')",
"java_binary(name = 'jb')",
"java_library(name = 'jl')");

Package pkg = getTarget("//x:BUILD").getPackage();
illicitonion marked this conversation as resolved.
Show resolved Hide resolved

assertThat(pkg.getRule("cb").isExecutable()).isTrue();
assertThat(pkg.getRule("jb").isExecutable()).isTrue();

assertThat(pkg.getRule("cl").isExecutable()).isFalse();
assertThat(pkg.getRule("jl").isExecutable()).isFalse();
}
}