diff --git a/.gitignore b/.gitignore index d9854487f..c2f5a6cda 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /tests/bcr/bazel-bin /tests/bcr/bazel-out /tests/bcr/bazel-testlogs +.DS_STORE diff --git a/go.sum b/go.sum index ce2eb77be..00f8612ad 100644 --- a/go.sum +++ b/go.sum @@ -17,7 +17,6 @@ github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwV github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -27,15 +26,12 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= @@ -43,65 +39,37 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.starlark.net v0.0.0-20210223155950-e043a3d3c984/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220907140024-f12130a52804 h1:0SH2R3f1b1VmIMG7BXbEZCBUu2dKmHschSmjqGUrW8A= golang.org/x/sync v0.0.0-20220907140024-f12130a52804/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220913175220-63ea55921009 h1:PuvuRMeLWqsf/ZdT1UUZz0syhioyv1mzuFZsXs4fvhw= golang.org/x/sys v0.0.0-20220913175220-63ea55921009/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -121,8 +89,5 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/go_repository_tools_srcs.bzl b/internal/go_repository_tools_srcs.bzl index 386521fb7..c7b27004c 100644 --- a/internal/go_repository_tools_srcs.bzl +++ b/internal/go_repository_tools_srcs.bzl @@ -48,6 +48,11 @@ GO_REPOSITORY_TOOLS_SRCS = [ Label("//label:label.go"), Label("//language:BUILD.bazel"), Label("//language:base.go"), + Label("//language/bazel:BUILD.bazel"), + Label("//language/bazel/visibility:BUILD.bazel"), + Label("//language/bazel/visibility:config.go"), + Label("//language/bazel/visibility:lang.go"), + Label("//language/bazel/visibility:resolve.go"), Label("//language/go:BUILD.bazel"), Label("//language/go:build_constraints.go"), Label("//language/go:config.go"), diff --git a/language/BUILD.bazel b/language/BUILD.bazel index 6a7cc6418..e4e7856b1 100644 --- a/language/BUILD.bazel +++ b/language/BUILD.bazel @@ -26,6 +26,7 @@ filegroup( "base.go", "lang.go", "update.go", + "//language/bazel:all_files", "//language/go:all_files", "//language/proto:all_files", ], diff --git a/language/bazel/BUILD.bazel b/language/bazel/BUILD.bazel new file mode 100644 index 000000000..27dcf6417 --- /dev/null +++ b/language/bazel/BUILD.bazel @@ -0,0 +1,9 @@ +filegroup( + name = "all_files", + testonly = True, + srcs = [ + "BUILD.bazel", + "//language/bazel/visibility:all_files", + ], + visibility = ["//visibility:public"], +) diff --git a/language/bazel/visibility/BUILD.bazel b/language/bazel/visibility/BUILD.bazel new file mode 100644 index 000000000..90389c1ab --- /dev/null +++ b/language/bazel/visibility/BUILD.bazel @@ -0,0 +1,51 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "visibility", + srcs = [ + "config.go", + "lang.go", + "resolve.go", + ], + importpath = "github.com/bazelbuild/bazel-gazelle/language/bazel/visibility", + visibility = ["//visibility:public"], + deps = [ + "//config", + "//label", + "//language", + "//repo", + "//resolve", + "//rule", + ], +) + +alias( + name = "go_default_library", + actual = ":visibility", + visibility = ["//visibility:public"], +) + +go_test( + name = "visibility_test", + srcs = ["lang_test.go"], + deps = [ + ":visibility", + "//config", + "//label", + "//language", + "//rule", + ], +) + +filegroup( + name = "all_files", + testonly = True, + srcs = [ + "BUILD.bazel", + "config.go", + "lang.go", + "lang_test.go", + "resolve.go", + ], + visibility = ["//visibility:public"], +) diff --git a/language/bazel/visibility/config.go b/language/bazel/visibility/config.go new file mode 100644 index 000000000..64385b3c3 --- /dev/null +++ b/language/bazel/visibility/config.go @@ -0,0 +1,64 @@ +package visibility + +import ( + "flag" + "strings" + + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/rule" +) + +const ( + _directiveName = "default_visibility" +) + +type visConfig struct { + visibilityTargets []string +} + +// getVisConfig directly returns the internal configuration struct rather +// than a pointer because we explicitly want pass-by-value symantics so +// configurations down a directory tree don't accidentially update upstream. +func getVisConfig(c *config.Config) visConfig { + cfg := c.Exts[_extName] + if cfg == nil { + return visConfig{} + } + return cfg.(visConfig) +} + +// RegisterFlags noops because we only parameterize behavior with a directive. +func (*visibilityExtension) RegisterFlags(fs *flag.FlagSet, cmd string, c *config.Config) {} + +// CheckFlags noops because no flags are referenced. +func (*visibilityExtension) CheckFlags(fs *flag.FlagSet, c *config.Config) error { + return nil +} + +// KnownDirectives returns the only directive this extension operates on. +func (*visibilityExtension) KnownDirectives() []string { + return []string{_directiveName} +} + +// Configure identifies the visibility targets from the directive value, if it exists. +// +// To set multiple visibility targets, either multiple directives can be used, or a +// list can be provided with comma-separated values. +func (*visibilityExtension) Configure(c *config.Config, _ string, f *rule.File) { + cfg := getVisConfig(c) + if f == nil { + return + } + + for _, d := range f.Directives { + switch d.Key { + case _directiveName: + for _, target := range strings.Split(d.Value, ",") { + cfg.visibilityTargets = append(cfg.visibilityTargets, target) + } + } + } + c.Exts[_extName] = cfg +} + +// /Configurator embed diff --git a/language/bazel/visibility/lang.go b/language/bazel/visibility/lang.go new file mode 100644 index 000000000..f3bb8243c --- /dev/null +++ b/language/bazel/visibility/lang.go @@ -0,0 +1,52 @@ +package visibility + +import ( + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/language" + "github.com/bazelbuild/bazel-gazelle/rule" +) + +type visibilityExtension struct{} + +// NewLanguage constructs a new language.Language modifying visibility. +func NewLanguage() language.Language { + return &visibilityExtension{} +} + +// Kinds instructs gazelle to match any 'package' rule as BUILD files can only have one. +func (*visibilityExtension) Kinds() map[string]rule.KindInfo { + return map[string]rule.KindInfo{ + "package": { + MatchAny: true, + MergeableAttrs: map[string]bool{ + "default_visibility": true, + }, + }, + } +} + +// Loads noops because there are no imports to add +func (*visibilityExtension) Loads() []rule.LoadInfo { + return nil +} + +// GenerateRules does the hard work of setting the default_visibility if a config exists. +func (*visibilityExtension) GenerateRules(args language.GenerateArgs) language.GenerateResult { + res := language.GenerateResult{} + cfg := getVisConfig(args.Config) + + if len(cfg.visibilityTargets) == 0 { + return res + } + + r := rule.NewRule("package", "") + r.SetAttr("default_visibility", cfg.visibilityTargets) + + res.Gen = append(res.Gen, r) + // we have to add a nil to Imports because there is length-matching validation with Gen. + res.Imports = append(res.Imports, nil) + return res +} + +// Fix noop because there is nothing out there to fix yet +func (*visibilityExtension) Fix(c *config.Config, f *rule.File) {} diff --git a/language/bazel/visibility/lang_test.go b/language/bazel/visibility/lang_test.go new file mode 100644 index 000000000..9722d39fd --- /dev/null +++ b/language/bazel/visibility/lang_test.go @@ -0,0 +1,175 @@ +package visibility_test + +import ( + "fmt" + "testing" + + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/label" + "github.com/bazelbuild/bazel-gazelle/language" + "github.com/bazelbuild/bazel-gazelle/language/bazel/visibility" + "github.com/bazelbuild/bazel-gazelle/rule" +) + +func TestNoopsBecauseILoveCoverage(t *testing.T) { + ext := visibility.NewLanguage() + + ext.RegisterFlags(nil /* flagset */, "command", nil /* config */) + ext.Resolve(nil /* config */, nil /* RuleIndex */, nil /* RemoteCache */, nil /* Rule */, nil /* imports */, label.New("repo", "pkg", "name")) + ext.Fix(nil /* config */, nil /* File */) + if ext.CheckFlags(nil /* flagset */, nil /* config */) != nil { + t.Fatal("expected nil") + } + if ext.Imports(nil /* rule */, nil /* rule */, nil /* file */) != nil { + t.Fatal("expected nil") + } + if ext.Embeds(nil /* rule */, label.New("repo", "pkg", "name")) != nil { + t.Fatal("expected nil") + } + if ext.Loads() != nil { + t.Fatal("expected nil") + } + if ext.KnownDirectives() == nil { + t.Fatal("expected not nil") + } + if ext.Name() == "" { + t.Fatal("expected not empty name") + } +} + +func Test_NoDirective(t *testing.T) { + cfg := config.New() + file := rule.EmptyFile("path", "pkg") + + ext := visibility.NewLanguage() + ext.Configure(cfg, "rel", file) + res := ext.GenerateRules(language.GenerateArgs{Config: cfg}) + + if len(res.Imports) != 0 { + t.Fatal("expected empty array") + } + if len(res.Gen) != 0 { + t.Fatal("expected empty array") + } +} + +func Test_NewDirective(t *testing.T) { + testVis := "//src:__subpackages__" + cfg := config.New() + file, err := rule.LoadData("path", "pkg", []byte(fmt.Sprintf("# gazelle:default_visibility %s", testVis))) + if err != nil { + t.Fatal("expected nil") + } + + ext := visibility.NewLanguage() + ext.Configure(cfg, "rel", file) + res := ext.GenerateRules(language.GenerateArgs{Config: cfg}) + + if len(res.Gen) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Imports) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Gen[0].AttrStrings("default_visibility")) != 1 { + t.Fatal("expected array of length 1") + } + if testVis != res.Gen[0].AttrStrings("default_visibility")[0] { + t.Fatal("expected returned visibility to match 'testVis'") + } +} + +func Test_ReplacementDirective(t *testing.T) { + testVis := "//src:__subpackages__" + cfg := config.New() + file, err := rule.LoadData("path", "pkg", []byte(fmt.Sprintf(` +# gazelle:default_visibility %s + +package(default_visibility = "//not-src:__subpackages__") +`, testVis))) + if err != nil { + t.Fatalf("expected not nil - %+v", err) + } + + ext := visibility.NewLanguage() + ext.Configure(cfg, "rel", file) + res := ext.GenerateRules(language.GenerateArgs{Config: cfg}) + + if len(res.Gen) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Imports) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Gen[0].AttrStrings("default_visibility")) != 1 { + t.Fatal("expected array of length 1") + } + if testVis != res.Gen[0].AttrStrings("default_visibility")[0] { + t.Fatal("expected returned visibility to match '//src:__subpackages__'") + } +} + +func Test_MultipleDirectives(t *testing.T) { + testVis1 := "//src:__subpackages__" + testVis2 := "//src2:__subpackages__" + cfg := config.New() + file, err := rule.LoadData("path", "pkg", []byte(fmt.Sprintf(` +# gazelle:default_visibility %s +# gazelle:default_visibility %s +`, testVis1, testVis2))) + if err != nil { + t.Fatalf("expected not nil - %+v", err) + } + + ext := visibility.NewLanguage() + ext.Configure(cfg, "rel", file) + res := ext.GenerateRules(language.GenerateArgs{Config: cfg}) + + if len(res.Gen) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Imports) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Gen[0].AttrStrings("default_visibility")) != 2 { + t.Fatal("expected array of length 2") + } + if testVis1 != res.Gen[0].AttrStrings("default_visibility")[0] { + t.Fatal("expected returned visibility to match '//src:__subpackages__'") + } + if testVis2 != res.Gen[0].AttrStrings("default_visibility")[1] { + t.Fatal("expected returned visibility to match '//src2:__subpackages__'") + } +} + +func Test_MultipleDefaultsSingleDirective(t *testing.T) { + testVis1 := "//src:__subpackages__" + testVis2 := "//src2:__subpackages__" + cfg := config.New() + file, err := rule.LoadData("path", "pkg", []byte(fmt.Sprintf(` +# gazelle:default_visibility %s,%s +`, testVis1, testVis2))) + if err != nil { + t.Fatalf("expected not nil - %+v", err) + } + + ext := visibility.NewLanguage() + ext.Configure(cfg, "rel", file) + res := ext.GenerateRules(language.GenerateArgs{Config: cfg}) + + if len(res.Gen) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Imports) != 1 { + t.Fatal("expected array of length 1") + } + if len(res.Gen[0].AttrStrings("default_visibility")) != 2 { + t.Fatal("expected array of length 2") + } + if testVis1 != res.Gen[0].AttrStrings("default_visibility")[0] { + t.Fatal("expected returned visibility to match '//src:__subpackages__'") + } + if testVis2 != res.Gen[0].AttrStrings("default_visibility")[1] { + t.Fatal("expected returned visibility to match '//src2:__subpackages__'") + } +} diff --git a/language/bazel/visibility/resolve.go b/language/bazel/visibility/resolve.go new file mode 100644 index 000000000..c1be809d7 --- /dev/null +++ b/language/bazel/visibility/resolve.go @@ -0,0 +1,32 @@ +package visibility + +import ( + "github.com/bazelbuild/bazel-gazelle/config" + "github.com/bazelbuild/bazel-gazelle/label" + "github.com/bazelbuild/bazel-gazelle/repo" + "github.com/bazelbuild/bazel-gazelle/resolve" + "github.com/bazelbuild/bazel-gazelle/rule" +) + +const ( + _extName = "visibility_extension" +) + +// Name returns the extension name. +func (*visibilityExtension) Name() string { + return _extName +} + +// Imports noops because no imports are needed to leverage this functionality. +func (*visibilityExtension) Imports(c *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec { + return nil +} + +// Embeds noops because we are not a traditional rule, and cannot be embedded. +func (*visibilityExtension) Embeds(r *rule.Rule, from label.Label) []label.Label { + return nil +} + +// Resolve noops because we don't have deps=[] to resolve. +func (*visibilityExtension) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imports interface{}, from label.Label) { +}