diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aaebd4695..142df6a208 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,8 +29,12 @@ A brief description of the categories of changes: https://github.com/indygreg/python-build-standalone/releases/tag/20240224. * (gazelle) Added a new `python_visibility` directive to control visibility of generated targets by appending additional visibility labels. +* (gazelle) Added a new `python_default_visibility` directive to control the + _default_ visibility of generated targets. See the [docs][python_default_visibility] + for details. [0.XX.0]: https://github.com/bazelbuild/rules_python/releases/tag/0.XX.0 +[python_default_visibility]: gazelle/README.md#directive-python_default_visibility ### Changed diff --git a/gazelle/README.md b/gazelle/README.md index 00170345e7..1caa677d34 100644 --- a/gazelle/README.md +++ b/gazelle/README.md @@ -198,6 +198,8 @@ Python-specific directives are as follows: | Controls the `py_test` naming convention. Follows the same interpolation rules as `python_library_naming_convention`. | | | `# gazelle:resolve py ...` | n/a | | 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`. | | +| [`# gazelle:python_default_visibility labels`](#directive-python_default_visibility) | | +| Instructs gazelle to use these visibility labels on all python targets. `labels` is a comma-separated list of labels (without spaces). | `//$python_root:__subpackages__` | | [`# gazelle:python_visibility label`](#directive-python_visibility) | | | Appends additional visibility labels to each generated target. This directive can be set multiple times. | | @@ -238,6 +240,81 @@ py_libary( [python-packaging-user-guide]: https://github.com/pypa/packaging.python.org/blob/4c86169a/source/tutorials/packaging-projects.rst +#### Directive: `python_default_visibility`: + +Instructs gazelle to use these visibility labels on all _python_ targets +(typically `py_*`, but can be modified via the `map_kind` directive). The arg +to this directive is a a comma-separated list (without spaces) of labels. + +For example: + +```starlark +# gazelle:python_default_visibility //:__subpackages__,//tests:__subpackages__ +``` + +produces the following visibility attribute: + +```starlark +py_library( + ..., + visibility = [ + "//:__subpackages__", + "//tests:__subpackages__", + ], + ..., +) +``` + +You can also inject the `python_root` value by using the exact string +`$python_root`. All instances of this string will be replaced by the `python_root` +value. + +```starlark +# gazelle:python_default_visibility //$python_root:__pkg__,//foo/$python_root/tests:__subpackages__ + +# Assuming the "# gazelle:python_root" directive is set in ./py/src/BUILD.bazel, +# the results will be: +py_library( + ..., + visibility = [ + "//foo/py/src/tests:__subpackages__", # sorted alphabetically + "//py/src:__pkg__", + ], + ..., +) +``` + +Two special values are also accepted as an argument to the directive: + ++ `NONE`: This removes all default visibility. Labels added by the + `python_visibility` directive are still included. ++ `DEFAULT`: This resets the default visibility. + +For example: + +```starlark +# gazelle:python_default_visibility NONE + +py_library( + name = "...", + srcs = [...], +) +``` + +```starlark +# gazelle:python_default_visibility //foo:bar +# gazelle:python_default_visibility DEFAULT + +py_library( + ..., + visibility = ["//:__subpackages__"], + ..., +) +``` + +These special values can be useful for sub-packages. + + #### Directive: `python_visibility`: Appends additional `visibility` labels to each generated target. diff --git a/gazelle/python/configure.go b/gazelle/python/configure.go index 431568829b..843609605c 100644 --- a/gazelle/python/configure.go +++ b/gazelle/python/configure.go @@ -63,6 +63,7 @@ func (py *Configurer) KnownDirectives() []string { pythonconfig.LibraryNamingConvention, pythonconfig.BinaryNamingConvention, pythonconfig.TestNamingConvention, + pythonconfig.DefaultVisibilty, pythonconfig.Visibility, } } @@ -119,6 +120,7 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) { } case pythonconfig.PythonRootDirective: config.SetPythonProjectRoot(rel) + config.SetDefaultVisibility([]string{fmt.Sprintf(pythonconfig.DefaultVisibilityFmtString, rel)}) case pythonconfig.PythonManifestFileNameDirective: gazelleManifestFilename = strings.TrimSpace(d.Value) case pythonconfig.IgnoreFilesDirective: @@ -163,6 +165,20 @@ func (py *Configurer) Configure(c *config.Config, rel string, f *rule.File) { config.SetBinaryNamingConvention(strings.TrimSpace(d.Value)) case pythonconfig.TestNamingConvention: config.SetTestNamingConvention(strings.TrimSpace(d.Value)) + case pythonconfig.DefaultVisibilty: + switch directiveArg := strings.TrimSpace(d.Value); directiveArg { + case "NONE": + config.SetDefaultVisibility([]string{}) + case "DEFAULT": + pythonProjectRoot := config.PythonProjectRoot() + defaultVisibility := fmt.Sprintf(pythonconfig.DefaultVisibilityFmtString, pythonProjectRoot) + config.SetDefaultVisibility([]string{defaultVisibility}) + default: + // Handle injecting the python root. Assume that the user used the + // exact string "$python_root". + labels := strings.ReplaceAll(directiveArg, "$python_root", config.PythonProjectRoot()) + config.SetDefaultVisibility(strings.Split(labels, ",")) + } case pythonconfig.Visibility: config.AppendVisibility(strings.TrimSpace(d.Value)) } diff --git a/gazelle/python/generate.go b/gazelle/python/generate.go index 6973d2ded8..400c25e0b4 100644 --- a/gazelle/python/generate.go +++ b/gazelle/python/generate.go @@ -212,8 +212,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes } parser := newPython3Parser(args.Config.RepoRoot, args.Rel, cfg.IgnoresDependency) - visibility := []string{fmt.Sprintf("//%s:__subpackages__", pythonProjectRoot)} - visibility = append(visibility, cfg.Visibility()...) + visibility := cfg.Visibility() var result language.GenerateResult result.Gen = make([]*rule.Rule, 0) diff --git a/gazelle/python/testdata/directive_python_default_visibility/README.md b/gazelle/python/testdata/directive_python_default_visibility/README.md new file mode 100644 index 0000000000..be42792375 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/README.md @@ -0,0 +1,21 @@ +# Directive: `python_default_visibility` + +This test case asserts that the `# gazelle:python_default_visibility` directive +correctly: + +1. Uses the default value when `python_default_visibility` is not set. +2. Uses the correct default value when `python_root` is set and + `python_default_visibility` is not set. +3. Supports injecting `python_root` +4. Supports multiple labels +5. Setting the label to "NONE" removes all visibility attibutes. +6. Setting the label to "DEFAULT" reverts to using the default. +7. Adding `python_visibility` directive with `python_default_visibility NONE` + only adds the items listed by `python_visibility`. +8. Multiple `python_root` dirs [GH #1682][gh-1682] uses correct value when + injecting `python_root`. +9. Setting both `python_default_visibility` and `python_visibility` and how + they interact with sub-packages. + + +[gh-1682]: https://github.com/bazelbuild/rules_python/issues/1682 diff --git a/gazelle/python/testdata/directive_python_default_visibility/WORKSPACE b/gazelle/python/testdata/directive_python_default_visibility/WORKSPACE new file mode 100644 index 0000000000..faff6af87a --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/WORKSPACE @@ -0,0 +1 @@ +# This is a Bazel workspace for the Gazelle test data. diff --git a/gazelle/python/testdata/directive_python_default_visibility/test.yaml b/gazelle/python/testdata/directive_python_default_visibility/test.yaml new file mode 100644 index 0000000000..2410223e59 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test.yaml @@ -0,0 +1,17 @@ +# Copyright 2023 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +expect: + exit_code: 0 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.in new file mode 100644 index 0000000000..690a65151d --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.in @@ -0,0 +1 @@ +# python_default_visibility is not set. diff --git a/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.out new file mode 100644 index 0000000000..47fd2d87d5 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test1_default/BUILD.out @@ -0,0 +1,9 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# python_default_visibility is not set. + +py_library( + name = "test1_default", + srcs = ["test1.py"], + visibility = ["//:__subpackages__"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test1_default/test1.py b/gazelle/python/testdata/directive_python_default_visibility/test1_default/test1.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test1_default/test1.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.in new file mode 100644 index 0000000000..6948b47b10 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_root diff --git a/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.out new file mode 100644 index 0000000000..c3b51bd50e --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/BUILD.out @@ -0,0 +1,12 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_root + +py_library( + name = "test2_default_with_python_root", + srcs = [ + "__init__.py", + "test2.py", + ], + visibility = ["//test2_default_with_python_root:__subpackages__"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/__init__.py b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/test2.py b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/test2.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test2_default_with_python_root/test2.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.in new file mode 100644 index 0000000000..dd64538ef1 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.in @@ -0,0 +1,2 @@ +# gazelle:python_root +# gazelle:python_default_visibility //foo/$python_root/bar:__pkg__ diff --git a/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.out new file mode 100644 index 0000000000..1dc862bfd3 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/BUILD.out @@ -0,0 +1,13 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_root +# gazelle:python_default_visibility //foo/$python_root/bar:__pkg__ + +py_library( + name = "test3_injection", + srcs = [ + "__init__.py", + "test3.py", + ], + visibility = ["//foo/test3_injection/bar:__pkg__"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test3_injection/__init__.py b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test3_injection/test3.py b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/test3.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test3_injection/test3.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.in new file mode 100644 index 0000000000..53eb8a352d --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_default_visibility //foo/bar:__pkg__,//tests:__subpackages__,//a:b diff --git a/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.out new file mode 100644 index 0000000000..2c3a433275 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/BUILD.out @@ -0,0 +1,13 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_default_visibility //foo/bar:__pkg__,//tests:__subpackages__,//a:b + +py_library( + name = "test4_multiple_labels", + srcs = ["test4.py"], + visibility = [ + "//a:b", + "//foo/bar:__pkg__", + "//tests:__subpackages__", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/test4.py b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/test4.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test4_multiple_labels/test4.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.in new file mode 100644 index 0000000000..7810eea7ae --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_default_visibility NONE diff --git a/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.out new file mode 100644 index 0000000000..fc410f6866 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/BUILD.out @@ -0,0 +1,8 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_default_visibility NONE + +py_library( + name = "test5_none_label", + srcs = ["test5.py"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/test5.py b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/test5.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test5_none_label/test5.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.in new file mode 100644 index 0000000000..65b51e30ee --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_default_visibility //foo:bar diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.out new file mode 100644 index 0000000000..3df11b4024 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/BUILD.out @@ -0,0 +1,9 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_default_visibility //foo:bar + +py_library( + name = "test6_default_label", + srcs = ["test6.py"], + visibility = ["//foo:bar"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.in new file mode 100644 index 0000000000..2a54cfda68 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.in @@ -0,0 +1,2 @@ +# Reset the default visibility to the default for all child packages. +# gazelle:python_default_visibility DEFAULT diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.out new file mode 100644 index 0000000000..61693674ea --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/BUILD.out @@ -0,0 +1,10 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# Reset the default visibility to the default for all child packages. +# gazelle:python_default_visibility DEFAULT + +py_library( + name = "subpkg", + srcs = ["test6_sub.py"], + visibility = ["//:__subpackages__"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/test6_sub.py b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/test6_sub.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/subpkg/test6_sub.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/test6.py b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/test6.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test6_default_label/test6.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.in new file mode 100644 index 0000000000..d64169facb --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.in @@ -0,0 +1,5 @@ +# python_visibility directives that happen either before _or_ after the +# NONE reset both get applied. +# gazelle:python_visibility //foo:bar +# gazelle:python_default_visibility NONE +# gazelle:python_visibility //bar:baz diff --git a/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.out new file mode 100644 index 0000000000..f912ac6fe5 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/BUILD.out @@ -0,0 +1,16 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# python_visibility directives that happen either before _or_ after the +# NONE reset both get applied. +# gazelle:python_visibility //foo:bar +# gazelle:python_default_visibility NONE +# gazelle:python_visibility //bar:baz + +py_library( + name = "test7_none_label_with_extra_vis", + srcs = ["test7.py"], + visibility = [ + "//bar:baz", + "//foo:bar", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/test7.py b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/test7.py new file mode 100644 index 0000000000..98907eb794 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test7_none_label_with_extra_vis/test7.py @@ -0,0 +1,2 @@ +def func(): + print("library_func") diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.in new file mode 100644 index 0000000000..4e90bdcff5 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.in @@ -0,0 +1,2 @@ +# For funzies, also throw in some additional visibility. +# gazelle:python_visibility //tests:__pkg__ diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.out new file mode 100644 index 0000000000..4e90bdcff5 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/BUILD.out @@ -0,0 +1,2 @@ +# For funzies, also throw in some additional visibility. +# gazelle:python_visibility //tests:__pkg__ diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.in new file mode 100644 index 0000000000..6948b47b10 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_root diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.out new file mode 100644 index 0000000000..6948b47b10 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/BUILD.out @@ -0,0 +1 @@ +# gazelle:python_root diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.in new file mode 100644 index 0000000000..0151a68526 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.in @@ -0,0 +1,2 @@ +# proj1 depends on proj2 +# We can leave the default visibility. diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.out new file mode 100644 index 0000000000..a473ba5e02 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/BUILD.out @@ -0,0 +1,14 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# proj1 depends on proj2 +# We can leave the default visibility. + +py_library( + name = "pkg1", + srcs = ["file1.py"], + imports = [".."], + visibility = [ + "//test8_multiple_python_root_dirs/proj1/src:__subpackages__", + "//tests:__pkg__", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/file1.py b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj1/src/pkg1/file1.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.in new file mode 100644 index 0000000000..6948b47b10 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_root diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.out new file mode 100644 index 0000000000..6948b47b10 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/BUILD.out @@ -0,0 +1 @@ +# gazelle:python_root diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.in new file mode 100644 index 0000000000..be5aae68f0 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.in @@ -0,0 +1,3 @@ +# proj1 depends on proj2 +# So we have to make sure that proj2 is visible by proj1 +# gazelle:python_default_visibility //$python_root:__subpackages__,//test8_multiple_python_root_dirs/proj1/src:__subpackages__ diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.out new file mode 100644 index 0000000000..d6942c4e33 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/BUILD.out @@ -0,0 +1,16 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# proj1 depends on proj2 +# So we have to make sure that proj2 is visible by proj1 +# gazelle:python_default_visibility //$python_root:__subpackages__,//test8_multiple_python_root_dirs/proj1/src:__subpackages__ + +py_library( + name = "pkg2", + srcs = ["file2.py"], + imports = [".."], + visibility = [ + "//test8_multiple_python_root_dirs/proj1/src:__subpackages__", + "//test8_multiple_python_root_dirs/proj2/src:__subpackages__", + "//tests:__pkg__", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/file2.py b/gazelle/python/testdata/directive_python_default_visibility/test8_multiple_python_root_dirs/proj2/src/pkg2/file2.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.in new file mode 100644 index 0000000000..44e23ed1c4 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_default_visibility //tests:__pkg__ diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.out new file mode 100644 index 0000000000..69587b1b2a --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/BUILD.out @@ -0,0 +1,9 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_default_visibility //tests:__pkg__ + +py_library( + name = "test9_default_vis_with_python_vis", + srcs = ["test9.py"], + visibility = ["//tests:__pkg__"], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.in new file mode 100644 index 0000000000..6e484ffb55 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.in @@ -0,0 +1 @@ +# gazelle:python_visibility //some/new:target diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.out new file mode 100644 index 0000000000..6b7f7c3bcd --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/BUILD.out @@ -0,0 +1,12 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_visibility //some/new:target + +py_library( + name = "subpkg1", + srcs = ["foo.py"], + visibility = [ + "//some/new:target", + "//tests:__pkg__", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/foo.py b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg1/foo.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.in b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.in new file mode 100644 index 0000000000..912134a5b8 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.in @@ -0,0 +1,3 @@ +# gazelle:python_default_visibility //a:b,//a:c +# gazelle:python_visibility //c:d +# gazelle:python_visibility //e:f diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.out b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.out new file mode 100644 index 0000000000..a43fc0ca86 --- /dev/null +++ b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/BUILD.out @@ -0,0 +1,16 @@ +load("@rules_python//python:defs.bzl", "py_library") + +# gazelle:python_default_visibility //a:b,//a:c +# gazelle:python_visibility //c:d +# gazelle:python_visibility //e:f + +py_library( + name = "subpkg2", + srcs = ["foo.py"], + visibility = [ + "//a:b", + "//a:c", + "//c:d", + "//e:f", + ], +) diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/foo.py b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/subpkg2/foo.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/test9.py b/gazelle/python/testdata/directive_python_default_visibility/test9_default_vis_with_python_vis/test9.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/gazelle/pythonconfig/pythonconfig.go b/gazelle/pythonconfig/pythonconfig.go index e350a7cb60..a0bc9f689d 100644 --- a/gazelle/pythonconfig/pythonconfig.go +++ b/gazelle/pythonconfig/pythonconfig.go @@ -67,6 +67,9 @@ const ( // naming convention. See python_library_naming_convention for more info on // the package name interpolation. TestNamingConvention = "python_test_naming_convention" + // DefaultVisibilty represents the directive that controls what visibility + // labels are added to generated python targets. + DefaultVisibilty = "python_default_visibility" // Visibility represents the directive that controls what additional // visibility labels are added to generated targets. It mimics the behavior // of the `go_visibility` directive. @@ -93,6 +96,11 @@ const ( packageNameNamingConventionSubstitution = "$package_name$" ) +// The default visibility label, including a format placeholder for `python_root`. +const ( + DefaultVisibilityFmtString = "//%s:__subpackages__" +) + // defaultIgnoreFiles is the list of default values used in the // python_ignore_files option. var defaultIgnoreFiles = map[string]struct{}{ @@ -140,6 +148,7 @@ type Config struct { libraryNamingConvention string binaryNamingConvention string testNamingConvention string + defaultVisibility []string visibility []string } @@ -162,6 +171,7 @@ func New( libraryNamingConvention: packageNameNamingConventionSubstitution, binaryNamingConvention: fmt.Sprintf("%s_bin", packageNameNamingConventionSubstitution), testNamingConvention: fmt.Sprintf("%s_test", packageNameNamingConventionSubstitution), + defaultVisibility: []string{fmt.Sprintf(DefaultVisibilityFmtString, "")}, visibility: []string{}, } } @@ -189,6 +199,7 @@ func (c *Config) NewChild() *Config { libraryNamingConvention: c.libraryNamingConvention, binaryNamingConvention: c.binaryNamingConvention, testNamingConvention: c.testNamingConvention, + defaultVisibility: c.defaultVisibility, visibility: c.visibility, } } @@ -246,7 +257,6 @@ func (c *Config) FindThirdPartyDependency(modName string) (string, bool) { } sanitizedDistribution := SanitizeDistribution(distributionName) - // @// lbl := label.New(distributionRepositoryName, sanitizedDistribution, sanitizedDistribution) return lbl.String(), true @@ -403,5 +413,15 @@ func (c *Config) AppendVisibility(visibility string) { // Visibility returns the target's visibility. func (c *Config) Visibility() []string { - return c.visibility + return append(c.defaultVisibility, c.visibility...) +} + +// SetDefaultVisibility sets the default visibility of the target. +func (c *Config) SetDefaultVisibility(visibility []string) { + c.defaultVisibility = visibility +} + +// DefaultVisibilty returns the target's default visibility. +func (c *Config) DefaultVisibilty() []string { + return c.defaultVisibility }