bazel-contrib / bazel-contrib/rules_python

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

未关闭
#1,877 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
gazelle help wanted type: feature request
主要语言
Starlark
星标
688
派生
721
平均合并
15 小时 7 分钟
30 天内合并 PR
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 导入是如何映射到依赖项的。为嵌套导入定义明确无歧义的行为,尤其是 `hello.world.again` 这种情况;要视为完成,必须有经协商一致的解析模型,以及相应的实现和覆盖率。

由索引模型根据 Issue 内容生成。

评估

技术栈
python
领域
build-system
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
停滞
描述清晰度
基本清楚
新手友好度
30/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。