bazelbuild / bazelbuild/bazel

Support select() on aspect attributes

Open
#7,690 4 comments 1 reaction 0 assignees View on GitHub
P2 stale team-Configurability type: feature request
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 18h
Merged PRs (30d)
75

Description

### Description of the problem / feature request:

When an aspect declares `attrs = {foo:...}`, the build fails when the rule it's attached to sets `foo = select(...)`:

```
ERROR: /home/workspace/BUILD:3:1: //:hello: attribute 'pure' has a select() and aspect
//:def.bzl%go_archive_aspect also declares '//:hello'. Aspect attributes don't currently
support select().
```

Before my fix to #5120, this was a crash. My fix turned it into a proper error. But there's no conceptual reason why this shouldn't work.

### Feature requests: what underlying problem are you trying to solve with this feature?

Reduce instances where rule users can't use `select()` for no clear reason.

### Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Copied from #5120:

```
# BUILD.bazel

load("//:def.bzl", "go_binary")

go_binary(
name = "hello",
srcs = ["hello.go"],
pure = select({"//conditions:default": "auto"}),
)
```
```
# def.bzl

def _go_archive_aspect_impl(ctx):
return []

go_archive_aspect = aspect(
_go_archive_aspect_impl,
attrs = {
"pure": attr.string(values = [
"on",
"off",
"auto",
]),
},
)

def _go_binary_impl(ctx):
return []

go_binary = rule(
_go_binary_impl,
attrs = {
"srcs": attr.label_list(allow_files = [".go"]),
"deps": attr.label_list(aspects = [go_archive_aspect]),
"pure": attr.string(
values = [
"on",
"off",
"auto",
],
default = "auto",
),
},
)
```

### What operating system are you running Bazel on?

Linux.

### What's the output of `bazel info release`?

`release 0.23.2`

### What's the output of `git remote get-url origin ; git rev-parse master ; git rev-parse HEAD` ?

https://github.com/gregestren/bazel.git
52cf982bfad2836f7b7239a67ee322d90f43c4d5
21d03fed6f78ad3473e4f83d83e1a33b18119b69

### Have you found anything relevant by searching the web?

Just #5120.

### Any other information, logs, or outputs that you want to share?

While conceptually simple, this won't be a 10-minute fix.

The problem is that aspect definitions are created during Bazel's *loading* phase, which is before Bazel knows what values `select()s` actually bind to. And aspect definitions read their attribute values as a part of initialization.

So to fix this we have to refactor aspect definitions to either **a)** not read their attribute values or **b)** read them in some lazy way that can be deferred until the aspect implementation triggers.

Contributor guide

Open the contributing guide

Research direction

Start with the minimal BUILD.bazel and def.bzl reproduction, then trace how aspect definitions read attribute values during Bazel's loading phase and how the aspect implementation is triggered. Done means the rule can set the aspect attribute with select() without an error while preserving the declared attribute behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
build-system
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.