bazel-contrib / bazel-contrib/rules_jvm

FR: Gazelle resolve class directives

Open
#155 1 comment 0 reactions 0 assignees View on GitHub
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.

image

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.