bazel-contrib / bazel-contrib/rules_python

Can Gazelle's 'resolve' directive be smarter? Or am I just using it wrong?

Aperta
#1,877 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
gazelle help wanted type: feature request
Lingua principale
Starlark
Stelle
688
Fork
721
Merge medio
15h 7m
PR unite (30g)
76

Descrizione

# :question: question | possible 🚀 feature request

### Relevant Rules

+ gazelle

### Description

Can Gazelle's 'resolve' directive be smarter? Or am I just using it wrong?

Example:

```
# gazelle:resolve py foo @other//foo
```

| Import | Expected Dep | Actual Dep |
| --- | --- | --- |
| `import foo.bar.baz` | `"@other//foo/bar:baz"` | `"@other//foo"` |
| `from foo import bar` | `"@other//foo:bar"` | `"@other//foo"` |
| `import foo.bar as bar` | `"@other//foo/bar"` | `"@other//foo"` |

This is coming about because we have a nested project with a dir structure like:

```
./main_project_repo
+ BUILD.bazel
+ MODULE.bazel # module(name = "main_project_repo")
+ src/
+ BUILD.bazel # sets python_root
+ main_project/
+ BUILD.bazel
+ foo.py # imports other_project_repo/src/other_project/bar.py
# via `import other_project.bar` thanks to PYTHONPATH
+ private.py
+ other_project_repo/
+ BUILD.bazel
+ MODULE.bazel # module(name = "other_project_repo")
+ src/
+ BUILD.bazel # sets python_root
+ other_project/
+ BUILD.bazel
+ bar.py
```

And `./main_project_repo/src/main_project/BUILD.bazel` looks like so to work:

```starlark
# //src/main_project:foo
py_library(
name = "foo",
srcs = ["foo.py"],
deps = [
":private",
"@other_project_repo//src/other_project:bar"
],
)
```

With the current functionality, I'd have to write out resolve directives for every import used

```
# gazelle:resolve py other_project @other_project_repo//src/other_project
# gazelle:resolve py other_project.bar @other_project_repo//src/other_project:bar
# gazelle:resolve py other_project.foobar @other_project_repo//src/other_project/foobar
# gazelle:resolve py other_project.foobar.hello @other_project_repo//src/other_project/foobar:hello
# gazelle:resolve py other_project.foobar.goodbye @other_project_repo//src/other_project/foobar:goodbye
...
```

Sadly this is not feasible given the size of our codebases.

### Describe the solution you'd like

I may be in the wrong, but it seems like the directive should match the start of the import and then follow the rest of the import path. I'm not exactly sure how, or even if, this would work though (see example 2).

#### Example 1

```
# gazelle:resolve py foo @other//foo
# import foo --> @other//foo
# import foo.bar --> @other//foo:bar
```

#### Example 2

```
# gazelle resolve py hello.world //goodbye:world
# import hello --> //hello # no change because it's not matched by resolve.
# import hello.world --> //goodbye:world # no change from current functionality
# import hello.world.again --> ... I donno. Can't be //goodbye:world:again haha
```

### Describe alternatives you've considered

We might be able to run buildozer and modify all the deps in `./main_project_repo/src` after Gazelle generates them, but I haven't looked into how feasible that actually is.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Start with the `gazelle:resolve` directives and the `BUILD.bazel` examples in the issue, then trace how Python imports such as `foo.bar` are mapped to dependencies. Define unambiguous behavior for nested imports, especially the `hello.world.again` case; done requires an agreed resolution model and corresponding implementation and coverage.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
build-system
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.