diff --git a/BUILD b/BUILD index c0ccdcd6..bec32f56 100644 --- a/BUILD +++ b/BUILD @@ -4,6 +4,11 @@ licenses(["notice"]) package(default_visibility = ["//visibility:public"]) +# gazelle:exclude internal_deps.bzl +# gazelle:exclude internal_setup.bzl +# buildifier: disable=skylark-comment +# gazelle:exclude skylark_library.bzl + exports_files(["LICENSE"]) filegroup( @@ -45,6 +50,16 @@ bzl_library( srcs = ["bzl_library.bzl"], ) +bzl_library( + name = "version", + srcs = ["version.bzl"], +) + +bzl_library( + name = "workspace", + srcs = ["workspace.bzl"], +) + # The files needed for distribution. # TODO(aiuto): We should strip this from the release, but there is no # capability now to generate BUILD.foo from BUILD and have it appear in the diff --git a/CODEOWNERS b/CODEOWNERS index 2b22b23a..07b74fad 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,4 @@ * @c-parsons @laurentlb @jin @aiuto distribution/ @aiuto @fwe rules/ @juliexxia +gazelle/ @achew22 @jayconrod diff --git a/WORKSPACE b/WORKSPACE index a6581ec6..c79cb22b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -10,14 +10,20 @@ maybe( url = "https://github.com/bazelbuild/bazel-federation/releases/download/0.0.1/bazel_federation-0.0.1.tar.gz", ) -load("@bazel_federation//:repositories.bzl", "bazel_skylib_deps") +load("@bazel_federation//:repositories.bzl", "bazel_skylib_deps", "rules_go") bazel_skylib_deps() +rules_go() + load("@bazel_federation//setup:bazel_skylib.bzl", "bazel_skylib_setup") bazel_skylib_setup() +load("@bazel_federation//setup:rules_go.bzl", "rules_go_setup") + +rules_go_setup() + # Below this line is for documentation generation only, # and should thus not be included by dependencies on # bazel-skylib. @@ -40,3 +46,22 @@ maybe( "https://github.com/bazelbuild/rules_cc/archive/cb2dfba6746bfa3c3705185981f3109f0ae1b893.zip", ], ) + +# Provide a repository hint for Gazelle to inform it that the go package +# github.com/bazelbuild/rules_go is available from io_bazel_rules_go and it +# doesn't need to duplicatively fetch it. +# gazelle:repository go_repository name=io_bazel_rules_go importpath=github.com/bazelbuild/rules_go +http_archive( + name = "bazel_gazelle", + sha256 = "bfd86b3cbe855d6c16c6fce60d76bd51f5c8dbc9cfcaef7a2bb5c1aafd0710e8", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.0/bazel-gazelle-v0.21.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.21.0/bazel-gazelle-v0.21.0.tar.gz", + ], +) +# Another Gazelle repository hint. +# gazelle:repository go_repository name=bazel_gazelle importpath=github.com/bazelbuild/bazel-gazelle/testtools + +load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") + +gazelle_dependencies() diff --git a/gazelle/BUILD b/gazelle/BUILD new file mode 100644 index 00000000..d20212cb --- /dev/null +++ b/gazelle/BUILD @@ -0,0 +1,53 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +load("@bazel_gazelle//:def.bzl", "gazelle", "gazelle_binary") + +# gazelle:exclude testdata + +go_library( + name = "go_default_library", + srcs = ["gazelle.go"], + importpath = "github.com/bazelbuild/bazel-skylib/gazelle", + visibility = ["//visibility:public"], + deps = [ + "@bazel_gazelle//config:go_default_library", + "@bazel_gazelle//label:go_default_library", + "@bazel_gazelle//language:go_default_library", + "@bazel_gazelle//pathtools:go_default_library", + "@bazel_gazelle//repo:go_default_library", + "@bazel_gazelle//resolve:go_default_library", + "@bazel_gazelle//rule:go_default_library", + "@com_github_bazelbuild_buildtools//build:go_default_library", + ], +) + +go_test( + name = "go_default_test", + srcs = ["gazelle_test.go"], + data = [ + ":gazelle-skylib", + ] + glob([ + "testdata/**", + ]), + embed = [":go_default_library"], + deps = [ + "@bazel_gazelle//testtools:go_default_library", + "@io_bazel_rules_go//go/tools/bazel:go_default_library", + ], +) + +# This gazelle binary is used exclusively for testing the gazelle language +# extension and thus only has the skylib language installed. +gazelle_binary( + name = "gazelle-skylib", + languages = [":go_default_library"], + visibility = [ + # Also make the binary available in the root of the repo for use, but + # not externally. + "//:__pkg__", + ], +) + +gazelle( + name = "gazelle", + gazelle = "//gazelle:gazelle-skylib", +) diff --git a/gazelle/README.md b/gazelle/README.md new file mode 100644 index 00000000..8b7cb7b9 --- /dev/null +++ b/gazelle/README.md @@ -0,0 +1,13 @@ +# Gazelle + +Gazelle is a `BUILD` file generator for Bazel. This directory contains a +language extension for the Gazelle generator that allows it to automatically +parse valid `bzl_library` targets for all `.bzl` files in a repo in which it +runs. It will additionally include a `deps` entry tracking every `.bzl` that is +`load`ed into the primary file. + +This can be used, for example, to generate +[`stardoc`](https://github.com/bazelbuild/stardoc) documentation for your +`.bzl` files, both simplify the task of and improve the quality of +documentation. + diff --git a/gazelle/gazelle.go b/gazelle/gazelle.go new file mode 100644 index 00000000..b45ef3d8 --- /dev/null +++ b/gazelle/gazelle.go @@ -0,0 +1,315 @@ +/* Copyright 2020 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 gazelle generates a `bzl_library` target for every `.bzl` file in +// each package. +// +// The `bzl_library` rule is provided by +// https://github.com/bazelbuild/bazel-skylib. +// +// This extension is experimental and subject to change. It is not included +// in the default Gazelle binary. +package gazelle + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "path/filepath" + "sort" + "strings" + + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/label" + "github.com/bazelbuild/bazel-gazelle/language" + "github.com/bazelbuild/bazel-gazelle/pathtools" + "github.com/bazelbuild/bazel-gazelle/repo" + "github.com/bazelbuild/bazel-gazelle/resolve" + "github.com/bazelbuild/bazel-gazelle/rule" + + "github.com/bazelbuild/buildtools/build" +) + +const languageName = "starlark" +const fileType = ".bzl" + +var ignoreSuffix = suffixes{ + "_tests.bzl", + "_test.bzl", +} + +type suffixes []string + +func (s suffixes) Matches(test string) bool { + for _, v := range s { + if strings.HasSuffix(test, v) { + return true + } + } + return false +} + +type bzlLibraryLang struct{} + +// NewLanguage is called by Gazelle to install this language extension in a binary. +func NewLanguage() language.Language { + return &bzlLibraryLang{} +} + +// Name returns the name of the language. This should be a prefix of the +// kinds of rules generated by the language, e.g., "go" for the Go extension +// since it generates "go_library" rules. +func (*bzlLibraryLang) Name() string { return languageName } + +// The following methods are implemented to satisfy the +// https://pkg.go.dev/github.com/bazelbuild/bazel-gazelle/resolve?tab=doc#Resolver +// interface, but are otherwise unused. +func (*bzlLibraryLang) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {} +func (*bzlLibraryLang) CheckFlags(fs *flag.FlagSet, c *config.Config) error { return nil } +func (*bzlLibraryLang) KnownDirectives() []string { return nil } +func (*bzlLibraryLang) Configure(c *config.Config, rel string, f *rule.File) {} + +// Kinds returns a map of maps rule names (kinds) and information on how to +// match and merge attributes that may be found in rules of those kinds. All +// kinds of rules generated for this language may be found here. +func (*bzlLibraryLang) Kinds() map[string]rule.KindInfo { + return kinds +} + +// Loads returns .bzl files and symbols they define. Every rule generated by +// GenerateRules, now or in the past, should be loadable from one of these +// files. +func (*bzlLibraryLang) Loads() []rule.LoadInfo { + return []rule.LoadInfo{{ + Name: "@bazel_skylib//:bzl_library.bzl", + Symbols: []string{"bzl_library"}, + }} +} + +// Fix repairs deprecated usage of language-specific rules in f. This is +// called before the file is indexed. Unless c.ShouldFix is true, fixes +// that delete or rename rules should not be performed. +func (*bzlLibraryLang) Fix(c *config.Config, f *rule.File) {} + +// Imports returns a list of ImportSpecs that can be used to import the rule +// r. This is used to populate RuleIndex. +// +// If nil is returned, the rule will not be indexed. If any non-nil slice is +// returned, including an empty slice, the rule will be indexed. +func (b *bzlLibraryLang) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec { + srcs := r.AttrStrings("srcs") + imports := make([]resolve.ImportSpec, len(srcs)) + + for _, src := range srcs { + spec := resolve.ImportSpec{ + // Lang is the language in which the import string appears (this should + // match Resolver.Name). + Lang: languageName, + // Imp is an import string for the library. + Imp: fmt.Sprintf("//%s:%s", f.Pkg, src), + } + + imports = append(imports, spec) + } + + return imports +} + +// Embeds returns a list of labels of rules that the given rule embeds. If +// a rule is embedded by another importable rule of the same language, only +// the embedding rule will be indexed. The embedding rule will inherit +// the imports of the embedded rule. +// Since SkyLark doesn't support embedding this should always return nil. +func (*bzlLibraryLang) Embeds(r *rule.Rule, from label.Label) []label.Label { return nil } + +// Resolve translates imported libraries for a given rule into Bazel +// dependencies. Information about imported libraries is returned for each +// rule generated by language.GenerateRules in +// language.GenerateResult.Imports. Resolve generates a "deps" attribute (or +// the appropriate language-specific equivalent) for each import according to +// language-specific rules and heuristics. +func (*bzlLibraryLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, importsRaw interface{}, from label.Label) { + imports := importsRaw.([]string) + + r.DelAttr("deps") + + if len(imports) == 0 { + return + } + + deps := make([]string, 0, len(imports)) + for _, imp := range imports { + if strings.HasPrefix(imp, "@") || !c.IndexLibraries { + // This is a dependency that is external to the current repo, or indexing + // is disabled so take a guess at what hte target name should be. + deps = append(deps, strings.TrimSuffix(imp, fileType)) + } else { + res := resolve.ImportSpec{ + Lang: languageName, + Imp: imp, + } + matches := ix.FindRulesByImport(res, languageName) + + if len(matches) == 0 { + log.Printf("%s: %q was not found in dependency index. Skipping. This may result in an incomplete deps section and require manual BUILD file intervention.\n", from.String(), imp) + } + + for _, m := range matches { + deps = append(deps, m.Label.String()) + } + } + } + + sort.Strings(deps) + if len(deps) > 0 { + r.SetAttr("deps", deps) + } +} + +var kinds = map[string]rule.KindInfo{ + "bzl_library": { + NonEmptyAttrs: map[string]bool{"srcs": true, "deps": true}, + MergeableAttrs: map[string]bool{"srcs": true}, + }, +} + +// GenerateRules extracts build metadata from source files in a directory. +// GenerateRules is called in each directory where an update is requested +// in depth-first post-order. +// +// args contains the arguments for GenerateRules. This is passed as a +// struct to avoid breaking implementations in the future when new +// fields are added. +// +// A GenerateResult struct is returned. Optional fields may be added to this +// type in the future. +// +// Any non-fatal errors this function encounters should be logged using +// log.Print. +func (*bzlLibraryLang) GenerateRules(args language.GenerateArgs) language.GenerateResult { + var rules []*rule.Rule + var imports []interface{} + for _, f := range append(args.RegularFiles, args.GenFiles...) { + if !isBzlSourceFile(f) { + continue + } + name := strings.TrimSuffix(f, fileType) + r := rule.NewRule("bzl_library", name) + + r.SetAttr("srcs", []string{f}) + + if args.File == nil || !args.File.HasDefaultVisibility() { + inPrivateDir := pathtools.Index(args.Rel, "private") >= 0 + if !inPrivateDir { + r.SetAttr("visibility", []string{"//visibility:public"}) + } + } + + fullPath := filepath.Join(args.Dir, f) + loads, err := getBzlFileLoads(fullPath) + if err != nil { + log.Printf("%s: contains syntax errors: %v", fullPath, err) + // Don't `continue` since it is reasonable to create a target even + // without deps. + } + + rules = append(rules, r) + imports = append(imports, loads) + } + + return language.GenerateResult{ + Gen: rules, + Imports: imports, + Empty: generateEmpty(args), + } +} + +func getBzlFileLoads(path string) ([]string, error) { + f, err := ioutil.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("ioutil.ReadFile(%q) error: %v", path, err) + } + ast, err := build.ParseBuild(path, f) + if err != nil { + return nil, fmt.Errorf("build.Parse(%q) error: %v", f, err) + } + + var loads []string + build.WalkOnce(ast, func(expr *build.Expr) { + n := *expr + if l, ok := n.(*build.LoadStmt); ok { + loads = append(loads, l.Module.Value) + } + }) + sort.Strings(loads) + + return loads, nil +} + +func isBzlSourceFile(f string) bool { + return strings.HasSuffix(f, fileType) && !ignoreSuffix.Matches(f) +} + +// generateEmpty generates the list of rules that don't need to exist in the +// BUILD file any more. +// For each bzl_library rule in args.File that only has srcs that aren't in +// args.RegularFiles or args.GenFiles, add a bzl_library with no srcs or deps. +// That will let Gazelle delete bzl_library rules after the corresponding .bzl +// files are deleted. +func generateEmpty(args language.GenerateArgs) []*rule.Rule { + var ret []*rule.Rule + if args.File == nil { + return ret + } + for _, r := range args.File.Rules { + if r.Kind() != "bzl_library" { + continue + } + name := r.AttrString("name") + + exists := make(map[string]bool) + for _, f := range args.RegularFiles { + exists[f] = true + } + for _, f := range args.GenFiles { + exists[f] = true + } + for _, r := range args.File.Rules { + srcsExist := false + for _, f := range r.AttrStrings("srcs") { + if exists[f] { + srcsExist = true + break + } + } + if !srcsExist { + ret = append(ret, rule.NewRule("bzl_library", name)) + } + } + } + return ret +} + +type srcsList []string + +func (s srcsList) Contains(m string) bool { + for _, e := range s { + if e == m { + return true + } + } + return false +} diff --git a/gazelle/gazelle_test.go b/gazelle/gazelle_test.go new file mode 100644 index 00000000..a22f7f65 --- /dev/null +++ b/gazelle/gazelle_test.go @@ -0,0 +1,140 @@ +package gazelle + +/* Copyright 2020 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. +*/ + +import ( + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/bazelbuild/bazel-gazelle/testtools" + "github.com/bazelbuild/rules_go/go/tools/bazel" +) + +var gazellePath = findGazelle() + +const testDataPath = "gazelle/testdata/" + +// TestGazelleBinary runs a gazelle binary with starlib installed on each +// directory in `testdata/*`. Please see `testdata/README.md` for more +// information on each test. +func TestGazelleBinary(t *testing.T) { + tests := map[string][]bazel.RunfileEntry{} + + files, err := bazel.ListRunfiles() + if err != nil { + t.Fatalf("bazel.ListRunfiles() error: %v", err) + } + for _, f := range files { + if strings.HasPrefix(f.ShortPath, testDataPath) { + relativePath := strings.TrimPrefix(f.ShortPath, testDataPath) + parts := strings.SplitN(relativePath, "/", 2) + if len(parts) < 2 { + // This file is not a part of a testcase since it must be in a dir that + // is the test case and then have a path inside of that. + continue + } + + tests[parts[0]] = append(tests[parts[0]], f) + } + } + + for testName, files := range tests { + testPath(t, testName, files) + } +} + +func testPath(t *testing.T, name string, files []bazel.RunfileEntry) { + t.Run(name, func(t *testing.T) { + var inputs []testtools.FileSpec + var goldens []testtools.FileSpec + + for _, f := range files { + path := f.Path + trim := testDataPath + name + "/" + shortPath := strings.TrimPrefix(f.ShortPath, trim) + info, err := os.Stat(path) + if err != nil { + t.Fatalf("os.Stat(%q) error: %v", path, err) + } + + // Skip dirs. + if info.IsDir() { + continue + } + + content, err := ioutil.ReadFile(path) + if err != nil { + t.Errorf("ioutil.ReadFile(%q) error: %v", path, err) + } + + // Now trim the common prefix off. + if strings.HasSuffix(shortPath, ".in") { + inputs = append(inputs, testtools.FileSpec{ + Path: strings.TrimSuffix(shortPath, ".in"), + Content: string(content), + }) + } else if strings.HasSuffix(shortPath, ".out") { + goldens = append(goldens, testtools.FileSpec{ + Path: strings.TrimSuffix(shortPath, ".out"), + Content: string(content), + }) + } else { + inputs = append(inputs, testtools.FileSpec{ + Path: shortPath, + Content: string(content), + }) + goldens = append(goldens, testtools.FileSpec{ + Path: shortPath, + Content: string(content), + }) + } + } + + dir, cleanup := testtools.CreateFiles(t, inputs) + defer cleanup() + + cmd := exec.Command(gazellePath, "-build_file_name=BUILD") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Dir = dir + if err := cmd.Run(); err != nil { + t.Fatal(err) + } + + testtools.CheckFiles(t, dir, goldens) + if t.Failed() { + filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + t.Logf("%q exists", path) + return nil + }) + } + }) +} + +func findGazelle() string { + gazellePath, ok := bazel.FindBinary("gazelle", "gazelle-skylib") + if !ok { + panic("could not find gazelle binary") + } + return gazellePath +} diff --git a/gazelle/testdata/README.md b/gazelle/testdata/README.md new file mode 100644 index 00000000..a6a36031 --- /dev/null +++ b/gazelle/testdata/README.md @@ -0,0 +1,56 @@ +# Gazelle test cases + +This directory contains a suite of test cases for the Skylark language plugin +for Gazelle. + +Please note that there are no `BUILD` or `BUILD.bazel` files in subdirs, insted +there are `BUILD.in` and `BUILD.out` describing what the `BUILD` should look +like initially and what the `BUILD` file should look like after the run. These +names are special because they are not recognized by Bazel as a proper `BUILD` +file, and therefore are included in the data dependency by the recursive data +glob in `//gazelle:go_default_test`. If you would like to include any extremely +complicated tests that contain proper `BUILD` files you will need to manually +add them to the `//gazelle:go_default_test` target's `data` section. + +## `simple` + +Simple is a base test case that was used to validate the parser. + +## `nobuildfiles` + +A test just like `simple` that has no `BUILD` files at the beginning. + +## `import` + +Import is a test case that imports a `.bzl` from the same directory. + +## `multidir` + +Multidir is a test that has a `.bzl` that imports from a different dirrectory. + +## `tests` + +Using the skylib as an example, this test has `.bzl` files that end in +`_tests.bzl` which are `load`ed into `BUILD` files and never imported by +another repo. + +## `private` + +Using the skylib as an example, this test has `.bzl` files that live in a +directory called `private` which is used to indicate that they are repo private. +Note that this is distict from the expectations of go's `internal` where the +relative position in the hierarchy determines the visibility. + +## `defaultvisibility` + +If the package declares a `default_visibility` the generated `bzl_library` +should not set its own `visibility`. + +## `external` + +This test demonstrates that if you load from another repo, it is able to +generate a `deps` entry for the dependency. + +## `empty` + +Gazelle has the ability to remove old and unused targets. Test that. diff --git a/gazelle/testdata/defaultvisibility/BUILD.in b/gazelle/testdata/defaultvisibility/BUILD.in new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/defaultvisibility/BUILD.out b/gazelle/testdata/defaultvisibility/BUILD.out new file mode 100644 index 00000000..44c1495e --- /dev/null +++ b/gazelle/testdata/defaultvisibility/BUILD.out @@ -0,0 +1,8 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], + deps = ["//nested/dir:bar"], +) diff --git a/gazelle/testdata/defaultvisibility/WORKSPACE b/gazelle/testdata/defaultvisibility/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/defaultvisibility/foo.bzl b/gazelle/testdata/defaultvisibility/foo.bzl new file mode 100644 index 00000000..1191303a --- /dev/null +++ b/gazelle/testdata/defaultvisibility/foo.bzl @@ -0,0 +1,7 @@ +""" +Doc string +""" + +load("//nested/dir:bar.bzl", "func") + +func() diff --git a/gazelle/testdata/defaultvisibility/nested/dir/BUILD.in b/gazelle/testdata/defaultvisibility/nested/dir/BUILD.in new file mode 100644 index 00000000..830932af --- /dev/null +++ b/gazelle/testdata/defaultvisibility/nested/dir/BUILD.in @@ -0,0 +1 @@ +package(default_visibility = ["//:__pkg__"]) diff --git a/gazelle/testdata/defaultvisibility/nested/dir/BUILD.out b/gazelle/testdata/defaultvisibility/nested/dir/BUILD.out new file mode 100644 index 00000000..8394b9c8 --- /dev/null +++ b/gazelle/testdata/defaultvisibility/nested/dir/BUILD.out @@ -0,0 +1,8 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +package(default_visibility = ["//:__pkg__"]) + +bzl_library( + name = "bar", + srcs = ["bar.bzl"], +) diff --git a/gazelle/testdata/defaultvisibility/nested/dir/bar.bzl b/gazelle/testdata/defaultvisibility/nested/dir/bar.bzl new file mode 100644 index 00000000..8ab1fcb5 --- /dev/null +++ b/gazelle/testdata/defaultvisibility/nested/dir/bar.bzl @@ -0,0 +1,6 @@ +""" +Doc string +""" + +def asdf(): + pass diff --git a/gazelle/testdata/empty/BUILD.in b/gazelle/testdata/empty/BUILD.in new file mode 100644 index 00000000..e1e154cb --- /dev/null +++ b/gazelle/testdata/empty/BUILD.in @@ -0,0 +1,13 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "weirdly_named_target_that_will_be_removed", + srcs = ["nonexistant.bzl"], + visibility = ["//visibility:public"], +) + +bzl_library( + name = "weirdly_named_target_that_will_be_renamed", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/empty/BUILD.out b/gazelle/testdata/empty/BUILD.out new file mode 100644 index 00000000..ac0e990f --- /dev/null +++ b/gazelle/testdata/empty/BUILD.out @@ -0,0 +1,7 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/empty/WORKSPACE b/gazelle/testdata/empty/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/empty/foo.bzl b/gazelle/testdata/empty/foo.bzl new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/external/BUILD.in b/gazelle/testdata/external/BUILD.in new file mode 100644 index 00000000..e7bc836e --- /dev/null +++ b/gazelle/testdata/external/BUILD.in @@ -0,0 +1,8 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) diff --git a/gazelle/testdata/external/BUILD.out b/gazelle/testdata/external/BUILD.out new file mode 100644 index 00000000..c70685fe --- /dev/null +++ b/gazelle/testdata/external/BUILD.out @@ -0,0 +1,15 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], + deps = ["@external_repo//path/to:file"], +) diff --git a/gazelle/testdata/external/WORKSPACE b/gazelle/testdata/external/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/external/foo.bzl b/gazelle/testdata/external/foo.bzl new file mode 100644 index 00000000..ad548a58 --- /dev/null +++ b/gazelle/testdata/external/foo.bzl @@ -0,0 +1,7 @@ +""" +Test sample code. +""" + +load("@external_repo//path/to:file.bzl", "func") + +func() diff --git a/gazelle/testdata/import/BUILD.in b/gazelle/testdata/import/BUILD.in new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/import/BUILD.out b/gazelle/testdata/import/BUILD.out new file mode 100644 index 00000000..a19a11aa --- /dev/null +++ b/gazelle/testdata/import/BUILD.out @@ -0,0 +1,14 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "bar", + srcs = ["bar.bzl"], + visibility = ["//visibility:public"], +) + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], + deps = ["//:bar"], +) diff --git a/gazelle/testdata/import/WORKSPACE b/gazelle/testdata/import/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/import/bar.bzl b/gazelle/testdata/import/bar.bzl new file mode 100644 index 00000000..7ffea515 --- /dev/null +++ b/gazelle/testdata/import/bar.bzl @@ -0,0 +1,6 @@ +""" +Doc string +""" + +def func(): + pass diff --git a/gazelle/testdata/import/foo.bzl b/gazelle/testdata/import/foo.bzl new file mode 100644 index 00000000..eb8d33c6 --- /dev/null +++ b/gazelle/testdata/import/foo.bzl @@ -0,0 +1,7 @@ +""" +Doc string +""" + +load("//:bar.bzl", "func") + +func() diff --git a/gazelle/testdata/multidir/BUILD.in b/gazelle/testdata/multidir/BUILD.in new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/multidir/BUILD.out b/gazelle/testdata/multidir/BUILD.out new file mode 100644 index 00000000..44c1495e --- /dev/null +++ b/gazelle/testdata/multidir/BUILD.out @@ -0,0 +1,8 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], + deps = ["//nested/dir:bar"], +) diff --git a/gazelle/testdata/multidir/WORKSPACE b/gazelle/testdata/multidir/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/multidir/foo.bzl b/gazelle/testdata/multidir/foo.bzl new file mode 100644 index 00000000..1191303a --- /dev/null +++ b/gazelle/testdata/multidir/foo.bzl @@ -0,0 +1,7 @@ +""" +Doc string +""" + +load("//nested/dir:bar.bzl", "func") + +func() diff --git a/gazelle/testdata/multidir/nested/dir/BUILD.out b/gazelle/testdata/multidir/nested/dir/BUILD.out new file mode 100644 index 00000000..07ec8ce6 --- /dev/null +++ b/gazelle/testdata/multidir/nested/dir/BUILD.out @@ -0,0 +1,7 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "bar", + srcs = ["bar.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/multidir/nested/dir/bar.bzl b/gazelle/testdata/multidir/nested/dir/bar.bzl new file mode 100644 index 00000000..7ffea515 --- /dev/null +++ b/gazelle/testdata/multidir/nested/dir/bar.bzl @@ -0,0 +1,6 @@ +""" +Doc string +""" + +def func(): + pass diff --git a/gazelle/testdata/nobuildfiles/BUILD.out b/gazelle/testdata/nobuildfiles/BUILD.out new file mode 100644 index 00000000..ac0e990f --- /dev/null +++ b/gazelle/testdata/nobuildfiles/BUILD.out @@ -0,0 +1,7 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/nobuildfiles/WORKSPACE b/gazelle/testdata/nobuildfiles/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/nobuildfiles/foo.bzl b/gazelle/testdata/nobuildfiles/foo.bzl new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/private/BUILD.in b/gazelle/testdata/private/BUILD.in new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/private/BUILD.out b/gazelle/testdata/private/BUILD.out new file mode 100644 index 00000000..e65b00f8 --- /dev/null +++ b/gazelle/testdata/private/BUILD.out @@ -0,0 +1,8 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], + deps = ["//private:bar"], +) diff --git a/gazelle/testdata/private/WORKSPACE b/gazelle/testdata/private/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/private/foo.bzl b/gazelle/testdata/private/foo.bzl new file mode 100644 index 00000000..7e1dcd1f --- /dev/null +++ b/gazelle/testdata/private/foo.bzl @@ -0,0 +1,7 @@ +""" +Test sample code. +""" + +load("//private:bar.bzl", "func") + +func() diff --git a/gazelle/testdata/private/private/BUILD.out b/gazelle/testdata/private/private/BUILD.out new file mode 100644 index 00000000..eb2e935d --- /dev/null +++ b/gazelle/testdata/private/private/BUILD.out @@ -0,0 +1,6 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +bzl_library( + name = "bar", + srcs = ["bar.bzl"], +) diff --git a/gazelle/testdata/private/private/bar.bzl b/gazelle/testdata/private/private/bar.bzl new file mode 100644 index 00000000..c8a48713 --- /dev/null +++ b/gazelle/testdata/private/private/bar.bzl @@ -0,0 +1,6 @@ +""" +Test sample code. +""" + +def func(): + pass diff --git a/gazelle/testdata/simple/BUILD.in b/gazelle/testdata/simple/BUILD.in new file mode 100644 index 00000000..e267b5a1 --- /dev/null +++ b/gazelle/testdata/simple/BUILD.in @@ -0,0 +1,6 @@ +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) diff --git a/gazelle/testdata/simple/BUILD.out b/gazelle/testdata/simple/BUILD.out new file mode 100644 index 00000000..3c71d561 --- /dev/null +++ b/gazelle/testdata/simple/BUILD.out @@ -0,0 +1,14 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/simple/WORKSPACE b/gazelle/testdata/simple/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/simple/foo.bzl b/gazelle/testdata/simple/foo.bzl new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/tests/BUILD.in b/gazelle/testdata/tests/BUILD.in new file mode 100644 index 00000000..e267b5a1 --- /dev/null +++ b/gazelle/testdata/tests/BUILD.in @@ -0,0 +1,6 @@ +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) diff --git a/gazelle/testdata/tests/BUILD.out b/gazelle/testdata/tests/BUILD.out new file mode 100644 index 00000000..3c71d561 --- /dev/null +++ b/gazelle/testdata/tests/BUILD.out @@ -0,0 +1,14 @@ +load("@bazel_skylib//:bzl_library.bzl", "bzl_library") + +# Some comment to be preserved + +filegroup( + name = "allfiles", + srcs = glob(["**"]), +) + +bzl_library( + name = "foo", + srcs = ["foo.bzl"], + visibility = ["//visibility:public"], +) diff --git a/gazelle/testdata/tests/WORKSPACE b/gazelle/testdata/tests/WORKSPACE new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/tests/foo.bzl b/gazelle/testdata/tests/foo.bzl new file mode 100644 index 00000000..e69de29b diff --git a/gazelle/testdata/tests/foo_tests.bzl b/gazelle/testdata/tests/foo_tests.bzl new file mode 100644 index 00000000..e69de29b diff --git a/lib/BUILD b/lib/BUILD index c959bcc1..d17caa57 100644 --- a/lib/BUILD +++ b/lib/BUILD @@ -93,3 +93,8 @@ filegroup( "//distribution:__pkg__", ], ) + +bzl_library( + name = "old_sets", + srcs = ["old_sets.bzl"], +) diff --git a/rules/BUILD b/rules/BUILD index 9c6c047c..bad361b8 100644 --- a/rules/BUILD +++ b/rules/BUILD @@ -81,3 +81,8 @@ exports_files( glob(["*.bzl"]), visibility = ["//:__subpackages__"], ) + +bzl_library( + name = "select_file", + srcs = ["select_file.bzl"], +)