bazel-contrib / bazel-contrib/rules_jvm
FR: Gazelle resolve class directives
- Dominant language
- Go
- Stars
- 54
- Forks
- 98
- Avg merge
- 6d 2h
- Merged PRs (30d)
- 7
Description
For the most part, resolving dependencies by packages works pretty well and the cases where it does not aren't hard to workaround, however, there's one use case I found where it would be a much better user experience if class-level resolve directives were supported.
For a concrete example, I'll be using everyone's favorite (sarcasm), lombok
```bzl
# gazelle:resolve java lombok //:lombok
java_plugin(
name = "lombok_plugin",
generates_api = 1,
processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor",
deps = [artifact("org.projectlombok:lombok")],
)
java_library(
name = "lombok",
exported_plugins = [":lombok_plugin"],
neverlink = 1,
visibility = ["//visibility:public"],
exports = [artifact("org.projectlombok:lombok")],
)
```
So, here we have declared that any importer of `lombok.*` shall require `//:lombok` instead of `@maven//:org_projectlombok_lombok`. This mostly works, but what happens when a package tries to use the `CustomLog` annotation?
```java
import lombok.CustomLog;
@CustomLog
public class MyClass {}
```
`CustomLog` injects a logger of a class specified in a config file according to the javadoc.

So let's say we want to inject a logger of type `com.mycompany.myapp.logger.AppLogger`
```
lombok.log.custom.declaration = com.mycompany.myapp.logger.AppLogger
```
What I would normally do in this situation is add a dependency on `com.mycompany.myapp.logger.AppLogger` to `//:lombok`, however our logging class depends on a `StructuredLogging` class (log lines), which depends on `lombok.{Builder,Value}`, so that would create a cycle in the graph.
Barring any refactoring, what I'd like to be able to do is say "any imports of `lombok.CustomLog` resolve to labelA and any imports of `lombok.*` resolve to labelB"
```bzl
# gazelle:resolve java lombok.CustomLog //:logging
# gazelle:resolve java lombok //:lombok
```
Contributor guide
Research direction
Start by tracing Gazelle's Java resolve-directive handling and how it matches imports such as lombok.CustomLog versus the broader lombok package. Use the lombok example and the proposed labelA/labelB directives as the acceptance case; done means the specific class resolves to the logging target while other lombok imports resolve to the lombok target without introducing the dependency cycle.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, java
- Domain
- build-system, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100