Skip to content

Commit

Permalink
Mandatory cfg parameter for labels if executable=1 is provided
Browse files Browse the repository at this point in the history
RELNOTES[INC]: All executable labels must also have a cfg parameter specified.

--
PiperOrigin-RevId: 144332992
MOS_MIGRATED_REVID=144332992
  • Loading branch information
vladmos authored and hlopko committed Jan 13, 2017
1 parent 6e95b7d commit f7c552c
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 17 deletions.
22 changes: 10 additions & 12 deletions src/main/java/com/google/devtools/build/lib/rules/SkylarkAttr.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.Attribute;
import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet;
Expand Down Expand Up @@ -159,8 +158,8 @@ private static void setAllowedFileTypes(
}

private static Attribute.Builder<?> createAttribute(
Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env,
Location loc) throws EvalException, ConversionException {
Type<?> type, SkylarkDict<String, Object> arguments, FuncallExpression ast, Environment env)
throws EvalException, ConversionException {
// We use an empty name now so that we can set it later.
// This trick makes sense only in the context of Skylark (builtin rules should not use it).
Attribute.Builder<?> builder = Attribute.attr("", type);
Expand Down Expand Up @@ -205,11 +204,11 @@ private static Attribute.Builder<?> createAttribute(
if (containsNonNoneKey(arguments, EXECUTABLE_ARG) && (Boolean) arguments.get(EXECUTABLE_ARG)) {
builder.setPropertyFlag("EXECUTABLE");
if (!containsNonNoneKey(arguments, CONFIGURATION_ARG)) {
String message = "Argument `cfg = \"host\"`, `cfg = \"data\"`, or `cfg = \"target\"` "
+ "is required if `executable = True` is provided for a label. Please see "
throw new EvalException(
ast.getLocation(),
"cfg parameter is mandatory when executable=True is provided. Please see "
+ "https://www.bazel.build/versions/master/docs/skylark/rules.html#configurations "
+ "for more details.";
env.handleEvent(Event.warn(loc, message));
+ "for more details.");
}
}

Expand Down Expand Up @@ -325,7 +324,7 @@ private static Descriptor createAttrDescriptor(
SkylarkDict<String, Object> kwargs, Type<?> type, FuncallExpression ast, Environment env)
throws EvalException {
try {
return new Descriptor(createAttribute(type, kwargs, ast, env, ast.getLocation()));
return new Descriptor(createAttribute(type, kwargs, ast, env));
} catch (ConversionException e) {
throw new EvalException(ast.getLocation(), e.getMessage());
}
Expand Down Expand Up @@ -356,7 +355,7 @@ private static Descriptor createNonconfigurableAttrDescriptor(
Preconditions.checkNotNull(maybeGetNonConfigurableReason(type), type);
try {
return new Descriptor(
createAttribute(type, kwargs, ast, env, ast.getLocation())
createAttribute(type, kwargs, ast, env)
.nonconfigurable(whyNotConfigurableReason));
} catch (ConversionException e) {
throw new EvalException(ast.getLocation(), e.getMessage());
Expand Down Expand Up @@ -622,8 +621,7 @@ public Descriptor invoke(
CONFIGURATION_ARG,
cfg),
ast,
env,
ast.getLocation());
env);
ImmutableList<SkylarkAspect> skylarkAspects =
ImmutableList.copyOf(aspects.getContents(SkylarkAspect.class, "aspects"));
return new Descriptor(attribute, skylarkAspects);
Expand Down Expand Up @@ -902,7 +900,7 @@ public Descriptor invoke(
cfg);
try {
Attribute.Builder<?> attribute =
createAttribute(BuildType.LABEL_LIST, kwargs, ast, env, ast.getLocation());
createAttribute(BuildType.LABEL_LIST, kwargs, ast, env);
ImmutableList<SkylarkAspect> skylarkAspects =
ImmutableList.copyOf(aspects.getContents(SkylarkAspect.class, "aspects"));
return new Descriptor(attribute, skylarkAspects);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ public void aspectParametersOptionalOverride() throws Exception {
}

@Test
public void multipleExecutablesInTarget() throws Exception {
public void testMultipleExecutablesInTarget() throws Exception {
scratch.file("foo/extension.bzl",
"def _aspect_impl(target, ctx):",
" return struct()",
Expand All @@ -1061,8 +1061,8 @@ public void multipleExecutablesInTarget() throws Exception {
" pass",
"my_rule = rule(_main_rule_impl,",
" attrs = { ",
" 'exe1' : attr.label(executable = True, allow_files = True),",
" 'exe2' : attr.label(executable = True, allow_files = True),",
" 'exe1' : attr.label(executable = True, allow_files = True, cfg = 'host'),",
" 'exe2' : attr.label(executable = True, allow_files = True, cfg = 'host'),",
" },",
")"
);
Expand All @@ -1081,7 +1081,6 @@ public void multipleExecutablesInTarget() throws Exception {
assertThat(analysisResultOfAspect.hasError()).isFalse();
}


@Test
public void aspectFragmentAccessSuccess() throws Exception {
getConfiguredTargetForAspectFragment(
Expand Down Expand Up @@ -1251,7 +1250,6 @@ private String[] aspectBzlFile(String attrAspects) {
};
}


@Test
public void aspectOutputsToBinDirectory() throws Exception {
scratch.file(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@
import java.util.Collection;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

Expand All @@ -65,6 +67,7 @@
*/
@RunWith(JUnit4.class)
public class SkylarkRuleClassFunctionsTest extends SkylarkTestCase {
@Rule public ExpectedException thrown = ExpectedException.none();

@Before
public final void createBuildFile() throws Exception {
Expand Down Expand Up @@ -1083,6 +1086,7 @@ public void declaredProvidersConcatError() throws Exception {
}

@Test

public void structsAsDeclaredProvidersTest() throws Exception {
evalAndExport(
"data = struct(x = 1)"
Expand Down Expand Up @@ -1115,4 +1119,30 @@ public void starTheOnlyAspectArg() throws Exception {
" pass",
"aspect(_impl, attr_aspects=['*', 'foo'])");
}

@Test
public void testMandatoryConfigParameterForExecutableLabels() throws Exception {
scratch.file("third_party/foo/extension.bzl",
"def _main_rule_impl(ctx):",
" pass",
"my_rule = rule(_main_rule_impl,",
" attrs = { ",
" 'exe' : attr.label(executable = True, allow_files = True),",
" },",
")"
);
scratch.file("third_party/foo/BUILD",
"load('extension', 'my_rule')",
"my_rule(name = 'main', exe = ':tool.sh')"
);

try {
createRuleContext("//third_party/foo:main");
Assert.fail();
} catch (AssertionError e) {
assertThat(e.getMessage()).contains("cfg parameter is mandatory when executable=True is "
+ "provided.");
}
}
}

0 comments on commit f7c552c

Please sign in to comment.