The docs describe anon targets as solving "the overlay problem":
The overlay problem - this is the idea that you want to have a shadow-graph, similar in structure to the normal graph, but with additional information attached. Bazel accomplishes this with Aspects. With Anonymous (anon) targets, you can create a shadow-graph by convention, just by using the target name you wish to shadow as the attribute.
I don't understand this. If you try to make a graph purely by convention, an anon rule can't really have any inputs other than the target name. And because "deps" are one of these inputs you can't really have, you can't have a graph at all, at least not one with any edges.
In contrast, Bazel's Aspects do let you make a shadow graph. See the "advanced example" here, where you can make an aspect with attr_aspects = ['deps'], and it will basically add an additional provider to all nodes in a dep graph.
I think we should be able to do stuff like this in Buck.
Why?
I've wanted this a few times. The main reason is to get access to sources for all nodes in a dep graph, which is important for things like Tailwind CSS, which has to look at all your sources to generate its output. You could do this by modifying all the prelude rules to add a "SourcesTset" provider or something, but this is way too difficult, there are what, 100 different rules to add this to? And where do you cut off the tset? What if I want to filter the sources by target name (/ restrict to a particular cell) so that only some sources appear in the tset? You can't filter a tset after creation unless you iterate it, and these tsets will be very large if not filtered early on. So this is really not something that can go in the prelude.
When I read "the overlay problem", I thought "extending the prelude by overlaying another graph on it, without touching the original rules". So anon targets seem really promising at first!
You make an anon target with a "deps": attrs.list(attrs.dep()) attribute, returning a provider with a tset attribute
You can call it with the top-level dependencies inside a tailwind_bundle rule. All going well so far.
But, there is no way to get the dependencies of those dependencies inside the anon target impl, in order to create more anon_targets to construct the rest of the shadow graph recursively.
What would need to happen for anon targets to really function as overlays the way I've described?
The docs describe anon targets as solving "the overlay problem":
I don't understand this. If you try to make a graph purely by convention, an anon rule can't really have any inputs other than the target name. And because "deps" are one of these inputs you can't really have, you can't have a graph at all, at least not one with any edges.
In contrast, Bazel's Aspects do let you make a shadow graph. See the "advanced example" here, where you can make an aspect with
attr_aspects = ['deps'],
and it will basically add an additional provider to all nodes in a dep graph.I think we should be able to do stuff like this in Buck.
Why?
I've wanted this a few times. The main reason is to get access to sources for all nodes in a dep graph, which is important for things like Tailwind CSS, which has to look at all your sources to generate its output. You could do this by modifying all the prelude rules to add a "SourcesTset" provider or something, but this is way too difficult, there are what, 100 different rules to add this to? And where do you cut off the tset? What if I want to filter the sources by target name (/ restrict to a particular cell) so that only some sources appear in the tset? You can't filter a tset after creation unless you iterate it, and these tsets will be very large if not filtered early on. So this is really not something that can go in the prelude.
When I read "the overlay problem", I thought "extending the prelude by overlaying another graph on it, without touching the original rules". So anon targets seem really promising at first!
"deps": attrs.list(attrs.dep())
attribute, returning a provider with a tset attributetailwind_bundle
rule. All going well so far.What would need to happen for anon targets to really function as overlays the way I've described?