Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

language.GenerateResult - allow setting package(default_visibility) #783

Closed
robfig opened this issue May 15, 2020 · 6 comments · Fixed by #1341 or #1343
Closed

language.GenerateResult - allow setting package(default_visibility) #783

robfig opened this issue May 15, 2020 · 6 comments · Fixed by #1341 or #1343

Comments

@robfig
Copy link
Contributor

robfig commented May 15, 2020

The closure_js gazelle module produces one rule per source file. Presently, each one of those rules has a visibility set. Setting aside the desirability of having one rule per source file vs one rule per directory, I was interested in extracting visibility management by omitting it on the per-rule basis and setting package(default_visibility) instead when composing a new BUILD file.

There doesn't appear to be any way to set the default_visibility; GenerateResult returns only rules and imports. I propose packing the Rules into a File that is used as a template for the new BUILD file. If that breaking change to the type is unpalatable, I could instead return an additional bit for that, or an additional File type used only for that configuration.

I realize this may not be a core use case and not worth supporting, but I just thought I'd raise it as a possible addition. Thanks

@jayconrod
Copy link
Contributor

I think this would be a reasonable thing to support. It doesn't make sense for Go, but I could see it being useful for other languages, especially when there are a lot of libraries in a single directory.

The breaking change here is too much though. Syntactically, a package declaration is a function call, like a rule. Is it possible to include the package declaration with the other generated rules, or does that break something?

rule.File.HasDefaultVisibility is used by language/go and language/proto to check whether there is an existing default visibility setting. I guess the main issue is that it can't know about generated default visibility settings. So maybe there should be a new function that doesn't need a file: rule.HasDefaultVisibility(rules []*Rule) bool

@jayconrod
Copy link
Contributor

jayconrod commented May 18, 2020

Also, just brainstorming: maybe this belongs in a language-neutral extension? It could be triggered with a directive. I could see someone writing this at the top of a large subtree in a monorepo:

# gazelle:default_visibility //project:__subpackages__

Then the extension would generate this for every directory in the tree:

package(default_visibility = ["//project:__subpackages__"])

@robfig
Copy link
Contributor Author

robfig commented May 18, 2020

Both of those ideas sound pretty good.

In lieu of that, my recent update to rules_closure's Gazelle was to apply the same behavior from Go's rules to automatically set visibility using the internal directory rule:
robfig/rules_closure@fcbafcd

It seems that the internal/ directory and default_visibility directive serve a similar purpose. I wonder if applying the internal/ directory visibility should also be a language neutral behavior.

@jayconrod
Copy link
Contributor

It seems that the internal/ directory and default_visibility directive serve a similar purpose. I wonder if applying the internal/ directory visibility should also be a language neutral behavior.

It's hard to come up with a rule that works for everyone. For Go, internal has special meaning: go build will not let you import a package from an internal directory from outside that tree. But private does not have any semantic meaning to go build, though it arguably has the same meaning to humans.

This may not always be part of the directory either. I used to work on a project that was in //java/com/google/android/apps. There were a few hundred packages in there, and they were private to our subtree. There was also //java/com/google/android/libraries, which was public. We maintained package directives manually, but we could have done it automatically with a directive like this.

@dnathe4th
Copy link
Contributor

Sorry to revive an old issue but since it is still open I figured I would. I attempted to proof-of-concept the aforementioned gazelle:default_visibility language extension, but the issue I ran into is it seems that extensions can only output rules, whereas this functionality would be based on a bazel function, i.e. no name, no import, etc. Did I correctly identify this roadblock to this approach or did I misunderstand the documentation and code behind extension implementations?

@linzhp
Copy link
Contributor

linzhp commented Oct 3, 2022

I am in favor of a language-neutral directive like # gazelle:default_visibility //project:__subpackages__. Implementation wise, @dnathe4th , you should be able to create a Rule with its name being empty: https://github.com/bazelbuild/bazel-gazelle/blob/v0.27.0/rule/rule.go#L727

dnathe4th added a commit to dnathe4th/bazel-gazelle that referenced this issue Oct 5, 2022
…build#783)

Previously, the implementation of the language/go extension's GenerateRules method only considered args.File, and therefore missed scenarios where another extension (as recommended in the Issue) creates a package(default_visibility = ...)
linzhp pushed a commit that referenced this issue Oct 5, 2022
…#1341)

Previously, the implementation of the language/go extension's GenerateRules method only considered args.File, and therefore missed scenarios where another extension (as recommended in the Issue) creates a package(default_visibility = ...)
dnathe4th added a commit to dnathe4th/bazel-gazelle that referenced this issue Oct 13, 2022
…iguration via directive (bazelbuild#783)

Under a new /bazel/ subdirectory, this language-agnostic extension allows a directive to control the default_visibility templated out to all BUILD.bazel files in or under the directory. This feature is intended to allow large codebases to define hierarchical visibility defaults.
dnathe4th added a commit to dnathe4th/bazel-gazelle that referenced this issue Oct 13, 2022
…iguration (bazelbuild#783)

Under a new /bazel/ subdirectory, this language-agnostic extension allows a directive to control the default_visibility templated out to all BUILD.bazel files in or under the directory. This feature is intended to allow large codebases to define hierarchical visibility defaults.
dnathe4th added a commit to dnathe4th/bazel-gazelle that referenced this issue Oct 13, 2022
…iguration (bazelbuild#783)

Under a new /bazel/ subdirectory, this language-agnostic extension allows a directive to control the default_visibility templated out to all BUILD.bazel files in or under the directory. This feature is intended to allow large codebases to define hierarchical visibility defaults.
dnathe4th added a commit to dnathe4th/bazel-gazelle that referenced this issue Oct 13, 2022
…iguration (bazelbuild#783)

Under a new /bazel/ subdirectory, this language-agnostic extension allows a directive to control the default_visibility templated out to all BUILD.bazel files in or under the directory. This feature is intended to allow large codebases to define hierarchical visibility defaults.
linzhp pushed a commit that referenced this issue Oct 17, 2022
…iguration (#783) (#1343)

Under a new /bazel/ subdirectory, this language-agnostic extension allows a directive to control the default_visibility templated out to all BUILD.bazel files in or under the directory. This feature is intended to allow large codebases to define hierarchical visibility defaults.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants