Skip to content

Commit

Permalink
internal/language/proto: disable_global mode
Browse files Browse the repository at this point in the history
Similar to disable mode in that no proto_library or go_proto_library
rules will be generated. Additionally, all special cases for WKTs and
Google APIs in the dependency resolution will be disabled. This is
useful for avoiding build-time dependencies on protoc.

Related bazel-contrib/rules_go#1548
  • Loading branch information
Jay Conrod committed Jul 3, 2018
1 parent 79cf429 commit f58265c
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 105 deletions.
155 changes: 79 additions & 76 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -230,82 +230,82 @@ Subdirectories will be processed recursively.

The following flags are accepted:

+-----------------------------------------------+-----------------------------------+
| **Name** | **Default value** |
+===============================================+===================================+
| :flag:`-build_file_name file1,file2,...` | :value:`BUILD.bazel,BUILD` |
+-----------------------------------------------+-----------------------------------+
| Comma-separated list of file names. Gazelle recognizes these files as Bazel |
| build files. New files will use the first name in this list. Use this if |
| your project contains non-Bazel files named ``BUILD`` (or ``build`` on |
| case-insensitive file systems). |
+-----------------------------------------------+-----------------------------------+
| :flag:`-build_tags tag1,tag2` | |
+-----------------------------------------------+-----------------------------------+
| List of Go build tags Gazelle will consider to be true. Gazelle applies |
| constraints when generating Go rules. It assumes certain tags are true on |
| certain platforms (for example, ``amd64,linux``). It assumes all Go release |
| tags are true (for example, ``go1.8``). It considers other tags to be false |
| (for example, ``ignore``). This flag overrides that behavior. |
| |
| Bazel may still filter sources with these tags. Use |
| ``bazel build --features gotags=foo,bar`` to set tags at build time. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-external external|vendored` | :value:`external` |
+-----------------------------------------------+-----------------------------------+
| Determines how Gazelle resolves import paths. May be :value:`external` or |
| :value:`vendored`. Gazelle translates Go import paths to Bazel labels when |
| resolving library dependencies. Import paths that start with the |
| ``go_prefix`` are resolved to local labels, but other imports |
| are resolved based on this mode. In :value:`external` mode, paths are |
| resolved using an external dependency in the WORKSPACE file (Gazelle does |
| not create or maintain these dependencies yet). In :value:`vendored` mode, |
| paths are resolved to a library in the vendor directory. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-go_prefix example.com/repo` | |
+-----------------------------------------------+-----------------------------------+
| A prefix of import paths for libraries in the repository that corresponds to |
| the repository root. Gazelle infers this from the ``go_prefix`` rule in the |
| root BUILD.bazel file, if it exists. If not, this option is mandatory. |
| |
| This prefix is used to determine whether an import path refers to a library |
| in the current repository or an external dependency. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-known_import example.com` | |
+-----------------------------------------------+-----------------------------------+
| Skips import path resolution for a known domain. May be repeated. |
| |
| When Gazelle resolves an import path to an external dependency, it attempts |
| to discover the remote repository root over HTTP. Gazelle skips this |
| discovery step for a few well-known domains with predictable structure, like |
| golang.org and github.com. This flag specifies additional domains to skip, |
| which is useful in situations where the lookup would fail for some reason. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-mode fix|print|diff` | :value:`fix` |
+-----------------------------------------------+-----------------------------------+
| Method for emitting merged build files. |
| |
| In ``fix`` mode, Gazelle writes generated and merged files to disk. In |
| ``print`` mode, it prints them to stdout. In ``diff`` mode, it prints a |
| unified diff. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-proto default|package|legacy|disable` | :value:`default` |
+-----------------------------------------------+-----------------------------------+
| Determines how Gazelle should generate rules for .proto files. See details |
| in `Directives`_ below. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-proto_group group` | :value:`""` |
+-----------------------------------------------+-----------------------------------+
| Determines the proto option Gazelle uses to group .proto files into rules |
| when in ``package`` mode. See details in `Directives`_ below. |
+-----------------------------------------------+-----------------------------------+
| :flag:`-repo_root dir` | |
+-----------------------------------------------+-----------------------------------+
| The root directory of the repository. Gazelle normally infers this to be the |
| directory containing the WORKSPACE file. |
| |
| Gazelle will not process packages outside this directory. |
+-----------------------------------------------+-----------------------------------+
+--------------------------------------------------------------+-----------------------------------+
| **Name** | **Default value** |
+==============================================================+===================================+
| :flag:`-build_file_name file1,file2,...` | :value:`BUILD.bazel,BUILD` |
+--------------------------------------------------------------+-----------------------------------+
| Comma-separated list of file names. Gazelle recognizes these files as Bazel |
| build files. New files will use the first name in this list. Use this if |
| your project contains non-Bazel files named ``BUILD`` (or ``build`` on |
| case-insensitive file systems). |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-build_tags tag1,tag2` | |
+--------------------------------------------------------------+-----------------------------------+
| List of Go build tags Gazelle will consider to be true. Gazelle applies |
| constraints when generating Go rules. It assumes certain tags are true on |
| certain platforms (for example, ``amd64,linux``). It assumes all Go release |
| tags are true (for example, ``go1.8``). It considers other tags to be false |
| (for example, ``ignore``). This flag overrides that behavior. |
| |
| Bazel may still filter sources with these tags. Use |
| ``bazel build --features gotags=foo,bar`` to set tags at build time. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-external external|vendored` | :value:`external` |
+--------------------------------------------------------------+-----------------------------------+
| Determines how Gazelle resolves import paths. May be :value:`external` or |
| :value:`vendored`. Gazelle translates Go import paths to Bazel labels when |
| resolving library dependencies. Import paths that start with the |
| ``go_prefix`` are resolved to local labels, but other imports |
| are resolved based on this mode. In :value:`external` mode, paths are |
| resolved using an external dependency in the WORKSPACE file (Gazelle does |
| not create or maintain these dependencies yet). In :value:`vendored` mode, |
| paths are resolved to a library in the vendor directory. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-go_prefix example.com/repo` | |
+--------------------------------------------------------------+-----------------------------------+
| A prefix of import paths for libraries in the repository that corresponds to |
| the repository root. Gazelle infers this from the ``go_prefix`` rule in the |
| root BUILD.bazel file, if it exists. If not, this option is mandatory. |
| |
| This prefix is used to determine whether an import path refers to a library |
| in the current repository or an external dependency. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-known_import example.com` | |
+--------------------------------------------------------------+-----------------------------------+
| Skips import path resolution for a known domain. May be repeated. |
| |
| When Gazelle resolves an import path to an external dependency, it attempts |
| to discover the remote repository root over HTTP. Gazelle skips this |
| discovery step for a few well-known domains with predictable structure, like |
| golang.org and github.com. This flag specifies additional domains to skip, |
| which is useful in situations where the lookup would fail for some reason. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-mode fix|print|diff` | :value:`fix` |
+--------------------------------------------------------------+-----------------------------------+
| Method for emitting merged build files. |
| |
| In ``fix`` mode, Gazelle writes generated and merged files to disk. In |
| ``print`` mode, it prints them to stdout. In ``diff`` mode, it prints a |
| unified diff. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-proto default|package|legacy|disable|disable_global` | :value:`default` |
+--------------------------------------------------------------+-----------------------------------+
| Determines how Gazelle should generate rules for .proto files. See details |
| in `Directives`_ below. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-proto_group group` | :value:`""` |
+--------------------------------------------------------------+-----------------------------------+
| Determines the proto option Gazelle uses to group .proto files into rules |
| when in ``package`` mode. See details in `Directives`_ below. |
+--------------------------------------------------------------+-----------------------------------+
| :flag:`-repo_root dir` | |
+--------------------------------------------------------------+-----------------------------------+
| The root directory of the repository. Gazelle normally infers this to be the |
| directory containing the WORKSPACE file. |
| |
| Gazelle will not process packages outside this directory. |
+--------------------------------------------------------------+-----------------------------------+

``update-repos``
~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -494,6 +494,9 @@ The following directives are recognized:
| * ``disable``: .proto files are ignored. Gazelle will run in this mode |
| automatically if ``go_proto_library`` is loaded from any other source, |
| but this can be overridden with a directive. |
| * ``disable_global``: like ``disable`` mode, but also prevents Gazelle from |
| using any special cases in dependency resolution for Well Known Types and |
| Google APIs. Useful for avoiding build-time dependencies on protoc. |
| |
| This directive applies to the current directory and subdirectories. As a |
| special case, when Gazelle enters a directory named ``vendor``, if the proto |
Expand Down
32 changes: 14 additions & 18 deletions internal/language/go/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,21 @@ func (gl *goLang) GenerateRules(c *config.Config, dir, rel string, f *rule.File,
// files and generate go_proto_library rules.
gc := getGoConfig(c)
pc := proto.GetProtoConfig(c)
var protoPackages map[string]proto.Package
var protoFileInfo map[string]proto.FileInfo
var protoRuleNames []string
if pc.Mode != proto.DisableMode {
protoPackages = make(map[string]proto.Package)
protoFileInfo = make(map[string]proto.FileInfo)
for _, r := range otherGen {
if r.Kind() != "proto_library" {
continue
}
pkg := r.PrivateAttr(proto.PackageKey).(proto.Package)
protoPackages[r.Name()] = pkg
for name, info := range pkg.Files {
protoFileInfo[name] = info
}
protoRuleNames = append(protoRuleNames, r.Name())
protoPackages := make(map[string]proto.Package)
protoFileInfo := make(map[string]proto.FileInfo)
for _, r := range otherGen {
if r.Kind() != "proto_library" {
continue
}
pkg := r.PrivateAttr(proto.PackageKey).(proto.Package)
protoPackages[r.Name()] = pkg
for name, info := range pkg.Files {
protoFileInfo[name] = info
}
sort.Strings(protoRuleNames)
protoRuleNames = append(protoRuleNames, r.Name())
}
sort.Strings(protoRuleNames)
var emptyProtoRuleNames []string
for _, r := range otherEmpty {
if r.Kind() == "proto_library" {
Expand All @@ -64,7 +60,7 @@ func (gl *goLang) GenerateRules(c *config.Config, dir, rel string, f *rule.File,

// If proto rule generation is enabled, exclude .pb.go files that correspond
// to any .proto files present.
if pc.Mode != proto.DisableMode && pc.Mode != proto.LegacyMode {
if !pc.Mode.ShouldIncludePregeneratedFiles() {
keep := func(f string) bool {
if strings.HasSuffix(f, ".pb.go") {
_, ok := protoFileInfo[strings.TrimSuffix(f, ".pb.go")+".proto"]
Expand Down Expand Up @@ -369,7 +365,7 @@ func newGenerator(c *config.Config, f *rule.File, rel string) *generator {
}

func (g *generator) generateProto(mode proto.Mode, target protoTarget, importPath string) (string, []*rule.Rule) {
if mode == proto.DisableMode {
if !mode.ShouldGenerateRules() {
// Don't create or delete proto rules in this mode. Any existing rules
// are likely hand-written.
return "", nil
Expand Down
16 changes: 10 additions & 6 deletions internal/language/go/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/bazelbuild/bazel-gazelle/internal/config"
"github.com/bazelbuild/bazel-gazelle/internal/label"
"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
"github.com/bazelbuild/bazel-gazelle/internal/pathtools"
"github.com/bazelbuild/bazel-gazelle/internal/repos"
"github.com/bazelbuild/bazel-gazelle/internal/resolve"
Expand Down Expand Up @@ -71,9 +72,8 @@ func (gl *goLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repos.Rem
if r.Kind() == "go_proto_library" {
resolve = resolveProto
}
gc := getGoConfig(c)
deps, errs := imports.Map(func(imp string) (string, error) {
l, err := resolve(gc, ix, rc, r, imp, from)
l, err := resolve(c, ix, rc, r, imp, from)
if err == skipImportError {
return "", nil
} else if err != nil {
Expand All @@ -100,7 +100,9 @@ var (
notFoundError = errors.New("rule not found")
)

func resolveGo(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
gc := getGoConfig(c)
pc := proto.GetProtoConfig(c)
if build.IsLocalImport(imp) {
cleanRel := path.Clean(path.Join(from.Pkg, imp))
if build.IsLocalImport(cleanRel) {
Expand All @@ -113,7 +115,7 @@ func resolveGo(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *ru
return label.NoLabel, skipImportError
}

if l, ok := knownGoProtoImports[imp]; ok {
if l, ok := knownGoProtoImports[imp]; ok && pc.Mode.ShouldUseKnownImports() {
return l, nil
}

Expand Down Expand Up @@ -211,12 +213,14 @@ func resolveVendored(rc *repos.RemoteCache, imp string) (label.Label, error) {
return label.New("", path.Join("vendor", imp), config.DefaultLibName), nil
}

func resolveProto(gc *goConfig, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
func resolveProto(c *config.Config, ix *resolve.RuleIndex, rc *repos.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
pc := proto.GetProtoConfig(c)

if wellKnownProtos[imp] {
return label.NoLabel, skipImportError
}

if l, ok := knownProtoImports[imp]; ok {
if l, ok := knownProtoImports[imp]; ok && pc.Mode.ShouldUseKnownImports() {
if l.Equal(from) {
return label.NoLabel, skipImportError
} else {
Expand Down
Loading

0 comments on commit f58265c

Please sign in to comment.