Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit da10ac4

Browse filesBrowse files
authored
feat(gazelle): Add "python_visibility" directive that appends additional visibility labels (bazel-contrib#1784)
Fixes bazel-contrib#1783. Add a new gazelle directive, `python_visibility`, that allows users to add labels to the `visibility` attribute of generated targets. out by the way, hence this PR), I noticed that the docs were a little This directive acts similar to[^1] the [`go_visibility` directive](https://github.com/bazelbuild/bazel-gazelle#directives). The primary use case is for python projects that separate unit test files from the python packages/modules that they test, like so: ``` packaging_tutorial/ ├── LICENSE ├── pyproject.toml ├── README.md ├── src/ │ └── mypackage/ │ ├── __init__.py │ └── foo.py └── tests/ ├── __init__.py └── test_foo.py ``` A future PR will add an example to the `./examples` directory (issue bazel-contrib#1775). [^1]: At least, similar based on docs. I haven't done any actual comparison.
1 parent 3f40e98 commit da10ac4
Copy full SHA for da10ac4

File tree

15 files changed

+141
-4
lines changed
Filter options

15 files changed

+141
-4
lines changed

‎gazelle/README.md

Copy file name to clipboardExpand all lines: gazelle/README.md
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ Python-specific directives are as follows:
198198
| Controls the `py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | |
199199
| `# gazelle:resolve py ...` | n/a |
200200
| Instructs the plugin what target to add as a dependency to satisfy a given import statement. The syntax is `# gazelle:resolve py import-string label` where `import-string` is the symbol in the python `import` statement, and `label` is the Bazel label that Gazelle should write in `deps`. | |
201+
| [`# gazelle:python_visibility label`](#directive-python_visibility) | |
202+
| Appends additional visibility labels to each generated target. This directive can be set multiple times. | |
201203

202204

203205
#### Directive: `python_root`:
@@ -236,6 +238,50 @@ py_libary(
236238
[python-packaging-user-guide]: https://github.com/pypa/packaging.python.org/blob/4c86169a/source/tutorials/packaging-projects.rst
237239

238240

241+
#### Directive: `python_visibility`:
242+
243+
Appends additional `visibility` labels to each generated target.
244+
245+
This directive can be set multiple times. The generated `visibility` attribute
246+
will include the default visibility and all labels defined by this directive.
247+
All labels will be ordered alphabetically.
248+
249+
```starlark
250+
# ./BUILD.bazel
251+
# gazelle:python_visibility //tests:__pkg__
252+
# gazelle:python_visibility //bar:baz
253+
254+
py_library(
255+
...
256+
visibility = [
257+
"//:__subpackages__", # default visibility
258+
"//bar:baz",
259+
"//tests:__pkg__",
260+
],
261+
...
262+
)
263+
```
264+
265+
Child Bazel packages inherit values from parents:
266+
267+
```starlark
268+
# ./bar/BUILD.bazel
269+
# gazelle:python_visibility //tests:__subpackages__
270+
271+
py_library(
272+
...
273+
visibility = [
274+
"//:__subpackages__", # default visibility
275+
"//bar:baz", # defined in ../BUILD.bazel
276+
"//tests:__pkg__", # defined in ../BUILD.bazel
277+
"//tests:__subpackages__", # defined in this ./BUILD.bazel
278+
],
279+
...
280+
)
281+
282+
```
283+
284+
239285
### Libraries
240286

241287
Python source files are those ending in `.py` but not ending in `_test.py`.

‎gazelle/python/configure.go

Copy file name to clipboardExpand all lines: gazelle/python/configure.go
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func (py *Configurer) KnownDirectives() []string {
6363
pythonconfig.LibraryNamingConvention,
6464
pythonconfig.BinaryNamingConvention,
6565
pythonconfig.TestNamingConvention,
66+
pythonconfig.Visibility,
6667
}
6768
}
6869

@@ -162,6 +163,8 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) {
162163
config.SetBinaryNamingConvention(strings.TrimSpace(d.Value))
163164
case pythonconfig.TestNamingConvention:
164165
config.SetTestNamingConvention(strings.TrimSpace(d.Value))
166+
case pythonconfig.Visibility:
167+
config.AppendVisibility(strings.TrimSpace(d.Value))
165168
}
166169
}
167170

‎gazelle/python/generate.go

Copy file name to clipboardExpand all lines: gazelle/python/generate.go
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
212212
}
213213

214214
parser := newPython3Parser(args.Config.RepoRoot, args.Rel, cfg.IgnoresDependency)
215-
visibility := fmt.Sprintf("//%s:__subpackages__", pythonProjectRoot)
215+
visibility := []string{fmt.Sprintf("//%s:__subpackages__", pythonProjectRoot)}
216+
visibility = append(visibility, cfg.Visibility()...)
216217

217218
var result language.GenerateResult
218219
result.Gen = make([]*rule.Rule, 0)

‎gazelle/python/target.go

Copy file name to clipboardExpand all lines: gazelle/python/target.go
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,11 @@ func (t *targetBuilder) addResolvedDependency(dep string) *targetBuilder {
9999
return t
100100
}
101101

