From 6231478988f0a0b751a436d57d38bc09c1dcfdca Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Fri, 7 Dec 2018 17:06:44 -0500 Subject: [PATCH] gazelle_binary: create gazelle binaries with custom languages (#365) gazelle_binary is a new rule that creates binaries to be used with the gazelle rule. It accepts a list of languages (the default languages are proto and go). It generates a .go source file that imports the language packages and initializes each extension. That source file is compiled into the main package in a new gazelle binary. The rest of the main package does not reference any specific languages. Fixes #311 --- README.rst | 11 +- cmd/gazelle/BUILD.bazel | 51 +++--- cmd/gazelle/langs.go | 4 +- def.bzl | 28 ++- extend.rst | 163 ++++++++++++++++++ internal/gazelle_binary.bzl | 151 ++++++++++++++++ internal/gazellebinarytest/BUILD.bazel | 36 ++++ .../gazellebinarytest/gazellebinary_test.go | 85 +++++++++ internal/gazellebinarytest/xlang.go | 82 +++++++++ language/go/config_test.go | 2 +- language/go/lang.go | 2 +- language/proto/generate_test.go | 6 +- language/proto/lang.go | 2 +- merger/merger_test.go | 2 +- 14 files changed, 583 insertions(+), 42 deletions(-) create mode 100644 extend.rst create mode 100644 internal/gazelle_binary.bzl create mode 100644 internal/gazellebinarytest/BUILD.bazel create mode 100644 internal/gazellebinarytest/gazellebinary_test.go create mode 100644 internal/gazellebinarytest/xlang.go diff --git a/README.rst b/README.rst index 0c4217c68..7ddd1b66c 100644 --- a/README.rst +++ b/README.rst @@ -12,6 +12,9 @@ Gazelle build file generator .. _update: #fix-and-update .. _Avoiding conflicts with proto rules: https://github.com/bazelbuild/rules_go/blob/master/proto/core.rst#avoiding-conflicts .. _gazelle rule: #bazel-rule +.. _Extending Gazelle: extend.rst +.. _extended: `Extending Gazelle`_ +.. _gazelle_binary: extend.rst#gazelle_binary .. role:: cmd(code) .. role:: flag(code) @@ -27,7 +30,8 @@ files for a project that follows "go build" conventions, and it can update existing build files to include new sources, dependencies, and options. Gazelle may be run by Bazel using the `gazelle rule`_, or it can be run as a command line tool. Gazelle can also be run in an external repository as part of the -`go_repository`_ rule. +`go_repository`_ rule. Gazelle may be extended_ to support new languages +and custom rule sets. *Gazelle is under active development. Its interface and the rules it generates may change. Gazelle is not an official Google product.* @@ -44,6 +48,7 @@ may change. Gazelle is not an official Google product.* * `git_repository`_ (deprecated) * `http_archive`_ (deprecated) +* `Extending Gazelle`_ * `Avoiding conflicts with proto rules`_ Setup @@ -198,8 +203,8 @@ The following attributes are available on the ``gazelle`` rule. +======================+=====================+======================================+ | :param:`gazelle` | :type:`label` | :value:`@bazel_gazelle//cmd/gazelle` | +----------------------+---------------------+--------------------------------------+ -| The ``go_binary`` rule that builds Gazelle. You can substitute a modified | -| version of Gazelle with this. | +| The `gazelle_binary`_ rule that builds Gazelle. You can substitute a modified | +| version of Gazelle with this. See `Extending Gazelle`_. | +----------------------+---------------------+--------------------------------------+ | :param:`external` | :type:`string` | :value:`external` | +----------------------+---------------------+--------------------------------------+ diff --git a/cmd/gazelle/BUILD.bazel b/cmd/gazelle/BUILD.bazel index ed6768b09..65164df37 100644 --- a/cmd/gazelle/BUILD.bazel +++ b/cmd/gazelle/BUILD.bazel @@ -1,19 +1,42 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle_binary") + +gazelle_binary( + name = "gazelle", + languages = DEFAULT_LANGUAGES, + msan = "off", + pure = "off", + race = "off", + static = "off", + visibility = ["//visibility:public"], +) + +gazelle_binary( + name = "gazelle_pure", + languages = DEFAULT_LANGUAGES, + msan = "off", + pure = "on", + race = "off", + static = "off", + tags = ["manual"], + visibility = ["//visibility:public"], +) go_library( name = "go_default_library", + # keep srcs = [ "diff.go", "fix.go", "fix-update.go", "gazelle.go", - "langs.go", "print.go", "update-repos.go", "version.go", ], importpath = "github.com/bazelbuild/bazel-gazelle/cmd/gazelle", - visibility = ["//visibility:private"], + tags = ["manual"], + visibility = ["//visibility:public"], deps = [ "//config:go_default_library", "//flag:go_default_library", @@ -31,27 +54,6 @@ go_library( ], ) -go_binary( - name = "gazelle", - embed = [":go_default_library"], - msan = "off", - pure = "off", - race = "off", - static = "off", - visibility = ["//visibility:public"], -) - -go_binary( - name = "gazelle_pure", - embed = [":go_default_library"], - msan = "off", - pure = "on", - race = "off", - static = "off", - tags = ["manual"], - visibility = ["//visibility:public"], -) - go_test( name = "go_default_test", size = "small", @@ -59,6 +61,7 @@ go_test( "diff_test.go", "fix_test.go", "integration_test.go", + "langs.go", # keep ], embed = [":go_default_library"], deps = [ diff --git a/cmd/gazelle/langs.go b/cmd/gazelle/langs.go index dc3968ff6..0f8e11255 100644 --- a/cmd/gazelle/langs.go +++ b/cmd/gazelle/langs.go @@ -22,6 +22,6 @@ import ( ) var languages = []language.Language{ - proto.New(), - golang.New(), + proto.NewLanguage(), + golang.NewLanguage(), } diff --git a/def.bzl b/def.bzl index 2ba15306c..c51c0509a 100644 --- a/def.bzl +++ b/def.bzl @@ -17,17 +17,33 @@ load( _go_context = "go_context", _go_rule = "go_rule", ) -load("@bazel_skylib//lib:shell.bzl", "shell") -load("//internal:go_repository.bzl", _go_repository = "go_repository") +load( + "@bazel_skylib//lib:shell.bzl", + "shell", +) +load( + "//internal:go_repository.bzl", + _go_repository = "go_repository", +) load( "//internal:overlay_repository.bzl", _git_repository = "git_repository", _http_archive = "http_archive", ) +load( + "//internal:gazelle_binary.bzl", + _gazelle_binary = "gazelle_binary", +) go_repository = _go_repository git_repository = _git_repository http_archive = _http_archive +gazelle_binary = _gazelle_binary + +DEFAULT_LANGUAGES = [ + "@bazel_gazelle//language/proto:go_default_library", + "@bazel_gazelle//language/go:go_default_library", +] def _gazelle_runner_impl(ctx): go = _go_context(ctx) @@ -35,9 +51,9 @@ def _gazelle_runner_impl(ctx): ctx.attr.command, "-mode", ctx.attr.mode, - "-external", - ctx.attr.external, ] + if ctx.attr.external: + args.extend(["-external", ctx.attr.external]) if ctx.attr.prefix: args.extend(["-go_prefix", ctx.attr.prefix]) if ctx.attr.build_tags: @@ -89,8 +105,8 @@ _gazelle_runner = _go_rule( default = "fix", ), "external": attr.string( - values = ["external", "vendored"], - default = "external", + values = ["", "external", "vendored"], + default = "", ), "build_tags": attr.string_list(), "prefix": attr.string(), diff --git a/extend.rst b/extend.rst new file mode 100644 index 000000000..96c1f7444 --- /dev/null +++ b/extend.rst @@ -0,0 +1,163 @@ +Extending Gazelle +================= + +.. Begin directives +.. _Language: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language#Language +.. _`//internal/gazellebinarytest:go_default_library`: https://github.com/bazelbuild/bazel-gazelle/tree/master/internal/gazellebinarytest +.. _`//language/go:go_default_library`: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/go +.. _`//language/proto:go_default_library`: https://github.com/bazelbuild/bazel-gazelle/tree/master/language/proto +.. _gazelle: https://github.com/bazelbuild/bazel-gazelle#bazel-rule +.. _go_binary: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-binary +.. _go_library: https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#go-library +.. _proto godoc: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto +.. _proto.GetProtoConfig: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#GetProtoConfig +.. _proto.Package: https://godoc.org/github.com/bazelbuild/bazel-gazelle/language/proto#Package + +.. role:: cmd(code) +.. role:: flag(code) +.. role:: direc(code) +.. role:: param(kbd) +.. role:: type(emphasis) +.. role:: value(code) +.. |mandatory| replace:: **mandatory value** +.. End directives + +Gazelle started out as a build file generator for Go projects, but it can be +extended to support other languages and custom sets of rules. + +To extend Gazelle, you must do three things: + +* Write a `go_library`_ with a function named ``NewLanguage`` that provides an + implementation of the Language_ interface. This interface provides hooks for + generating rules, parsing configuration directives, and resolving imports + to Bazel labels. +* Write a `gazelle_binary`_ rule. Include your library in the ``languages`` + list. +* Write a `gazelle`_ rule that points to your ``gazelle_binary``. When you run + ``bazel run //:gazelle``, your binary will be built and executed instead of + the default binary. + +Example +------- + +**TODO:** Add a self-contained, concise, realistic example. + +Gazelle itself is built using the model described above, so it may serve as +an example. + +`//language/proto:go_default_library`_ and `//language/go:go_default_library`_ +both implement the `Language`_ +interface. There is also `//internal/gazellebinarytest:go_default_library`_, +a stub implementation used for testing. + +``//cmd/gazelle`` is a ``gazelle_binary`` rule that includes both of these +libraries through the ``DEFAULT_LANGUAGES`` list (you may want to use +``DEFAULT_LANGUAGES`` in your own rule). The ``msan``, ``pure``, ``race``, +and ``static`` attributes are optional. + +.. code:: bzl + + load("@bazel_gazelle//:def.bzl", "DEFAULT_LANGUAGES", "gazelle_binary") + + gazelle_binary( + name = "gazelle", + languages = DEFAULT_LANGUAGES, + msan = "off", + pure = "off", + race = "off", + static = "off", + visibility = ["//visibility:public"], + ) + +This binary can be invoked using a ``gazelle`` rule like this: + +.. code:: bzl + + load("@bazel_gazelle//:def.bzl", "gazelle") + + # gazelle:prefix example.com/project + gazelle( + name = "gazelle", + gazelle = "//:my_gazelle_binary", + ) + +You can run this with ``bazel run //:gazelle``. + +gazelle_binary +-------------- + +The ``gazelle_binary`` rule builds a Go binary that incorporates a list of +language extensions. This requires generating a small amount of code that +must be compiled into Gazelle's main package, so the normal `go_binary`_ +rule is not used. + +When the binary runs, each language extension is run sequentially. This affects +the order that rules appear in generated build files. Metadata may be produced +by an earlier extension and consumed by a later extension. For example, the +proto extension stores metadata in hidden attributes of generated +``proto_library`` rules. The Go extension uses this metadata to generate +``go_proto_library`` rules. + +The following attributes are supported on the ``gazelle_binary`` rule. + ++----------------------+---------------------+--------------------------------------+ +| **Name** | **Type** | **Default value** | ++======================+=====================+======================================+ +| :param:`languages` | :type:`label_list` | |mandatory| | ++----------------------+---------------------+--------------------------------------+ +| A list of language extensions the Gazelle binary will use. | +| | +| Each extension must be a `go_library`_ or something compatible. Each extension | +| must export a function named ``NewLanguage`` with no parameters that returns | +| a value assignable to `Language`_. | ++----------------------+---------------------+--------------------------------------+ +| :param:`pure` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ +| :param:`static` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ +| :param:`race` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ +| :param:`msan` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ +| :param:`goos` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ +| :param:`goarch` | :type:`string` | :value:`auto` | ++----------------------+---------------------+--------------------------------------+ +| Same meaning as `go_binary`_. It may be necessary to set this to avoid | +| command flags that affect both host and target configurations. | ++----------------------+---------------------+--------------------------------------+ + +Interacting with protos +----------------------- + +The proto extension (`//language/proto:go_default_library`_) gathers metadata +from .proto files and generates ``proto_library`` rules based on that metadata. +Extensions that generate language-specific proto rules (e.g., +``go_proto_library``) may use this metadata. + +For API reference, see the `proto godoc`_. + +To get proto configuration information, call `proto.GetProtoConfig`_. This is +mainly useful for discovering the current proto mode. + +To get information about ``proto_library`` rules, examine the ``OtherGen`` +list of rules passed to ``language.GenerateRules``. This is a list of rules +generated by other language extensions, and it will include ``proto_library`` +rules in each directory, if there were any. For each of these rules, you can +call ``r.PrivateAttr(proto.PackageKey)`` to get a `proto.Package`_ record. This +includes the proto package name, as well as source names, imports, and options. diff --git a/internal/gazelle_binary.bzl b/internal/gazelle_binary.bzl new file mode 100644 index 000000000..482081ac5 --- /dev/null +++ b/internal/gazelle_binary.bzl @@ -0,0 +1,151 @@ +# Copyright 2018 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. + +load( + "@io_bazel_rules_go//go:def.bzl", + "GoArchive", + "go_context", + "go_rule", +) +load( + "@io_bazel_rules_go//go/private:rules/aspect.bzl", + "go_archive_aspect", +) +load( + "@io_bazel_rules_go//go/platform:list.bzl", + "GOARCH", + "GOOS", +) + +def _gazelle_binary_impl(ctx): + go = go_context(ctx) + + # Generate a source file with a list of languages. This will get compiled + # with the rest of the sources in the main package. + langs_file = go.declare_file(go, "langs.go") + langs_content_tpl = """ +package main + +import ( + "github.com/bazelbuild/bazel-gazelle/language" + + {lang_imports} +) + +var languages = []language.Language{{ + {lang_calls}, +}} +""" + lang_imports = [_format_import(d[GoArchive].data.importpath) for d in ctx.attr.languages] + lang_calls = [_format_call(d[GoArchive].data.importpath) for d in ctx.attr.languages] + langs_content = langs_content_tpl.format( + lang_imports = "\n\t".join(lang_imports), + lang_calls = ",\n\t".join(lang_calls), + ) + go.actions.write(langs_file, langs_content) + + # Build the gazelle binary. + library = go.new_library(go) + attr = struct( + srcs = [struct(files = [langs_file])], + deps = ctx.attr.languages, + embed = [ctx.attr._srcs], + ) + source = go.library_to_source(go, attr, library, ctx.coverage_instrumented()) + + archive, executable, runfiles = go.binary( + go, + name = ctx.label.name, + source = source, + version_file = ctx.version_file, + info_file = ctx.info_file, + ) + + return [ + library, + source, + archive, + OutputGroupInfo(compilation_outputs = [archive.data.file]), + DefaultInfo( + files = depset([executable]), + runfiles = runfiles, + executable = executable, + ), + ] + +gazelle_binary = go_rule( + implementation = _gazelle_binary_impl, + attrs = { + "languages": attr.label_list( + doc = "A list of language extensions the Gazelle binary will use", + providers = [GoArchive], + mandatory = True, + allow_empty = False, + aspects = [go_archive_aspect], + ), + "pure": attr.string( + values = [ + "on", + "off", + "auto", + ], + default = "auto", + ), + "static": attr.string( + values = [ + "on", + "off", + "auto", + ], + default = "auto", + ), + "race": attr.string( + values = [ + "on", + "off", + "auto", + ], + default = "auto", + ), + "msan": attr.string( + values = [ + "on", + "off", + "auto", + ], + default = "auto", + ), + "goos": attr.string( + values = GOOS.keys() + ["auto"], + default = "auto", + ), + "goarch": attr.string( + values = GOARCH.keys() + ["auto"], + default = "auto", + ), + "_srcs": attr.label( + default = "//cmd/gazelle:go_default_library", + aspects = [go_archive_aspect], + ), + }, + executable = True, +) + +def _format_import(importpath): + _, _, base = importpath.rpartition("/") + return '{} "{}"'.format(base + "_", importpath) + +def _format_call(importpath): + _, _, base = importpath.rpartition("/") + return "{}.NewLanguage()".format(base + "_") diff --git a/internal/gazellebinarytest/BUILD.bazel b/internal/gazellebinarytest/BUILD.bazel new file mode 100644 index 000000000..f5a3bebc9 --- /dev/null +++ b/internal/gazellebinarytest/BUILD.bazel @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("//:def.bzl", "gazelle_binary") + +gazelle_binary( + name = "gazelle_go_x", + # keep + languages = [ + "//language/go:go_default_library", + ":go_default_library", + ], +) + +go_library( + name = "go_default_library", + srcs = ["xlang.go"], + importpath = "github.com/bazelbuild/bazel-gazelle/internal/gazellebinarytest", + visibility = ["//:__subpackages__"], + deps = [ + "//config:go_default_library", + "//label:go_default_library", + "//language:go_default_library", + "//repo:go_default_library", + "//resolve:go_default_library", + "//rule:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["gazellebinary_test.go"], + args = ["-gazelle=$(location :gazelle_go_x)"], + data = [":gazelle_go_x"], + embed = [":go_default_library"], + rundir = ".", + deps = ["//testtools:go_default_library"], +) diff --git a/internal/gazellebinarytest/gazellebinary_test.go b/internal/gazellebinarytest/gazellebinary_test.go new file mode 100644 index 000000000..c3fda293e --- /dev/null +++ b/internal/gazellebinarytest/gazellebinary_test.go @@ -0,0 +1,85 @@ +/* Copyright 2018 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. +*/ + +package gazellebinarytest + +import ( + "flag" + "log" + "os" + "os/exec" + "path/filepath" + "testing" + + "github.com/bazelbuild/bazel-gazelle/testtools" +) + +var ( + gazellePath = flag.String("gazelle", "", "path to gazelle binary") +) + +func TestMain(m *testing.M) { + _, ok := os.LookupEnv("TEST_TARGET") + if !ok { + // Skip all tests if we aren't run by Bazel + return + } + + flag.Parse() + if abs, err := filepath.Abs(*gazellePath); err != nil { + log.Fatalf("unable to find absolute path for gazelle: %v\n", err) + os.Exit(1) + } else { + *gazellePath = abs + } + os.Exit(m.Run()) +} + +func TestGazelleBinary(t *testing.T) { + files := []testtools.FileSpec{ + {Path: "WORKSPACE"}, + {Path: "BUILD.bazel", Content: "# gazelle:prefix example.com/test"}, + {Path: "foo.go", Content: "package foo"}, + {Path: "foo.proto", Content: `syntax = "proto3";`}, + } + dir, cleanup := testtools.CreateFiles(t, files) + defer cleanup() + + cmd := exec.Command(*gazellePath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Dir = dir + if err := cmd.Run(); err != nil { + t.Fatal(err) + } + + testtools.CheckFiles(t, dir, []testtools.FileSpec{{ + Path: "BUILD.bazel", + Content: ` +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +# gazelle:prefix example.com/test + +go_library( + name = "go_default_library", + srcs = ["foo.go"], + importpath = "example.com/test", + visibility = ["//visibility:public"], +) + +x_library(name = "x_default_library") +`, + }}) +} diff --git a/internal/gazellebinarytest/xlang.go b/internal/gazellebinarytest/xlang.go new file mode 100644 index 000000000..51f44b459 --- /dev/null +++ b/internal/gazellebinarytest/xlang.go @@ -0,0 +1,82 @@ +/* Copyright 2018 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. +*/ + +// gazellebinarytest provides a minimal implementation of language.Language. +// This is used to verify that gazelle_binary builds plugins and runs them +// in the correct order. +package gazellebinarytest + +import ( + "flag" + + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/label" + "github.com/bazelbuild/bazel-gazelle/language" + "github.com/bazelbuild/bazel-gazelle/repo" + "github.com/bazelbuild/bazel-gazelle/resolve" + "github.com/bazelbuild/bazel-gazelle/rule" +) + +type xlang struct{} + +func NewLanguage() language.Language { + return &xlang{} +} + +func (x *xlang) Name() string { + return "x" +} + +func (x *xlang) Kinds() map[string]rule.KindInfo { + return map[string]rule.KindInfo{ + "x_library": {}, + } +} + +func (x *xlang) Loads() []rule.LoadInfo { + return nil +} + +func (x *xlang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) { +} + +func (x *xlang) CheckFlags(fs *flag.FlagSet, c *config.Config) error { + return nil +} + +func (x *xlang) KnownDirectives() []string { + return nil +} + +func (x *xlang) Configure(c *config.Config, rel string, f *rule.File) { +} + +func (x *xlang) GenerateRules(args language.GenerateArgs) (empty, gen []*rule.Rule) { + return nil, []*rule.Rule{rule.NewRule("x_library", "x_default_library")} +} + +func (x *xlang) Fix(c *config.Config, f *rule.File) { +} + +func (x *xlang) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec { + return nil +} + +func (x *xlang) Embeds(r *rule.Rule, from label.Label) []label.Label { + return nil +} + +func (x *xlang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, from label.Label) { +} diff --git a/language/go/config_test.go b/language/go/config_test.go index e3b413994..72b3a1e4c 100644 --- a/language/go/config_test.go +++ b/language/go/config_test.go @@ -50,7 +50,7 @@ func testConfig(t *testing.T, args ...string) (*config.Config, []language.Langua &walk.Configurer{}, &resolve.Configurer{}, } - langs := []language.Language{proto.New(), New()} + langs := []language.Language{proto.NewLanguage(), NewLanguage()} c := testtools.NewTestConfig(t, cexts, langs, args) for _, lang := range langs { cexts = append(cexts, lang) diff --git a/language/go/lang.go b/language/go/lang.go index f56ef9f20..27d50cae2 100644 --- a/language/go/lang.go +++ b/language/go/lang.go @@ -65,6 +65,6 @@ type goLang struct { func (_ *goLang) Name() string { return goName } -func New() language.Language { +func NewLanguage() language.Language { return &goLang{goPkgRels: make(map[string]bool)} } diff --git a/language/proto/generate_test.go b/language/proto/generate_test.go index 0e45f0779..f6986079a 100644 --- a/language/proto/generate_test.go +++ b/language/proto/generate_test.go @@ -81,7 +81,7 @@ func TestGenerateRules(t *testing.T) { } func TestGenerateRulesEmpty(t *testing.T) { - lang := New() + lang := NewLanguage() c := config.New() c.Exts[protoName] = &ProtoConfig{} @@ -129,7 +129,7 @@ proto_library( } func TestGeneratePackage(t *testing.T) { - lang := New() + lang := NewLanguage() c, _, _ := testConfig(t, "testdata") dir := filepath.FromSlash("testdata/protos") _, gen := lang.GenerateRules(language.GenerateArgs{ @@ -174,7 +174,7 @@ func testConfig(t *testing.T, repoRoot string) (*config.Config, language.Languag &walk.Configurer{}, &resolve.Configurer{}, } - lang := New() + lang := NewLanguage() c := testtools.NewTestConfig(t, cexts, []language.Language{lang}, []string{ "-build_file_name=BUILD.old", "-repo_root=" + repoRoot, diff --git a/language/proto/lang.go b/language/proto/lang.go index d7cd4992f..fe009df88 100644 --- a/language/proto/lang.go +++ b/language/proto/lang.go @@ -67,6 +67,6 @@ type protoLang struct{} func (_ *protoLang) Name() string { return protoName } -func New() language.Language { +func NewLanguage() language.Language { return &protoLang{} } diff --git a/merger/merger_test.go b/merger/merger_test.go index e017bde5e..2829b3c03 100644 --- a/merger/merger_test.go +++ b/merger/merger_test.go @@ -904,7 +904,7 @@ var ( func init() { testKinds = make(map[string]rule.KindInfo) - langs := []language.Language{proto.New(), golang.New()} + langs := []language.Language{proto.NewLanguage(), golang.NewLanguage()} for _, lang := range langs { for kind, info := range lang.Kinds() { testKinds[kind] = info