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

Allow Skylark rules to specify whether targets can add execution plat… #5341

Closed
wants to merge 5 commits into from

Conversation

katre
Copy link
Member

@katre katre commented Jun 7, 2018

…form constraints.

Change-Id: Ic937b011d1d95aac7dc6d715fa418f54d89198a9

…form constraints.

Change-Id: Ic937b011d1d95aac7dc6d715fa418f54d89198a9
@@ -397,6 +400,14 @@ public BaseFunction rule(
builder.advertiseSkylarkProvider(skylarkProvider);
}

// TODO(katre): convert from bool to enum
if (!execCompatibleWith.isEmpty()) {
builder.addExecutionPlatformConstraints(collectConstraintLabels(execCompatibleWith, ast));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, builtin functions shouldn't depend on the AST of their call site in any way (it's kind of a wart that breaks encapsulation). This function already violates that, but as a tiny step to not making it worse, please replace ast with ast.getLocation() in the signature of collectConstraintLabels().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll send another PR shortly making these same changes for toolchains.

@@ -316,6 +317,8 @@ public BaseFunction rule(
SkylarkList<String> toolchains,
String doc,
SkylarkList<?> providesArg,
Boolean executionPlatformConstraintsAllowed,
SkylarkList<String> execCompatibleWith,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generic type is unchecked by the Skylark calling interface. Change this to SkylarkList<?>, and use SkylarkList#getContents to cast to a list of strings.

@@ -397,6 +400,14 @@ public BaseFunction rule(
builder.advertiseSkylarkProvider(skylarkProvider);
}

// TODO(katre): convert from bool to enum
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outdated comment?

@@ -283,6 +288,8 @@ public BaseFunction rule(
SkylarkList<String> toolchains,
String doc,
SkylarkList<?> providesArg,
Boolean executionPlatformConstraintsAllowed,
SkylarkList<String> execCompatibleWith,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<String> to <?> as mentioned earlier. (Yes, I see you use generic1 = String.class, but IIRC that affects documentation generation but isn't actually enforced. Regardless, let's be consistent with the other string list params here and worry about fixing that in the future.)

positional = false,
defaultValue = "False",
doc =
"Whether targets of this rule can set exec_compatible_with to add extra constraints on the execution platform."),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested rephrasing:

If true, a special attribute named <code>exec_compatible_with</code> of label-list type is added. Targets may use this attribute to specify additional constraints on the execution platform beyond those given in the <code>exec_compatible_with</code> argument to <code>rule()</code>.

Is this wording accurate? Specifically, is exec_compatible_with considered a real label-list attribute, or is it some kind of string-list with special processing? If it's really a label list, the user would expect ctx.attr.exec_compatible_with to return a Target object.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes: it's a list of labels, which must exist.
No: They can't be resolved as Targets, because execution constraints have to be checked before dependencies are resolved (because the selected toolchains are dependencies, and we need the execution constraints in order to select the proper toolchain).

The user can probably access ctx.attr.exec_compatible_with, I'm just not sure if there's ever a use for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With or without a use for ctx.attr.exec_compatible_with, if it exists it should be documented, and the easiest way to do that is to refer to it as an "attribute" here.

If setting this bool causes it to be illegal for the user to define their own "exec_compatible_with" attribute in the attrs dict, we should also say so here, e.g.:

If true, a special attribute named <code>exec_compatible_with</code> of label-list type is added, which must not already exist in `attrs`. ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(backticks to <code> and </code>)

positional = false,
defaultValue = "[]",
doc =
"A list of constraints on the execution platform that targets of this rule will use.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested rephrasing:

A list of constraints on the execution platform that apply to all targets of this rule type.

public void testRuleAddExecutionConstraints() throws Exception {
scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
evalAndExport(
"def impl(ctx): return None",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: pass is more idiomatic than return None

scratch.file("test/BUILD", "toolchain_type(name = 'my_toolchain_type')");
evalAndExport(
"def impl(ctx): return None",
"r1 = rule(impl, ",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use implementation=impl (on a new line) instead of a positional arg.

}

@Test
public void testTargetsCanAddExecutionPlatformConstraints() throws Exception {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a new test to illustrate what happens when a user defines the exec_compatible_with attribute themselves (using attrs = ...) -- whatever that behavior is supposed to be.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added such a tes, but it doesn't seem to work, as this is only checked when RuleClass.Builder.build() is called, and for Skylark rules that happens when the rule is exported, and I can't figure out how to write a test that exports a rule. Any pointers?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's understandable. Check out SkylarkImportLookupFunction#execAndExport, and SkylarkRuleClassFunctionsTest#evalAndExport.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that worked!

Change-Id: If9886663c578297d8c7bba5355735ffb2354f39e
Change-Id: I4f19dddc8ccbaf10853b5b842e2597f39fe0911d
Change-Id: I7fb0ed49df7bab74912740571813ef332e729ee9
this.ruleClass = builder.build(ruleClassName, skylarkLabel + "%" + ruleClassName);
try {
this.ruleClass = builder.build(ruleClassName, skylarkLabel + "%" + ruleClassName);
} catch (IllegalArgumentException | IllegalStateException ex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not too familiar with the rule class builder, but I'm a little wary when I see broad unchecked exception types reraised as a checked exception like this. Can you add a comment mentioning that it's in case there's a conflict in the attribute builder?

Change-Id: Ib74e59fec48102469a5039e045e3f3d0e0d86d8c
@bazel-io bazel-io closed this in d79e977 Jun 14, 2018
ArielleA pushed a commit to ArielleA/bazel that referenced this pull request Jun 19, 2018
…form constraints.

Closes bazelbuild#5341.

Change-Id: Ib74e59fec48102469a5039e045e3f3d0e0d86d8c
PiperOrigin-RevId: 200526448
@katre katre deleted the per-target-constraints-skylark branch June 20, 2018 17:14
werkt pushed a commit to werkt/bazel that referenced this pull request Aug 2, 2018
…form constraints.

Closes bazelbuild#5341.

Change-Id: Ib74e59fec48102469a5039e045e3f3d0e0d86d8c
PiperOrigin-RevId: 200526448
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants