bazel-contrib / bazel-contrib/rules_python

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

オープン
#1,877 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
gazelle help wanted type: feature request
主要言語
Starlark
スター
688
フォーク
721
平均マージ
15時間 7分
マージ済み PR(30日)
76

説明

# :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.

コントリビューションガイド

コントリビューションガイドを開く

調査の方向性

Issue にある `gazelle:resolve` ディレクティブと `BUILD.bazel` の例から始め、`foo.bar` のような Python の import が依存関係にどのようにマッピングされるかを追跡してください。ネストした import、特に `hello.world.again` のケースについて、曖昧さのない動作を定義してください。完了とするには、合意された解決モデルと、それに対応する実装およびカバレッジが必要です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
build-system
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
30/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。