102-
// addVisibility adds a visibility to the target.
103-
func (t *targetBuilder) addVisibility(visibility string) *targetBuilder {
104-
t.visibility.Add(visibility)
102+
// addVisibility adds visibility labels to the target.
103+
func (t *targetBuilder) addVisibility(visibility []string) *targetBuilder {
104+
for _, item := range visibility {
105+
t.visibility.Add(item)
106+
}
105107
return t
106108
}
107109

+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Directives can be added in any order. They will be ordered alphabetically
2+
# when added.
3+
# gazelle:python_visibility //tests:__pkg__
4+
# gazelle:python_visibility //bar:baz
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
load("@rules_python//python:defs.bzl", "py_library")
2+
3+
# Directives can be added in any order. They will be ordered alphabetically
4+
# when added.
5+
# gazelle:python_visibility //tests:__pkg__
6+
# gazelle:python_visibility //bar:baz
7+
8+
py_library(
9+
name = "directive_python_visibility",
10+
srcs = ["foo.py"],
11+
visibility = [
12+
"//:__subpackages__",
13+
"//bar:baz",
14+
"//tests:__pkg__",
15+
],
16+
)
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Directive: `python_visibility`
2+
3+
This test case asserts that the `# gazelle:python_visibility` directive correctly
4+
appends multiple labels to the target's `visibility` parameter.
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This is a Bazel workspace for the Gazelle test data.
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def func():
2+
print("library_func")
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# python_visibilty directive applies to all child bazel packages.
2+
# Thus, the generated file for this package will also have vis for
3+
# //tests:__pkg__ and //bar:baz in addition to the default.
4+
# gazelle:python_visibility //tests:__subpackages__
+20Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
load("@rules_python//python:defs.bzl", "py_library")
2+
3+
# python_visibilty directive applies to all child bazel packages.
4+
# Thus, the generated file for this package will also have vis for
5+
# //tests:__pkg__ and //bar:baz in addition to the default.
6+
# gazelle:python_visibility //tests:__subpackages__
7+
8+
py_library(
9+
name = "subdir",
10+
srcs = [
11+
"__init__.py",
12+
"bar.py",
13+
],
14+
visibility = [
15+
"//:__subpackages__",
16+
"//bar:baz",
17+
"//tests:__pkg__",
18+
"//tests:__subpackages__",
19+
],
20+
)

‎gazelle/python/testdata/directive_python_visibility/subdir/__init__.py

Copy file name to clipboardExpand all lines: gazelle/python/testdata/directive_python_visibility/subdir/__init__.py
Whitespace-only changes.

‎gazelle/python/testdata/directive_python_visibility/subdir/bar.py

Copy file name to clipboardExpand all lines: gazelle/python/testdata/directive_python_visibility/subdir/bar.py
Whitespace-only changes.
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright 2023 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
---
16+
expect:
17+
exit_code: 0

‎gazelle/pythonconfig/pythonconfig.go

Copy file name to clipboardExpand all lines: gazelle/pythonconfig/pythonconfig.go
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ const (
6767
// naming convention. See python_library_naming_convention for more info on
6868
// the package name interpolation.
6969
TestNamingConvention = "python_test_naming_convention"
70+
// Visibility represents the directive that controls what additional
71+
// visibility labels are added to generated targets. It mimics the behavior
72+
// of the `go_visibility` directive.
73+
Visibility = "python_visibility"
7074
)
7175

7276
// GenerationModeType represents one of the generation modes for the Python
@@ -136,6 +140,7 @@ type Config struct {
136140
libraryNamingConvention string
137141
binaryNamingConvention string
138142
testNamingConvention string
143+
visibility []string
139144
}
140145

141146
// New creates a new Config.
@@ -157,6 +162,7 @@ func New(
157162
libraryNamingConvention: packageNameNamingConventionSubstitution,
158163
binaryNamingConvention: fmt.Sprintf("%s_bin", packageNameNamingConventionSubstitution),
159164
testNamingConvention: fmt.Sprintf("%s_test", packageNameNamingConventionSubstitution),
165+
visibility: []string{},
160166
}
161167
}
162168

@@ -183,6 +189,7 @@ func (c *Config) NewChild() *Config {
183189
libraryNamingConvention: c.libraryNamingConvention,
184190
binaryNamingConvention: c.binaryNamingConvention,
185191
testNamingConvention: c.testNamingConvention,
192+
visibility: c.visibility,
186193
}
187194
}
188195

@@ -388,3 +395,13 @@ func (c *Config) SetTestNamingConvention(testNamingConvention string) {
388395
func (c *Config) RenderTestName(packageName string) string {
389396
return strings.ReplaceAll(c.testNamingConvention, packageNameNamingConventionSubstitution, packageName)
390397
}
398+
399+
// AppendVisibility adds additional items to the target's visibility.
400+
func (c *Config) AppendVisibility(visibility string) {
401+
c.visibility = append(c.visibility, visibility)
402+
}
403+
404+
// Visibility returns the target's visibility.
405+
func (c *Config) Visibility() []string {
406+
return c.visibility
407+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.