diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 000000000..6fb14b34f --- /dev/null +++ b/.bazelignore @@ -0,0 +1 @@ +bcr_tests diff --git a/.gitignore b/.gitignore index 5fd2c8a7e..39d90e25b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ bazel-bazel-gazelle +bcr_tests/bazel-bcr_tests bazel-bin bazel-genfiles bazel-out bazel-testlogs +/.ijwb diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..90e684ba7 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,279 @@ +module( + name = "bazel_gazelle", + version = "0.25.0", +) + +print("WARNING: The bazel_gazelle Bazel module is still highly experimental and subject to change at any time. Only use it to try out bzlmod for now.") + +bazel_dep(name = "bazel_skylib", version = "1.2.0") +bazel_dep(name = "rules_go", version = "0.33.0", repo_name = "io_bazel_rules_go") +local_path_override( + module_name = "rules_go", + path = "../rules_go", +) + +go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") + +# Known to exist since it is instantiated by rules_go itself. +use_repo(go_sdk, "go_default_sdk") + +non_module_deps = use_extension("@bazel_gazelle//internal/bzlmod:non_module_deps.bzl", "non_module_deps") +use_repo( + non_module_deps, + "bazel_gazelle_go_repository_cache", + "bazel_gazelle_go_repository_config", + "bazel_gazelle_go_repository_tools", +) + +go_dep = use_extension("@bazel_gazelle//:extensions.bzl", "go_dep") +go_dep.mod( + importpath = "honnef.co/go/tools", + sum = "h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=", + version = "v0.0.0-20190523083050-ea95bdfd59fc", +) +go_dep.mod( + importpath = "github.com/bazelbuild/buildtools", + sum = "h1:ox8T5nCkvLflRgKZ6uzzdvLDN3gbNZBgLBqA5Xgn7QA=", + version = "v0.0.0-20220323134444-a9f46b2bb3de", + build_naming_convention = "go_default_library", +) +go_dep.mod( + importpath = "github.com/bazelbuild/rules_go", + sum = "h1:8/MDe6zCE7nYKXhlbamM1izUgJjw2ce7M5kd4QKF/3Y=", + version = "v0.31.0", +) +go_dep.mod( + importpath = "github.com/bmatcuk/doublestar/v4", + sum = "h1:X0krlUVAVmtr2cRoTqR8aDMrDqnB36ht8wpWTiQ3jsA=", + version = "v4.0.2", +) +go_dep.mod( + importpath = "github.com/BurntSushi/toml", + sum = "h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=", + version = "v0.3.1", +) +go_dep.mod( + importpath = "github.com/census-instrumentation/opencensus-proto", + sum = "h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=", + version = "v0.2.1", +) +go_dep.mod( + importpath = "github.com/chzyer/logex", + sum = "h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=", + version = "v1.1.10", +) +go_dep.mod( + importpath = "github.com/chzyer/readline", + sum = "h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=", + version = "v0.0.0-20180603132655-2972be24d48e", +) +go_dep.mod( + importpath = "github.com/chzyer/test", + sum = "h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=", + version = "v0.0.0-20180213035817-a1ea475d72b1", +) +go_dep.mod( + importpath = "github.com/client9/misspell", + sum = "h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=", + version = "v0.3.4", +) +go_dep.mod( + importpath = "github.com/davecgh/go-spew", + sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=", + version = "v1.1.1", +) +go_dep.mod( + importpath = "github.com/envoyproxy/go-control-plane", + sum = "h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=", + version = "v0.9.1-0.20191026205805-5f8ba28d4473", +) +go_dep.mod( + importpath = "github.com/envoyproxy/protoc-gen-validate", + sum = "h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=", + version = "v0.1.0", +) +go_dep.mod( + importpath = "github.com/fsnotify/fsnotify", + sum = "h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=", + version = "v1.5.1", +) +go_dep.mod( + importpath = "github.com/golang/glog", + sum = "h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=", + version = "v0.0.0-20160126235308-23def4e6c14b", +) +go_dep.mod( + importpath = "github.com/golang/mock", + sum = "h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=", + version = "v1.1.1", +) +go_dep.mod( + importpath = "github.com/golang/protobuf", + sum = "h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=", + version = "v1.4.3", +) +go_dep.mod( + importpath = "github.com/google/go-cmp", + sum = "h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=", + version = "v0.5.7", +) +go_dep.mod( + importpath = "github.com/pelletier/go-toml", + sum = "h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=", + version = "v1.9.4", +) +go_dep.mod( + importpath = "github.com/pmezard/go-difflib", + sum = "h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=", + version = "v1.0.0", +) +go_dep.mod( + importpath = "github.com/prometheus/client_model", + sum = "h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=", + version = "v0.0.0-20190812154241-14fe0d1b01d4", +) +go_dep.mod( + importpath = "github.com/yuin/goldmark", + sum = "h1:OtISOGfH6sOWa1/qXqqAiOIAO6Z5J3AEAE18WAq6BiQ=", + version = "v1.4.0", +) +go_dep.mod( + importpath = "cloud.google.com/go", + sum = "h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=", + version = "v0.26.0", +) +go_dep.mod( + importpath = "gopkg.in/check.v1", + sum = "h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=", + version = "v0.0.0-20161208181325-20d25e280405", +) +go_dep.mod( + importpath = "gopkg.in/yaml.v2", + sum = "h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=", + version = "v2.2.2", +) +go_dep.mod( + importpath = "go.starlark.net", + sum = "h1:xwwDQW5We85NaTk2APgoN9202w/l0DVGp+GZMfsrh7s=", + version = "v0.0.0-20210223155950-e043a3d3c984", +) +go_dep.mod( + importpath = "google.golang.org/appengine", + sum = "h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=", + version = "v1.4.0", +) +go_dep.mod( + importpath = "google.golang.org/genproto", + sum = "h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=", + version = "v0.0.0-20200526211855-cb27e3aa2013", +) +go_dep.mod( + importpath = "google.golang.org/grpc", + sum = "h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=", + version = "v1.27.0", +) +go_dep.mod( + importpath = "google.golang.org/protobuf", + sum = "h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=", + version = "v1.25.0", +) +go_dep.mod( + importpath = "golang.org/x/crypto", + sum = "h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=", + version = "v0.0.0-20191011191535-87dc89f01550", +) +go_dep.mod( + importpath = "golang.org/x/exp", + sum = "h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=", + version = "v0.0.0-20190121172915-509febef88a4", +) +go_dep.mod( + importpath = "golang.org/x/lint", + sum = "h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=", + version = "v0.0.0-20190313153728-d0100b6bd8b3", +) +go_dep.mod( + importpath = "golang.org/x/mod", + sum = "h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=", + version = "v0.6.0-dev.0.20220106191415-9b9b3d81d5e3", +) +go_dep.mod( + importpath = "golang.org/x/net", + sum = "h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI=", + version = "v0.0.0-20210805182204-aaa1db679c0d", +) +go_dep.mod( + importpath = "golang.org/x/oauth2", + sum = "h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=", + version = "v0.0.0-20180821212333-d2e6202438be", +) +go_dep.mod( + importpath = "golang.org/x/sync", + sum = "h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=", + version = "v0.0.0-20210220032951-036812b2e83c", +) +go_dep.mod( + importpath = "golang.org/x/sys", + sum = "h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs=", + version = "v0.0.0-20220319134239-a9b59b0215f8", +) +go_dep.mod( + importpath = "golang.org/x/text", + sum = "h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=", + version = "v0.3.6", +) +go_dep.mod( + importpath = "golang.org/x/tools", + sum = "h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=", + version = "v0.1.10", +) +go_dep.mod( + importpath = "golang.org/x/xerrors", + sum = "h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=", + version = "v0.0.0-20200804184101-5ec99f83aff1", +) +use_repo( + go_dep, + "bazel_gazelle_go_repository_directives", + "co_honnef_go_tools", + "com_github_bazelbuild_buildtools", + "com_github_bazelbuild_rules_go", + "com_github_bmatcuk_doublestar_v4", + "com_github_burntsushi_toml", + "com_github_census_instrumentation_opencensus_proto", + "com_github_chzyer_logex", + "com_github_chzyer_readline", + "com_github_chzyer_test", + "com_github_client9_misspell", + "com_github_davecgh_go_spew", + "com_github_envoyproxy_go_control_plane", + "com_github_envoyproxy_protoc_gen_validate", + "com_github_fsnotify_fsnotify", + "com_github_golang_glog", + "com_github_golang_mock", + "com_github_golang_protobuf", + "com_github_google_go_cmp", + "com_github_pelletier_go_toml", + "com_github_pmezard_go_difflib", + "com_github_prometheus_client_model", + "com_github_yuin_goldmark", + "com_google_cloud_go", + "in_gopkg_check_v1", + "in_gopkg_yaml_v2", + "net_starlark_go", + "org_golang_google_appengine", + "org_golang_google_genproto", + "org_golang_google_grpc", + "org_golang_google_protobuf", + "org_golang_x_crypto", + "org_golang_x_exp", + "org_golang_x_lint", + "org_golang_x_mod", + "org_golang_x_net", + "org_golang_x_oauth2", + "org_golang_x_sync", + "org_golang_x_sys", + "org_golang_x_text", + "org_golang_x_tools", + "org_golang_x_xerrors", +) diff --git a/bcr_tests/.bazelrc b/bcr_tests/.bazelrc new file mode 100644 index 000000000..e2ece0c38 --- /dev/null +++ b/bcr_tests/.bazelrc @@ -0,0 +1 @@ +build --experimental_enable_bzlmod diff --git a/bcr_tests/.bazelversion b/bcr_tests/.bazelversion new file mode 100644 index 000000000..7229a26b2 --- /dev/null +++ b/bcr_tests/.bazelversion @@ -0,0 +1 @@ +6.0.0-pre.20220526.1 diff --git a/bcr_tests/BUILD.bazel b/bcr_tests/BUILD.bazel new file mode 100644 index 000000000..e63e4b697 --- /dev/null +++ b/bcr_tests/BUILD.bazel @@ -0,0 +1,6 @@ +load("@rules_go//go:def.bzl", "go_binary") + +go_binary( + name = "use_tools", + srcs = ["use_tools.go"], +) diff --git a/bcr_tests/MODULE.bazel b/bcr_tests/MODULE.bazel new file mode 100644 index 000000000..5aca36f7a --- /dev/null +++ b/bcr_tests/MODULE.bazel @@ -0,0 +1,16 @@ +module( + name = "bazel_gazelle_bcr_tests", +) + +bazel_dep(name = "bazel_gazelle", version = "") +local_path_override( + module_name = "bazel_gazelle", + path = "..", +) + +bazel_dep(name = "rules_go", version = "") + +go_dep = use_extension("@bazel_gazelle//:extensions.bzl", "go_dep") +go_dep.mod(importpath = "golang.org/x/tools", version = "0.1.9") +go_dep.mod(importpath = "github.com/golang/protobuf/protoc-gen-go", version = "1.3.3") +use_repo(go_dep, "org_golang_x_tools", "com_github_golang_protobuf_protoc_gen_go") diff --git a/bcr_tests/WORKSPACE b/bcr_tests/WORKSPACE new file mode 100644 index 000000000..e69de29bb diff --git a/bcr_tests/use_tools.go b/bcr_tests/use_tools.go new file mode 100644 index 000000000..790580777 --- /dev/null +++ b/bcr_tests/use_tools.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} diff --git a/extensions.bzl b/extensions.bzl new file mode 100644 index 000000000..fc6c64f13 --- /dev/null +++ b/extensions.bzl @@ -0,0 +1,3 @@ +load("//internal/bzlmod:go_dep.bzl", _go_dep = "go_dep") + +go_dep = _go_dep diff --git a/internal/BUILD.bazel b/internal/BUILD.bazel index e92b030e8..e14a85544 100644 --- a/internal/BUILD.bazel +++ b/internal/BUILD.bazel @@ -50,6 +50,7 @@ filegroup( "overlay_repository.bzl", "repository_docs.bzl", "repository_rules_test_errors.patch", + "//internal/bzlmod:all_files", "//internal/gazellebinarytest:all_files", "//internal/generationtest:all_files", "//internal/language:all_files", diff --git a/internal/bzlmod/BUILD.bazel b/internal/bzlmod/BUILD.bazel new file mode 100644 index 000000000..1fddb00c4 --- /dev/null +++ b/internal/bzlmod/BUILD.bazel @@ -0,0 +1,11 @@ +filegroup( + name = "all_files", + testonly = True, + srcs = [ + "BUILD.bazel", + "go_dep.bzl", + "non_module_deps.bzl", + "semver.bzl", + ], + visibility = ["//visibility:public"], +) diff --git a/internal/bzlmod/go_dep.bzl b/internal/bzlmod/go_dep.bzl new file mode 100644 index 000000000..9a076cb6e --- /dev/null +++ b/internal/bzlmod/go_dep.bzl @@ -0,0 +1,88 @@ +load("//internal:go_repository.bzl", "go_repository") +load(":semver.bzl", "semver") + +def _repo_name(importpath): + path_segments = importpath.split("/") + segments = reversed(path_segments[0].split(".")) + path_segments[1:] + return "_".join(segments).replace("-", "_") + +def _go_repository_directives_impl(ctx): + directives = [ + "# gazelle:repository go_repository name={name} {directives}".format( + name = name, + directives = " ".join(directives), + ) + for name, directives in ctx.attr.directives.items() + ] + ctx.file("WORKSPACE", "\n".join(directives)) + ctx.file("BUILD.bazel") + +_go_repository_directives = repository_rule( + implementation = _go_repository_directives_impl, + attrs = { + "directives": attr.string_list_dict(mandatory = True), + }, +) + +def _go_dep_impl(module_ctx): + resolved_mods = {} + for module in module_ctx.modules: + importpaths = {} + for mod_tag in module.tags.mod: + if mod_tag.importpath in importpaths: + fail("Duplicate importpath '%s' in module '%s'" % (mod_tag.importpath, module.name)) + importpaths[mod_tag.importpath] = None + raw_version = mod_tag.version + if raw_version.startswith("v"): + raw_version = raw_version[1:] + new_version = semver.parse(raw_version) + highest_version = resolved_mods.get(mod_tag.importpath, default = None) + if not highest_version or semver.is_higher(new_version, highest_version): + resolved_mods[mod_tag.importpath] = struct( + module = module.name, + repo_name = _repo_name(mod_tag.importpath), + version = new_version, + sum = mod_tag.sum, + build_naming_convention = mod_tag.build_naming_convention, + ) + [ + go_repository( + name = module.repo_name, + importpath = importpath, + sum = module.sum, + version = "v" + semver.to_string(module.version), + build_naming_convention = module.build_naming_convention, + ) + for importpath, module in resolved_mods.items() + ] + # With transitive dependencies, Gazelle would no longer just have to pass a + # single top-level WORKSPACE/MODULE.bazel file, but those of all modules + # that use the go_dep tag. Instead, emit a synthetic WORKSPACE file with + # Gazelle directives for all of those modules here. + directives = { + module.repo_name: [ + "importpath=" + importpath, + "build_naming_convention=" + module.build_naming_convention, + ] + for importpath, module in resolved_mods.items() + } + _go_repository_directives( + name = "bazel_gazelle_go_repository_directives", + directives = directives, + ) + +_mod_tag = tag_class( + attrs = { + "importpath": attr.string(mandatory = True), + "version": attr.string(mandatory = True), + "sum": attr.string(), + "build_naming_convention": attr.string(default = "import_alias"), + }, +) + +go_dep = module_extension( + _go_dep_impl, + tag_classes = { + "mod": _mod_tag, + }, +) diff --git a/internal/bzlmod/non_module_deps.bzl b/internal/bzlmod/non_module_deps.bzl new file mode 100644 index 000000000..143b14b14 --- /dev/null +++ b/internal/bzlmod/non_module_deps.bzl @@ -0,0 +1,33 @@ +load( + "@bazel_gazelle//internal:go_repository_cache.bzl", + "go_repository_cache", +) +load( + "@bazel_gazelle//internal:go_repository_tools.bzl", + "go_repository_tools", +) +load( + "@bazel_gazelle//internal:go_repository_config.bzl", + "go_repository_config", +) + +def _non_module_deps_impl(module_ctx): + go_repository_cache( + name = "bazel_gazelle_go_repository_cache", + # Always provided by rules_go. + go_sdk_name = "go_default_sdk", + go_env = {}, + ) + go_repository_tools( + name = "bazel_gazelle_go_repository_tools", + go_cache = Label("@bazel_gazelle_go_repository_cache//:go.env"), + ) + go_repository_config( + name = "bazel_gazelle_go_repository_config", + # Generated by the go_dep module extension. + config = Label("@bazel_gazelle_go_repository_directives//:WORKSPACE"), + ) + +non_module_deps = module_extension( + _non_module_deps_impl, +) diff --git a/internal/bzlmod/semver.bzl b/internal/bzlmod/semver.bzl new file mode 100644 index 000000000..53ee1bd62 --- /dev/null +++ b/internal/bzlmod/semver.bzl @@ -0,0 +1,41 @@ +def _is_higher(v1, v2): + if v1.major != v2.major: + return v1.major > v2.major + if v1.minor != v2.minor: + return v1.minor > v2.minor + if v1.patch != v2.patch: + return v1.patch > v2.patch + if (v1.prerelease == None) != (v2.prerelease == None): + return v1.prerelease == None + +def _parse(s): + """ + Parses a string representation of a semver version into a struct. + """ + major, _, remainder = s.partition(".") + minor, _, remainder = remainder.partition(".") + + # Strip build metadata. + remainder, _, _ = remainder.partition("+") + if "-" in remainder: + patch, _, prerelease = remainder.partition("-") + else: + patch, prerelease = remainder, None + return struct( + major = int(major), + minor = int(minor), + patch = int(patch), + prerelease = tuple(prerelease.split(".")) if prerelease != None else None, + ) + +def _to_string(version): + if version.prerelease: + return "%d.%d.%d-%s" % (version.major, version.minor, version.patch, ".".join(version.prerelease)) + else: + return "%d.%d.%d" % (version.major, version.minor, version.patch) + +semver = struct( + is_higher = _is_higher, + parse = _parse, + to_string = _to_string, +) diff --git a/internal/go_repository_tools_srcs.bzl b/internal/go_repository_tools_srcs.bzl index 48de4e3a2..800cddfd4 100644 --- a/internal/go_repository_tools_srcs.bzl +++ b/internal/go_repository_tools_srcs.bzl @@ -30,6 +30,7 @@ GO_REPOSITORY_TOOLS_SRCS = [ "@bazel_gazelle//flag:BUILD.bazel", "@bazel_gazelle//flag:flag.go", "@bazel_gazelle//internal:BUILD.bazel", + "@bazel_gazelle//internal/bzlmod:BUILD.bazel", "@bazel_gazelle//internal/gazellebinarytest:BUILD.bazel", "@bazel_gazelle//internal/gazellebinarytest:xlang.go", "@bazel_gazelle//internal/generationtest:BUILD.bazel", diff --git a/internal/list_repository_tools_srcs.go b/internal/list_repository_tools_srcs.go index b3dc25db9..4c477890e 100644 --- a/internal/list_repository_tools_srcs.go +++ b/internal/list_repository_tools_srcs.go @@ -68,7 +68,7 @@ func main() { } base := filepath.Base(path) - if base == "docs" || base == "vendor" || base == "third_party" || base == "testdata" { + if base == "bcr_tests" || base == "docs" || base == "vendor" || base == "third_party" || base == "testdata" { return filepath.SkipDir } if !info.IsDir() &&