blob: c6b0b6d17f2034203ae0060e2f0dc84421579880 [file] [log] [blame]
/* Copyright 2017 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 golang
import (
"testing"
"github.com/bazelbuild/bazel-gazelle/internal/merger"
"github.com/bazelbuild/bazel-gazelle/internal/rule"
)
type fixTestCase struct {
desc, old, want string
}
func TestFixFile(t *testing.T) {
for _, tc := range []fixTestCase{
// migrateLibraryEmbed tests
{
desc: "library migrated to embed",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["foo.go"],
)
go_test(
name = "go_default_test",
srcs = ["foo_test.go"],
library = ":go_default_library",
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["foo.go"],
)
go_test(
name = "go_default_test",
srcs = ["foo_test.go"],
embed = [":go_default_library"],
)
`,
}, {
// verifies #211
desc: "other library not migrated",
old: `
gomock(
name = "stripe_mock",
out = "stripe_mock_test.go",
library = ":go_default_library",
interfaces = [
"stSubscriptions",
"stCustomers",
],
package = "main",
source = "stripe.go",
)
`,
want: `
gomock(
name = "stripe_mock",
out = "stripe_mock_test.go",
library = ":go_default_library",
interfaces = [
"stSubscriptions",
"stCustomers",
],
package = "main",
source = "stripe.go",
)
`,
},
// migrateGrpcCompilers tests
{
desc: "go_grpc_library migrated to compilers",
old: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library")
proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//visibility:public"],
)
go_grpc_library(
name = "foo_go_proto",
importpath = "example.com/repo",
proto = ":foo_proto",
visibility = ["//visibility:public"],
)
`,
want: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library")
proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
visibility = ["//visibility:public"],
)
go_proto_library(
name = "foo_go_proto",
compilers = ["@io_bazel_rules_go//proto:go_grpc"],
importpath = "example.com/repo",
proto = ":foo_proto",
visibility = ["//visibility:public"],
)
`,
},
// flattenSrcs tests
{
desc: "flatten srcs",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"gen.go",
] + select({
"@io_bazel_rules_go//platform:darwin_amd64": [
# darwin
"foo.go", # keep
],
"@io_bazel_rules_go//platform:linux_amd64": [
# linux
"foo.go", # keep
],
}),
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
# darwin
# linux
"foo.go", # keep
"gen.go",
],
)
`,
},
// squashCgoLibrary tests
{
desc: "no cgo_library",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
)
`,
},
{
desc: "non-default cgo_library not removed",
old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
cgo_library(
name = "something_else",
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
cgo_library(
name = "something_else",
)
`,
},
{
desc: "unlinked cgo_library removed",
old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
go_library(
name = "go_default_library",
library = ":something_else",
)
cgo_library(
name = "cgo_default_library",
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library", "go_library")
go_library(
name = "go_default_library",
cgo = True,
)
`,
},
{
desc: "cgo_library replaced with go_library",
old: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
# before comment
cgo_library(
name = "cgo_default_library",
cdeps = ["cdeps"],
clinkopts = ["clinkopts"],
copts = ["copts"],
data = ["data"],
deps = ["deps"],
gc_goopts = ["gc_goopts"],
srcs = [
"foo.go" # keep
],
visibility = ["//visibility:private"],
)
# after comment
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "cgo_library")
# before comment
go_library(
name = "go_default_library",
srcs = [
"foo.go", # keep
],
cdeps = ["cdeps"],
cgo = True,
clinkopts = ["clinkopts"],
copts = ["copts"],
data = ["data"],
gc_goopts = ["gc_goopts"],
visibility = ["//visibility:private"],
deps = ["deps"],
)
# after comment
`,
}, {
desc: "cgo_library merged with go_library",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
# before go_library
go_library(
name = "go_default_library",
srcs = ["pure.go"],
deps = ["pure_deps"],
data = ["pure_data"],
gc_goopts = ["pure_gc_goopts"],
library = ":cgo_default_library",
cgo = False,
)
# after go_library
# before cgo_library
cgo_library(
name = "cgo_default_library",
srcs = ["cgo.go"],
deps = ["cgo_deps"],
data = ["cgo_data"],
gc_goopts = ["cgo_gc_goopts"],
copts = ["copts"],
cdeps = ["cdeps"],
)
# after cgo_library
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
# before go_library
# before cgo_library
go_library(
name = "go_default_library",
srcs = [
"cgo.go",
"pure.go",
],
cdeps = ["cdeps"],
cgo = True,
copts = ["copts"],
data = [
"cgo_data",
"pure_data",
],
gc_goopts = [
"cgo_gc_goopts",
"pure_gc_goopts",
],
deps = [
"cgo_deps",
"pure_deps",
],
)
# after go_library
# after cgo_library
`,
},
// squashXtest tests
{
desc: "rename xtest",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_test(
name = "go_default_xtest",
srcs = ["x_test.go"],
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_test(
name = "go_default_test",
srcs = ["x_test.go"],
)
`,
}, {
desc: "squash xtest",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_test(
name = "go_default_test",
srcs = ["i_test.go"],
deps = [
":i_dep",
":shared_dep",
],
visibility = ["//visibility:public"],
)
go_test(
name = "go_default_xtest",
srcs = ["x_test.go"],
deps = [
":x_dep",
":shared_dep",
],
visibility = ["//visibility:public"],
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_test(
name = "go_default_test",
srcs = [
"i_test.go",
"x_test.go",
],
visibility = ["//visibility:public"],
deps = [
":i_dep",
":shared_dep",
":x_dep",
],
)
`,
},
// removeLegacyProto tests
{
desc: "current proto preserved",
old: `load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
go_proto_library(
name = "foo_go_proto",
proto = ":foo_proto",
)
`,
want: `load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
go_proto_library(
name = "foo_go_proto",
proto = ":foo_proto",
)
`,
},
{
desc: "load and proto removed",
old: `load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
go_proto_library(
name = "go_default_library_protos",
srcs = ["foo.proto"],
visibility = ["//visibility:private"],
)
`,
want: "",
},
{
desc: "proto filegroup removed",
old: `filegroup(
name = "go_default_library_protos",
srcs = ["foo.proto"],
)
go_proto_library(name = "foo_proto")
`,
want: `go_proto_library(name = "foo_proto")
`,
},
} {
t.Run(tc.desc, func(t *testing.T) {
testFix(t, tc, func(f *rule.File) {
c, _, _ := testConfig()
c.ShouldFix = true
lang := New()
lang.Fix(c, f)
})
})
}
}
func TestFixLoads(t *testing.T) {
for _, tc := range []fixTestCase{
{
desc: "empty file",
old: "",
want: "",
}, {
desc: "non-Go file",
old: `load("@io_bazel_rules_intercal//intercal:def.bzl", "intercal_library")
intercal_library(
name = "intercal_default_library",
srcs = ["foo.ic"],
)
`,
want: `load("@io_bazel_rules_intercal//intercal:def.bzl", "intercal_library")
intercal_library(
name = "intercal_default_library",
srcs = ["foo.ic"],
)
`,
}, {
desc: "empty Go load",
old: `load("@io_bazel_rules_go//go:def.bzl")
`,
want: "",
}, {
desc: "add and remove loaded symbols",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(name = "go_default_library")
go_binary(name = "cmd")
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(name = "go_default_library")
go_binary(name = "cmd")
`,
}, {
desc: "consolidate load statements",
old: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_library(name = "go_default_library")
go_test(name = "go_default_test")
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(name = "go_default_library")
go_test(name = "go_default_test")
`,
}, {
desc: "new load statement",
old: `go_library(
name = "go_default_library",
)
go_embed_data(
name = "data",
)
`,
want: `load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
)
go_embed_data(
name = "data",
)
`,
}, {
desc: "proto symbols",
old: `go_proto_library(
name = "foo_proto",
)
go_grpc_library(
name = "bar_proto",
)
`,
want: `load("@io_bazel_rules_go//proto:def.bzl", "go_grpc_library", "go_proto_library")
go_proto_library(
name = "foo_proto",
)
go_grpc_library(
name = "bar_proto",
)
`,
}, {
desc: "fixLoad doesn't touch other symbols or loads",
old: `load(
"@io_bazel_rules_go//go:def.bzl",
"go_embed_data", # embed
"go_test",
foo = "go_binary", # binary
)
load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
go_library(
name = "go_default_library",
)
`,
want: `load(
"@io_bazel_rules_go//go:def.bzl",
"go_embed_data", # embed
"go_library",
foo = "go_binary", # binary
)
load("@io_bazel_rules_go//proto:go_proto_library.bzl", "go_proto_library")
go_library(
name = "go_default_library",
)
`,
}, {
desc: "fixLoad doesn't touch loads from other files",
old: `load(
"@com_github_pubref_rules_protobuf//go:rules.bzl",
"go_proto_library",
go_grpc_library = "go_proto_library",
)
go_proto_library(
name = "foo_go_proto",
)
grpc_proto_library(
name = "bar_go_proto",
)
`,
want: `load(
"@com_github_pubref_rules_protobuf//go:rules.bzl",
"go_proto_library",
go_grpc_library = "go_proto_library",
)
go_proto_library(
name = "foo_go_proto",
)
grpc_proto_library(
name = "bar_go_proto",
)
`,
}, {
desc: "moved symbol",
old: `
load("@io_bazel_rules_go//go:def.bzl", "go_repository")
go_repository(name = "foo")
`,
want: `
load("@bazel_gazelle//:deps.bzl", "go_repository")
go_repository(name = "foo")
`,
}, {
desc: "moved symbols with others",
old: `
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_repository")
go_rules_dependencies()
go_repository(name = "foo")
`,
want: `
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies")
go_rules_dependencies()
load("@bazel_gazelle//:deps.bzl", "go_repository")
go_repository(name = "foo")
`,
}, {
desc: "load after",
old: `
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
go_repository(name = "foo")
`,
want: `
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
load("@bazel_gazelle//:deps.bzl", "go_repository")
go_repository(name = "foo")
`,
},
} {
t.Run(tc.desc, func(t *testing.T) {
testFix(t, tc, func(f *rule.File) {
merger.FixLoads(f, goLoads)
})
})
}
}
func testFix(t *testing.T, tc fixTestCase, fix func(*rule.File)) {
f, err := rule.LoadData("old", "", []byte(tc.old))
if err != nil {
t.Fatalf("%s: parse error: %v", tc.desc, err)
}
fix(f)
want := tc.want
if len(want) > 0 && want[0] == '\n' {
// Strip leading newline, added for readability
want = want[1:]
}
if got := string(f.Format()); got != want {
t.Fatalf("%s: got %s; want %s", tc.desc, got, want)
}
}