FR: propagate aspects using labels as the matching edge key
- Dominant language
- Java
- Stars
- 25.8k
- Forks
- 4.6k
- Avg merge
- 2d 20h
- Merged PRs (30d)
- 72
Description
### Description of the feature request:
Today, aspects traverse through the graph by matching attribute names. This mostly works, but has several drawbacks and short comings. Instead, I propose to use labels to identify matching edges. An attribute can specify a list of "aspect_edge" labels. An aspect then specifies a list of aspect edge type labels it cares about. e.g.
```
# foo.bzl
foo = rule(attrs = {
"deps": attr.label_list(aspect_edge_types=["@bazel_tools//aspects:deps_edge"])
}, ...)
foo_aspect = aspect(
aspect_edge_types = ["@bazel_tools//aspects:deps_edge"], ...
)
# bazel_tools/aspects/BUILD
aspect_edge_type(name="deps")
```
## Motivation
@tjgq summed it up rather nicely in an internal doc, "Avoid Starlark Aspects", back in 2019:
> Aspects are stringly typed
>
> An attribute of the same name doesn’t necessarily mean the same for every rule. For example, js_library.deps contains library dependencies, but js_module.deps contains module dependencies. As another (cross-language) example, ts_library.runtime_deps looks superficially similar to java_library.runtime_deps, but doesn’t have the same semantics.
>
> It is difficult to generate an exhaustive list of attribute names used by rules for a given language. In addition, anyone can add new rules or attributes at any time and fail to update the list. This is further compounded by the existence of private attributes that aren’t visible in BUILD files. For example, my best attempt for JavaScript is here, but I wouldn’t trust it to be complete.
>
> Aspect propagation may unintentionally cross language boundaries. For example, say you have a genrule that produces output JavaScript files, which is then put in the srcs of a js_library. A JavaScript aspect will happily traverse the genrule.srcs attribute, even though it may contain targets that aren’t JavaScript at all. This is at best an annoyance (you must write the aspect in such a way that it refuses to operate on “invalid” targets) and at worst a potential bug (the aspect generates bogus output for these targets).
Since that doc, some cases of the above have been noted:
* private_deps in swift
* implementation deps in C++
* I think java has runtime_deps ?
* protos: `lang_library--deps--> lang_proto_library --deps--> proto_library`
* Private attributes that are conceptually just extra deps and make sense for an aspect to visit or know about
### Which category does this issue belong to?
Rules API
### What underlying problem are you trying to solve with this feature?
The issue of having a more stable and reliable interface for aspects. Today, rule authors don't have a good way to cleanly support aspects. There's a variety of reason for this, but one of them is that rules and aspects don't have a clear way to communicate what the correct attributes to visit are.
### Which operating system are you running Bazel on?
_No response_
### What is the output of `bazel info release`?
_No response_
### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.
_No response_
### What's the output of `git remote get-url origin; git rev-parse HEAD` ?
_No response_
### Have you found anything relevant by searching the web?
I was unable to find prior issues about this topic
### Any other information, logs, or outputs that you want to share?
_No response_
Contributor guide
Research direction
No implementation files, tests, or entry points are identified in the issue. Start by locating Bazel's aspect propagation and Rules API definitions, then determine how rule attributes and aspects could declare matching edge labels. Done would require an agreed label-based propagation API, its implementation, and coverage for the examples and cross-language cases described.
Written by the indexing model from the issue text.
Assessment
- Domain
- api, build-system
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100