From 9304905660f3ed55c10f36ad03103d7909542a87 Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Thu, 18 Apr 2024 13:01:20 -0600 Subject: [PATCH] [Feature] go.mod & go.work FilePath ReplaceDirective support --- cmd/fetch_repo/BUILD.bazel | 2 + cmd/fetch_repo/fetch_repo.go | 31 ++++++++- cmd/fetch_repo/module.go | 6 +- cmd/fetch_repo/path.go | 37 +++++++++++ internal/bzlmod/BUILD.bazel | 3 + internal/bzlmod/go_deps.bzl | 48 ++++++++++---- internal/bzlmod/go_mod.bzl | 84 +++++++++++++++++++++---- internal/bzlmod/semver.bzl | 12 ++-- internal/go_repository.bzl | 43 +++++++++++-- internal/go_repository_tools_srcs.bzl | 1 + repository.md | 7 ++- tests/bcr/go_mod/MODULE.bazel | 1 + tests/bcr/go_mod/go.mod | 14 ++++- tests/bcr/go_mod/go.sum | 90 ++++++++++++++++++++++++--- tests/bcr/go_mod/pkg/BUILD.bazel | 1 + tests/bcr/go_mod/pkg/pkg_test.go | 7 +++ tests/bcr/go_work/MODULE.bazel | 1 + tests/bcr/go_work/go.work | 10 +-- tests/bcr/go_work/pkg/BUILD.bazel | 1 + tests/bcr/go_work/pkg/go.mod | 4 ++ tests/bcr/go_work/pkg/go.sum | 11 +++- tests/bcr/go_work/pkg/pkg_test.go | 7 +++ tests/bzlmod/go_mod_test.bzl | 17 +++-- tests/fixtures/hello/go.mod | 10 +++ tests/fixtures/hello/go.sum | 6 ++ tests/fixtures/hello/hello.go | 7 +++ tests/fixtures/hello/hello_test.go | 10 +++ 27 files changed, 405 insertions(+), 66 deletions(-) create mode 100644 cmd/fetch_repo/path.go create mode 100644 tests/fixtures/hello/go.mod create mode 100644 tests/fixtures/hello/go.sum create mode 100644 tests/fixtures/hello/hello.go create mode 100644 tests/fixtures/hello/hello_test.go diff --git a/cmd/fetch_repo/BUILD.bazel b/cmd/fetch_repo/BUILD.bazel index f0ffdb009..4e089c907 100644 --- a/cmd/fetch_repo/BUILD.bazel +++ b/cmd/fetch_repo/BUILD.bazel @@ -7,6 +7,7 @@ go_library( "fetch_repo.go", "go_mod_download.go", "module.go", + "path.go", "vcs.go", ], importpath = "github.com/bazelbuild/bazel-gazelle/cmd/fetch_repo", @@ -40,6 +41,7 @@ filegroup( "fetch_repo_test.go", "go_mod_download.go", "module.go", + "path.go", "vcs.go", ], visibility = ["//visibility:public"], diff --git a/cmd/fetch_repo/fetch_repo.go b/cmd/fetch_repo/fetch_repo.go index f494bf81a..7646be916 100644 --- a/cmd/fetch_repo/fetch_repo.go +++ b/cmd/fetch_repo/fetch_repo.go @@ -34,6 +34,7 @@ import ( var ( // Common flags importpath = flag.String("importpath", "", "Go importpath to the repository fetch") + path = flag.String("path", "", "absolute or relative path to a local go module") dest = flag.String("dest", "", "destination directory") // Repository flags @@ -54,9 +55,11 @@ func main() { log.SetPrefix("fetch_repo: ") flag.Parse() - if *importpath == "" { - log.Fatal("-importpath must be set") + + if *importpath == "" && *path == "" { + log.Fatal("-importpath or -path must be set") } + if *dest == "" { log.Fatal("-dest must be set") } @@ -64,7 +67,29 @@ func main() { log.Fatal("fetch_repo does not accept positional arguments") } - if *version != "" { + if *path != "" { + if *importpath != "" { + log.Fatal("-importpath must not be set") + } + if *remote != "" { + log.Fatal("-remote must not be set in module path mode") + } + if *cmd != "" { + log.Fatal("-vcs must not be set in module path mode") + } + if *rev != "" { + log.Fatal("-rev must not be set in module path mode") + } + if *version != "" { + log.Fatal("-version must not be set in module path mode") + } + if *sum != "" { + log.Fatal("-sum must not be set in module path mode") + } + if err := moduleFromPath(*path, *dest); err != nil { + log.Fatal(err) + } + } else if *version != "" { if *remote != "" { log.Fatal("-remote must not be set in module mode") } diff --git a/cmd/fetch_repo/module.go b/cmd/fetch_repo/module.go index 353d007a9..dab2fab97 100644 --- a/cmd/fetch_repo/module.go +++ b/cmd/fetch_repo/module.go @@ -17,8 +17,9 @@ package main import ( "fmt" - "golang.org/x/mod/sumdb/dirhash" "os" + + "golang.org/x/mod/sumdb/dirhash" ) func fetchModule(dest, importpath, version, sum string) error { @@ -33,7 +34,6 @@ func fetchModule(dest, importpath, version, sum string) error { // so we create a dummy module in the current directory (which should be // empty). w, err := os.OpenFile("go.mod", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o666) - if err != nil { return fmt.Errorf("error creating temporary go.mod: %v", err) } @@ -46,7 +46,7 @@ func fetchModule(dest, importpath, version, sum string) error { return fmt.Errorf("error closing temporary go.mod: %v", err) } - var dl = GoModDownloadResult{} + dl := GoModDownloadResult{} err = runGoModDownload(&dl, dest, importpath, version) os.Remove("go.mod") if err != nil { diff --git a/cmd/fetch_repo/path.go b/cmd/fetch_repo/path.go new file mode 100644 index 000000000..0dcc4318f --- /dev/null +++ b/cmd/fetch_repo/path.go @@ -0,0 +1,37 @@ +/* Copyright 2019 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 main + +import ( + "fmt" + "os/exec" +) + +func moduleFromPath(from string, dest string) error { + err := copyTree(dest, from) + if err != nil { + return err + } + + cmd := exec.Command(findGoPath(), "mod", "download", "-json", "-modcacherw") + cmd.Dir = dest + + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("error running '%v': %v in %s. Output: %s", cmd.Args, err, dest, string(output)) + } + return nil +} diff --git a/internal/bzlmod/BUILD.bazel b/internal/bzlmod/BUILD.bazel index 2bac102aa..20dd82709 100644 --- a/internal/bzlmod/BUILD.bazel +++ b/internal/bzlmod/BUILD.bazel @@ -30,6 +30,9 @@ bzl_library( name = "go_mod", srcs = ["go_mod.bzl"], visibility = ["//:__subpackages__"], + deps = [ + ":semver", + ], ) bzl_library( diff --git a/internal/bzlmod/go_deps.bzl b/internal/bzlmod/go_deps.bzl index bdbda4519..15ad27517 100644 --- a/internal/bzlmod/go_deps.bzl +++ b/internal/bzlmod/go_deps.bzl @@ -19,8 +19,8 @@ load( "DEFAULT_BUILD_FILE_GENERATION_BY_PATH", "DEFAULT_DIRECTIVES_BY_PATH", ) -load(":go_mod.bzl", "deps_from_go_mod", "parse_go_work", "sums_from_go_mod", "sums_from_go_work") -load(":semver.bzl", "semver") +load(":go_mod.bzl", "deps_from_go_mod", "go_work_from_label", "sums_from_go_mod", "sums_from_go_work") +load(":semver.bzl", "semver", "COMPARES_HIGHEST_SENTINEL") load( ":utils.bzl", "drop_nones", @@ -83,12 +83,6 @@ _GAZELLE_ATTRS = { ), } -def go_work_from_label(module_ctx, go_work_label): - """Loads deps from a go.work file""" - go_work_path = module_ctx.path(go_work_label) - go_work_content = module_ctx.read(go_work_path) - return parse_go_work(go_work_content, go_work_label) - def _fail_on_non_root_overrides(module_ctx, module, tag_class): if module.is_root: return @@ -299,6 +293,10 @@ def check_for_version_conflict(version, previous, module_tag, module_name_to_go_ # version is the same, skip because we won't error return + if hasattr(module_tag, "local_path"): + # overrides are not considered for version conflicts + return + # When using go.work, duplicate dependency versions are possible. # This can cause issues, so we fail with a hopefully actionable error. current_label = module_tag._parent_label @@ -435,7 +433,10 @@ def _go_deps_impl(module_ctx): ] if module.is_root or getattr(module_ctx, "is_isolated", False): - replace_map.update(go_mod_replace_map) + # for the replace_map, first in wins + for mod_path, mod in go_mod_replace_map.items(): + if not mod_path in replace_map: + replace_map[mod_path] = mod else: # Register this Bazel module as providing the specified Go module. It participates # in version resolution using its registry version, which uses a relaxed variant of @@ -507,10 +508,21 @@ def _go_deps_impl(module_ctx): paths[module_tag.path] = struct(version = version, module_tag = module_tag) if module_tag.path not in module_resolutions or version > module_resolutions[module_tag.path].version: + to_path = None + local_path= None + + if module_tag.path in replace_map: + replacement = replace_map[module_tag.path] + + to_path = replacement.to_path + local_path= replacement.local_path + module_resolutions[module_tag.path] = struct( repo_name = _repo_name(module_tag.path), version = version, raw_version = raw_version, + to_path = to_path, + local_path = local_path, ) _fail_on_unmatched_overrides(archive_overrides.keys(), module_resolutions, "archive_overrides") @@ -536,6 +548,7 @@ def _go_deps_impl(module_ctx): version = new_version, raw_version = replace.version, ) + if path in root_versions: if replace != replace.to_path: # If the root module replaces a Go module with a completely different one, do @@ -585,7 +598,6 @@ def _go_deps_impl(module_ctx): # Do not create a go_repository for a dep shared with the non-isolated instance of # go_deps. continue - go_repository_args = { "name": module.repo_name, "importpath": path, @@ -605,6 +617,12 @@ def _go_deps_impl(module_ctx): "patches": _get_patches(path, archive_overrides), "patch_args": _get_patch_args(path, archive_overrides), }) + elif module.local_path: + go_repository_args.update({ + # the version is now meaningless + "version": None, + "local_path": module.local_path, + }) else: go_repository_args.update({ "sum": _get_sum_from_module(path, module, sums), @@ -659,7 +677,11 @@ def _get_sum_from_module(path, module, sums): entry = (module.replace, module.raw_version) if entry not in sums: - fail("No sum for {}@{} found. You may need to run: bazel run @rules_go//go -- mod tidy".format(path, module.raw_version)) + if module.raw_version == COMPARES_HIGHEST_SENTINEL: + # replacement have no sums, so we can skip this + return None + elif module.local_path== None: + fail("No sum for {}@{} from {} found. You may need to run: bazel run @rules_go//go -- mod tidy".format(path, module.raw_version, "parent-label-todo")) #module.parent_label)) return sums[entry] @@ -706,6 +728,10 @@ _module_tag = tag_class( ), "build_naming_convention": attr.string(doc = """Removed, do not use""", default = ""), "build_file_proto_mode": attr.string(doc = """Removed, do not use""", default = ""), + "local_path": attr.string( + doc = """For when a module is replaced by one residing in a local directory path """, + mandatory = False, + ), }, ) diff --git a/internal/bzlmod/go_mod.bzl b/internal/bzlmod/go_mod.bzl index 9f07ff8cf..80556543f 100644 --- a/internal/bzlmod/go_mod.bzl +++ b/internal/bzlmod/go_mod.bzl @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +load(":semver.bzl", "COMPARES_HIGHEST_SENTINEL") + visibility([ "//tests/bzlmod/...", ]) @@ -28,6 +30,9 @@ def use_spec_to_label(repo_name, use_directive): if use_directive.startswith("../") or "/../" in use_directive or use_directive.endswith("/.."): fail("go.work use directive: '{}' contains '..' which is not currently supported.".format(use_directive)) + if use_directive.startswith("/"): + fail("go.work use directive: '{}' is an absolute path, which is not currently supported.".format(use_directive)) + if use_directive.startswith("./"): use_directive = use_directive[2:] @@ -36,6 +41,14 @@ def use_spec_to_label(repo_name, use_directive): return Label("@@{}//{}:go.mod".format(repo_name, use_directive)) +def go_work_from_label(module_ctx, go_work_label): + """Loads deps from a go.work file""" + go_work_path = module_ctx.path(go_work_label) + go_work_content = module_ctx.read(go_work_path) + go_work = parse_go_work(go_work_content, go_work_label) + + return _relativize_replace_paths(go_work, go_work_path) + def parse_go_work(content, go_work_label): # see: https://go.dev/ref/mod#go-work-file @@ -91,7 +104,7 @@ def parse_go_work(content, go_work_label): go_mods = [use_spec_to_label(go_work_label.workspace_name, use) for use in state["use"]] from_file_tags = [struct(go_mod = go_mod, _is_dev_dependency = False) for go_mod in go_mods] - module_tags = [struct(version = mod.version, path = mod.to_path, _parent_label = go_work_label, indirect = False) for mod in state["replace"].values()] + module_tags = [struct(version = mod.version, path = mod.to_path, _parent_label = go_work_label, local_path = mod.local_path, indirect = False) for mod in state["replace"].values()] return struct( go = (int(major), int(minor)), @@ -101,6 +114,39 @@ def parse_go_work(content, go_work_label): use = state["use"], ) +# this exists because we are unable to create a path object in unit tests, we +# must do this as a post-process step or we cannot unit test go_mod parsing +def _relativize_replace_paths(go_mod, go_mod_path): + new_replace_map = {} + + for key in go_mod.replace_map: + value = go_mod.replace_map[key] + + local_path = value.local_path + + if local_path: + # drop the go.mod from the path, to get the directory + directory = go_mod_path.dirname + + # now that we have the directory, we can use the use replace directive to get the full path + local_path = str(directory.get_child(local_path)) + + new_replace_map[key] = struct( + from_version = value.from_version, + to_path = value.to_path, + version = value.version, + local_path = local_path, + ) + + new_go_mod = { + attr: getattr(go_mod, attr) + for attr in dir(go_mod) + if not type(getattr(go_mod, attr)) == 'builtin_function_or_method' + } + + new_go_mod["replace_map"] = new_replace_map + return struct(**new_go_mod) + def deps_from_go_mod(module_ctx, go_mod_label): """Loads the entries from a go.mod file. @@ -118,6 +164,7 @@ def deps_from_go_mod(module_ctx, go_mod_label): go_mod_path = module_ctx.path(go_mod_label) go_mod_content = module_ctx.read(go_mod_path) go_mod = parse_go_mod(go_mod_content, go_mod_path) + go_mod = _relativize_replace_paths(go_mod, go_mod_path) if go_mod.go[0] != 1 or go_mod.go[1] < 17: # go.mod files only include entries for all transitive dependencies as @@ -130,6 +177,7 @@ def deps_from_go_mod(module_ctx, go_mod_label): path = require.path, version = require.version, indirect = require.indirect, + local_path = None, _parent_label = go_mod_label, )) @@ -225,11 +273,6 @@ def _parse_directive(state, directive, tokens, comment, path, line_no): # TODO: Handle exclude. def _parse_replace_directive(state, tokens, path, line_no): - # A replace directive might use a local file path beginning with ./ or ../ - # These are not supported with gazelle~go_deps. - if (len(tokens) == 3 and tokens[2][0] == ".") or (len(tokens) > 3 and tokens[3][0] == "."): - fail("{}:{}: local file path not supported in replace directive: '{}'".format(path, line_no, tokens[2])) - # replacements key off of the from_path from_path = tokens[0] @@ -238,23 +281,38 @@ def _parse_replace_directive(state, tokens, path, line_no): state["replace"][from_path] = struct( from_version = None, to_path = tokens[2], + local_path = None, version = _canonicalize_raw_version(tokens[3]), ) - # pattern: replace from_path from_version => to_path to_version + # pattern: replace from_path from_version => to_path to_version elif len(tokens) == 5 and tokens[2] == "=>": state["replace"][from_path] = struct( from_version = _canonicalize_raw_version(tokens[1]), to_path = tokens[3], version = _canonicalize_raw_version(tokens[4]), + local_path = None, ) - else: - fail( - "{}:{}: replace directive must follow pattern: ".format(path, line_no) + - "'replace from_path from_version => to_path to_version' or " + - "'replace from_path => to_path to_version'", - "but got: '{} {} {}'".format(*tokens), + + # pattern: replace from_path from_version => file_path + elif len(tokens) == 4 and tokens[2] == "=>": + state["replace"][from_path] = struct( + from_version = _canonicalize_raw_version(tokens[1]), + to_path = from_path, + local_path = tokens[3], + version = COMPARES_HIGHEST_SENTINEL + ) + + # pattern: replace from_path => to_path + elif len(tokens) == 3 and tokens[1] == "=>": + state["replace"][from_path] = struct( + from_version = None, + to_path = from_path, + local_path = tokens[2], + version = COMPARES_HIGHEST_SENTINEL ) + else: + fail("{}:{}: unexpected tokens '{}'".format(path, line_no, tokens)) def _tokenize_line(line, path, line_no): tokens = [] diff --git a/internal/bzlmod/semver.bzl b/internal/bzlmod/semver.bzl index d79a4f4bf..2ae030840 100644 --- a/internal/bzlmod/semver.bzl +++ b/internal/bzlmod/semver.bzl @@ -17,10 +17,10 @@ visibility([ ]) # Compares lower than any non-numeric identifier. -_COMPARES_LOWEST_SENTINEL = "" +COMPARES_LOWEST_SENTINEL = "" # Compares higher than any valid non-numeric identifier (containing only [A-Za-z0-9-]). -_COMPARES_HIGHEST_SENTINEL = "{" +COMPARES_HIGHEST_SENTINEL = "{" def _identifier_to_comparable(ident, *, numeric_only): if not ident: @@ -33,7 +33,9 @@ def _identifier_to_comparable(ident, *, numeric_only): # "Identifiers consisting of only digits are compared numerically." # 11.4.3: # "Numeric identifiers always have lower precedence than non-numeric identifiers." - return (_COMPARES_LOWEST_SENTINEL, int(ident)) + return (COMPARES_LOWEST_SENTINEL, int(ident)) + elif ident == COMPARES_HIGHEST_SENTINEL: + return (ident,) elif numeric_only: fail("Expected a numeric identifier, got: " + ident) else: @@ -64,10 +66,10 @@ def _semver_to_comparable(v, *, relaxed = False): else: # 11.3: # "When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version." - prerelease = [(_COMPARES_HIGHEST_SENTINEL,)] + prerelease = [(COMPARES_HIGHEST_SENTINEL,)] release = release_str.split(".") - if not relaxed and len(release) != 3: + if not v == COMPARES_HIGHEST_SENTINEL and not relaxed and len(release) != 3: fail("Semantic version strings must have exactly three dot-separated components, got: " + v) return ( diff --git a/internal/go_repository.bzl b/internal/go_repository.bzl index dd5b87771..627a1f9e3 100644 --- a/internal/go_repository.bzl +++ b/internal/go_repository.bzl @@ -133,7 +133,9 @@ def _go_repository_impl(ctx): if generate: gazelle_path = ctx.path(Label(_gazelle)) - if ctx.attr.urls: + if ctx.attr.local_path: + pass + elif ctx.attr.urls: # HTTP mode for key in ("commit", "tag", "vcs", "remote", "version", "sum", "replace"): if getattr(ctx.attr, key): @@ -178,7 +180,7 @@ def _go_repository_impl(ctx): for key in ("urls", "strip_prefix", "type", "sha256", "commit", "tag", "vcs", "remote"): if getattr(ctx.attr, key): fail("cannot specify both version and %s" % key) - if not ctx.attr.sum: + if ctx.attr.version and not ctx.attr.sum: fail("if version is specified, sum must also be") fetch_path = ctx.attr.replace if ctx.attr.replace else ctx.attr.importpath @@ -250,6 +252,32 @@ def _go_repository_impl(ctx): env.update({k: ctx.os.environ[k] for k in env_keys if k in ctx.os.environ}) + if ctx.attr.local_path: + local_path_env = dict(env) + local_path_env["GOSUMDB"] = "off" + + # Override external GO111MODULE, because it is needed by module mode, no-op in repository mode + local_path_env["GO111MODULE"] = "on" + + if hasattr(ctx, "watch_tree"): + # https://github.com/bazelbuild/bazel/commit/fffa0affebbacf1961a97ef7cd248be64487d480 + ctx.watch_tree(ctx.attr.local_path) + else: + print(""" + WARNING: go.mod replace directives to module paths is only supported in bazel 7.1.0-rc1 or later, + Because of this changes to %s will not be detected by your version of Bazel.""" % ctx.attr.local_path) + + command = [fetch_repo, "--path", ctx.attr.local_path, "--dest", ctx.path("")] + result = env_execute( + ctx, + command, + environment = local_path_env, + timeout = _GO_REPOSITORY_TIMEOUT, + ) + + if result.return_code: + fail(command) + if fetch_repo_args: # Disable sumdb in fetch_repo. In module mode, the sum is a mandatory # attribute of go_repository, so we don't need to look it up. @@ -266,9 +294,7 @@ def _go_repository_impl(ctx): timeout = _GO_REPOSITORY_TIMEOUT, ) if result.return_code: - fail("failed to fetch %s: %s" % (ctx.name, result.stderr)) - if ctx.attr.debug_mode and result.stderr: - print("fetch_repo: " + result.stderr) + fail("%s: %s" % (ctx.name, result.stderr)) # Repositories are fetched. Determine if build file generation is needed. build_file_names = ctx.attr.build_file_name.split(",") @@ -320,7 +346,7 @@ def _go_repository_impl(ctx): "-repo_config", repo_config, ] - if ctx.attr.version: + if ctx.attr.version or ctx.attr.local_path: cmd.append("-go_repository_module_mode") if ctx.attr.build_file_name: cmd.extend(["-build_file_name", ctx.attr.build_file_name]) @@ -434,6 +460,11 @@ go_repository = repository_rule( doc = _AUTH_PATTERN_DOC, ), + # Attributes for a module that should be loaded from the local file system. + "local_path": attr.string( + doc = """ If specified, `go_repository` will load the module from this local directory""", + ), + # Attributes for a module that should be downloaded with the Go toolchain. "version": attr.string( doc = """If specified, `go_repository` will download the module at this version diff --git a/internal/go_repository_tools_srcs.bzl b/internal/go_repository_tools_srcs.bzl index 218f380c4..0a2c4033d 100644 --- a/internal/go_repository_tools_srcs.bzl +++ b/internal/go_repository_tools_srcs.bzl @@ -12,6 +12,7 @@ GO_REPOSITORY_TOOLS_SRCS = [ Label("//cmd/fetch_repo:fetch_repo.go"), Label("//cmd/fetch_repo:go_mod_download.go"), Label("//cmd/fetch_repo:module.go"), + Label("//cmd/fetch_repo:path.go"), Label("//cmd/fetch_repo:vcs.go"), Label("//cmd/gazelle:BUILD.bazel"), Label("//cmd/gazelle:diff.go"), diff --git a/repository.md b/repository.md index b5c2eb926..5fa4f192d 100644 --- a/repository.md +++ b/repository.md @@ -102,9 +102,9 @@ git_repository(
 go_repository(name, auth_patterns, build_config, build_directives, build_external, build_extra_args,
               build_file_generation, build_file_name, build_file_proto_mode, build_naming_convention,
-              build_tags, canonical_id, commit, debug_mode, importpath, patch_args, patch_cmds,
-              patch_tool, patches, remote, replace, repo_mapping, sha256, strip_prefix, sum, tag,
-              type, urls, vcs, version)
+              build_tags, canonical_id, commit, debug_mode, importpath, local_path, patch_args,
+              patch_cmds, patch_tool, patches, remote, replace, repo_mapping, sha256, strip_prefix,
+              sum, tag, type, urls, vcs, version)
 
`go_repository` downloads a Go project and generates build files with Gazelle @@ -187,6 +187,7 @@ go_repository( | commit | If the repository is downloaded using a version control tool, this is the commit or revision to check out. With git, this would be a sha1 commit id. `commit` and `tag` may not both be set. | String | optional | `""` | | debug_mode | Enables logging of fetch_repo and Gazelle output during succcesful runs. Gazelle can be noisy so this defaults to `False`. However, setting to `True` can be useful for debugging build failures and unexpected behavior for the given rule. | Boolean | optional | `False` | | importpath | The Go import path that matches the root directory of this repository.

In module mode (when `version` is set), this must be the module path. If neither `urls` nor `remote` is specified, `go_repository` will automatically find the true path of the module, applying import path redirection.

If build files are generated for this repository, libraries will have their `importpath` attributes prefixed with this `importpath` string. | String | required | | +| local_path | If specified, `go_repository` will load the module from this local directory | String | optional | `""` | | patch_args | Arguments passed to the patch tool when applying patches. | List of strings | optional | `["-p0"]` | | patch_cmds | Commands to run in the repository after patches are applied. | List of strings | optional | `[]` | | patch_tool | The patch tool used to apply `patches`. If this is specified, Bazel will use the specifed patch tool instead of the Bazel-native patch implementation. | String | optional | `""` | diff --git a/tests/bcr/go_mod/MODULE.bazel b/tests/bcr/go_mod/MODULE.bazel index 90572eb69..858a52782 100644 --- a/tests/bcr/go_mod/MODULE.bazel +++ b/tests/bcr/go_mod/MODULE.bazel @@ -138,6 +138,7 @@ use_repo( # "in_gopkg_yaml_v3", # Only used for testing. "bazel_gazelle_go_repository_config", + "org_example_hello", ) # Use an isolated usage to bring in Go tools from the tools package with their own dependency diff --git a/tests/bcr/go_mod/go.mod b/tests/bcr/go_mod/go.mod index 9becf5d60..030865263 100644 --- a/tests/bcr/go_mod/go.mod +++ b/tests/bcr/go_mod/go.mod @@ -1,25 +1,35 @@ // This will stop go mod from descending into this directory. module github.com/bazelbuild/bazel-gazelle/tests/bcr/go_mod -go 1.19 +go 1.21.5 // Validate go.mod replace directives can be properly used: replace github.com/bmatcuk/doublestar/v4 => github.com/bmatcuk/doublestar v1.3.4 require ( + example.org/hello v1.0.0 github.com/DataDog/sketches-go v1.4.1 + github.com/bazelbuild/buildtools v0.0.0-20230317132445-9c3c1fc0106e github.com/bazelbuild/rules_go v0.39.1 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/cloudflare/circl v1.3.7 github.com/envoyproxy/protoc-gen-validate v1.0.1 github.com/fmeum/dep_on_gazelle v1.0.0 github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 + github.com/stretchr/testify v1.6.1 golang.org/x/sys v0.15.0 - google.golang.org/protobuf v1.32.0 ) require ( github.com/bazelbuild/bazel-gazelle v0.30.0 // indirect + github.com/davecgh/go-spew v1.1.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 // indirect ) + +replace example.org/hello => ../../fixtures/hello diff --git a/tests/bcr/go_mod/go.sum b/tests/bcr/go_mod/go.sum index ee03e8091..9e6056a54 100644 --- a/tests/bcr/go_mod/go.sum +++ b/tests/bcr/go_mod/go.sum @@ -1,27 +1,54 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/sketches-go v1.4.1 h1:j5G6as+9FASM2qC36lvpvQAj9qsv/jUs3FtO8CwZNAY= github.com/DataDog/sketches-go v1.4.1/go.mod h1:xJIXldczJyyjnbDop7ZZcLxJdV3+7Kra7H1KMgpgkLk= github.com/bazelbuild/bazel-gazelle v0.30.0 h1:q9XLWQSCA5NZPJ98WFqicHkq6fxrDPnfvMO1XycQBMg= github.com/bazelbuild/bazel-gazelle v0.30.0/go.mod h1:6RxhjM1v/lTpD3JlMpKUCcdus4tvdqsqdfbjYi+czYs= +github.com/bazelbuild/buildtools v0.0.0-20230317132445-9c3c1fc0106e h1:XmPu4mXICgdGnC5dXGjUGbwUD/kUmS0l5Aop3LaevBM= +github.com/bazelbuild/buildtools v0.0.0-20230317132445-9c3c1fc0106e/go.mod h1:689QdV3hBP7Vo9dJMmzhoYIyo/9iMhEmHkJcnaPRCbo= github.com/bazelbuild/rules_go v0.39.1 h1:wkJLUDx59dntWMghuL8++GteoU1To6sRoKJXuyFtmf8= github.com/bazelbuild/rules_go v0.39.1/go.mod h1:TMHmtfpvyfsxaqfL9WnahCsXMWDMICTw7XeK9yVb+YU= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ= github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/fmeum/dep_on_gazelle v1.0.0 h1:7gEtQ2CoD77tYca+1iUnKjIBUZ4mX7mZwjdWp3uuN/E= github.com/fmeum/dep_on_gazelle v1.0.0/go.mod h1:VYCjwfsyRHOJL8oenaEjhIzgM7Oj70iTxgJ2RfXbYr0= +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/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= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +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 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= 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/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 h1:SJ+NtwL6QaZ21U+IrK7d0gGgpjGGvd2kz+FzTHVzdqI= @@ -29,26 +56,73 @@ github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2/go.mod h1:Tv1PlzqC github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= -github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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/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/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/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/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-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +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/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= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b h1:QRR6H1YWRnHb4Y/HeNFCTJLFVxaq6wH4YuVdsUOr75U= +gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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= +rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tests/bcr/go_mod/pkg/BUILD.bazel b/tests/bcr/go_mod/pkg/BUILD.bazel index 7d6c40305..ab8a846cd 100644 --- a/tests/bcr/go_mod/pkg/BUILD.bazel +++ b/tests/bcr/go_mod/pkg/BUILD.bazel @@ -61,5 +61,6 @@ go_test( "@com_github_google_safetext//yamltemplate", "@com_github_stretchr_testify//require:go_default_library", "@my_rules_go//go/runfiles", + "@org_example_hello//:hello", ], ) diff --git a/tests/bcr/go_mod/pkg/pkg_test.go b/tests/bcr/go_mod/pkg/pkg_test.go index bc93a2f90..05d873a84 100644 --- a/tests/bcr/go_mod/pkg/pkg_test.go +++ b/tests/bcr/go_mod/pkg/pkg_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "example.org/hello" "github.com/DataDog/sketches-go/ddsketch" "github.com/bazelbuild/bazel-gazelle/tests/bcr/go_mod/pkg/data" "github.com/bazelbuild/buildtools/labels" @@ -77,3 +78,9 @@ func TestArchiveOverrideUsed(t *testing.T) { func TestArchiveOverrideWithPatch(t *testing.T) { require.Equal(t, labels.Patched, "hello") } + +func TestGodModReplaceToFilePath(t *testing.T) { + // This test is used to validate that the go.mod replace directive is being used to replace + // the module path with a file path. + require.Equal(t, "Hello, world.", hello.Hello()) +} diff --git a/tests/bcr/go_work/MODULE.bazel b/tests/bcr/go_work/MODULE.bazel index b13d9b399..0e4220acb 100644 --- a/tests/bcr/go_work/MODULE.bazel +++ b/tests/bcr/go_work/MODULE.bazel @@ -137,6 +137,7 @@ use_repo( "org_golang_x_sys", # Only used for testing. "bazel_gazelle_go_repository_config", + "org_example_hello", ) # Use an isolated usage to bring in Go tools from the tools package with their own dependency diff --git a/tests/bcr/go_work/go.work b/tests/bcr/go_work/go.work index c4a80cf5b..effa2ce4b 100644 --- a/tests/bcr/go_work/go.work +++ b/tests/bcr/go_work/go.work @@ -1,7 +1,9 @@ -go 1.21.5 +go 1.21 use ( - ./pkg - ./tools - ./proto + ./pkg + ./tools + ./proto ) + +replace example.org/hello => ../../fixtures/hello diff --git a/tests/bcr/go_work/pkg/BUILD.bazel b/tests/bcr/go_work/pkg/BUILD.bazel index 1e75d93df..21333bf5b 100644 --- a/tests/bcr/go_work/pkg/BUILD.bazel +++ b/tests/bcr/go_work/pkg/BUILD.bazel @@ -61,5 +61,6 @@ go_test( "@com_github_google_safetext//yamltemplate", "@com_github_stretchr_testify//require:go_default_library", "@my_rules_go//go/runfiles", + "@org_example_hello//:hello", ], ) diff --git a/tests/bcr/go_work/pkg/go.mod b/tests/bcr/go_work/pkg/go.mod index 202fdd260..2222e404d 100644 --- a/tests/bcr/go_work/pkg/go.mod +++ b/tests/bcr/go_work/pkg/go.mod @@ -3,6 +3,7 @@ module github.com/bazelbuild/bazel-gazelle/tests/bcr/go_work/pkg go 1.21.5 require ( + example.org/hello v0.0.0-00010101000000-000000000000 github.com/DataDog/sketches-go v1.4.4 github.com/bazelbuild/buildtools v0.0.0-20240207142252-03bf520394af github.com/bazelbuild/rules_go v0.44.0 @@ -21,8 +22,11 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/pborman/uuid v1.2.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/protobuf v1.32.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/quote v1.5.2 // indirect + rsc.io/sampler v1.3.0 // indirect ) // Validate go.mod replace directives can be properly used: diff --git a/tests/bcr/go_work/pkg/go.sum b/tests/bcr/go_work/pkg/go.sum index d3b2c1dc6..c5d9f6e1b 100644 --- a/tests/bcr/go_work/pkg/go.sum +++ b/tests/bcr/go_work/pkg/go.sum @@ -6,8 +6,8 @@ github.com/bazelbuild/bazel-gazelle v0.30.0 h1:q9XLWQSCA5NZPJ98WFqicHkq6fxrDPnfv github.com/bazelbuild/bazel-gazelle v0.30.0/go.mod h1:6RxhjM1v/lTpD3JlMpKUCcdus4tvdqsqdfbjYi+czYs= github.com/bazelbuild/buildtools v0.0.0-20240207142252-03bf520394af h1:wycIfuqZJzkloRT+fcazTM3NjvAMyAi1qC2QXmEZP4s= github.com/bazelbuild/buildtools v0.0.0-20240207142252-03bf520394af/go.mod h1:689QdV3hBP7Vo9dJMmzhoYIyo/9iMhEmHkJcnaPRCbo= -github.com/bazelbuild/rules_go v0.45.1 h1:kuiC/mK1SKoZ0lyX5gD9uVBGFWOoXT3I4W/ose6Jouo= -github.com/bazelbuild/rules_go v0.45.1/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= +github.com/bazelbuild/rules_go v0.44.0 h1:uJStI9o5obVWSwquy9WxKNWfZxf2sKA2rpEsX6x5RVM= +github.com/bazelbuild/rules_go v0.44.0/go.mod h1:z7Y8GZ90V4mwgYizbNbEQKmOmx93Q3Btcel4vX7pXoc= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -82,7 +82,10 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 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= @@ -117,3 +120,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 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= +rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tests/bcr/go_work/pkg/pkg_test.go b/tests/bcr/go_work/pkg/pkg_test.go index 85227abd6..e81dcc076 100644 --- a/tests/bcr/go_work/pkg/pkg_test.go +++ b/tests/bcr/go_work/pkg/pkg_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "example.org/hello" "github.com/DataDog/sketches-go/ddsketch" "github.com/bazelbuild/bazel-gazelle/tests/bcr/go_work/pkg/data" "github.com/bazelbuild/buildtools/labels" @@ -77,3 +78,9 @@ func TestArchiveOverrideUsed(t *testing.T) { func TestArchiveOverrideWithPatch(t *testing.T) { require.Equal(t, labels.Patched, "hello") } + +func TestGodModReplaceToFilePath(t *testing.T) { + // This test is used to validate that the go.mod replace directive is being used to replace + // the module path with a file path. + require.Equal(t, "Hello, world.", hello.Hello()) +} diff --git a/tests/bzlmod/go_mod_test.bzl b/tests/bzlmod/go_mod_test.bzl index e1abba0f9..93db2b1b1 100644 --- a/tests/bzlmod/go_mod_test.bzl +++ b/tests/bzlmod/go_mod_test.bzl @@ -14,6 +14,7 @@ github.com/bmatcuk/doublestar/v4 v4.0.2 // indirect replace github.com/go-fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.4.2 replace github.com/bmatcuk/doublestar/v4 v4.0.2 => github.com/bmatcuk/doublestar/v4 v4.0.3 +replace example.org/hello => ../fixtures/hello module github.com/bazelbuild/bazel-gazelle @@ -30,8 +31,9 @@ _EXPECTED_GO_MOD_PARSE_RESULT = struct( go = (1, 18), module = "github.com/bazelbuild/bazel-gazelle", replace_map = { - "github.com/go-fsnotify/fsnotify": struct(from_version = None, to_path = "github.com/fsnotify/fsnotify", version = "1.4.2"), - "github.com/bmatcuk/doublestar/v4": struct(from_version = "4.0.2", to_path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + "github.com/go-fsnotify/fsnotify": struct(file_path = None, from_version = None, to_path = "github.com/fsnotify/fsnotify", version = "1.4.2"), + "github.com/bmatcuk/doublestar/v4": struct(file_path = None, from_version = "4.0.2", to_path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + "example.org/hello": struct(file_path = "../fixtures/hello", from_version = None, to_path = "example.org/hello", version = "{"), }, require = ( struct(indirect = False, path = "github.com/bazelbuild/buildtools", version = "v0.0.0-20220531122519-a43aed7014c8"), @@ -111,6 +113,7 @@ use ( replace github.com/go-fsnotify/fsnotify => github.com/fsnotify/fsnotify v1.4.2 replace github.com/bmatcuk/doublestar/v4 v4.0.2 => github.com/bmatcuk/doublestar/v4 v4.0.3 +replace example.org/hello => ../fixtures/hello """ _EXPECTED_GO_WORK_PARSE_RESULT = struct( @@ -121,12 +124,14 @@ _EXPECTED_GO_WORK_PARSE_RESULT = struct( struct(_is_dev_dependency = False, go_mod = Label("//bar/baz/go_mod_three:go.mod")), ], module_tags = [ - struct(indirect = False, _parent_label = Label("//:go.work"), path = "github.com/fsnotify/fsnotify", version = "1.4.2"), - struct(indirect = False, _parent_label = Label("//:go.work"), path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + struct(indirect = False, _parent_label = Label("//:go.work"), file_path = None, path = "github.com/fsnotify/fsnotify", version = "1.4.2"), + struct(indirect = False, _parent_label = Label("//:go.work"), file_path = None, path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + struct(indirect = False, _parent_label = Label("//:go.work"), file_path = "../fixtures/hello", path = "example.org/hello", version = "{"), ], replace_map = { - "github.com/go-fsnotify/fsnotify": struct(from_version = None, to_path = "github.com/fsnotify/fsnotify", version = "1.4.2"), - "github.com/bmatcuk/doublestar/v4": struct(from_version = "4.0.2", to_path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + "github.com/go-fsnotify/fsnotify": struct(file_path = None, from_version = None, to_path = "github.com/fsnotify/fsnotify", version = "1.4.2"), + "github.com/bmatcuk/doublestar/v4": struct(file_path = None, from_version = "4.0.2", to_path = "github.com/bmatcuk/doublestar/v4", version = "4.0.3"), + "example.org/hello": struct(file_path = "../fixtures/hello", from_version = None, to_path = "example.org/hello", version = "{"), }, use = [ "./go_mod_one", diff --git a/tests/fixtures/hello/go.mod b/tests/fixtures/hello/go.mod new file mode 100644 index 000000000..cecdf0530 --- /dev/null +++ b/tests/fixtures/hello/go.mod @@ -0,0 +1,10 @@ +module example.com/hello + +go 1.21 + +require rsc.io/quote v1.5.2 + +require ( + golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect + rsc.io/sampler v1.3.0 // indirect +) diff --git a/tests/fixtures/hello/go.sum b/tests/fixtures/hello/go.sum new file mode 100644 index 000000000..4a8bcd704 --- /dev/null +++ b/tests/fixtures/hello/go.sum @@ -0,0 +1,6 @@ +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tests/fixtures/hello/hello.go b/tests/fixtures/hello/hello.go new file mode 100644 index 000000000..83891ff60 --- /dev/null +++ b/tests/fixtures/hello/hello.go @@ -0,0 +1,7 @@ +package hello + +import "rsc.io/quote" + +func Hello() string { + return quote.Hello() +} diff --git a/tests/fixtures/hello/hello_test.go b/tests/fixtures/hello/hello_test.go new file mode 100644 index 000000000..b01b58f6e --- /dev/null +++ b/tests/fixtures/hello/hello_test.go @@ -0,0 +1,10 @@ +package hello + +import "testing" + +func TestHello(t *testing.T) { + want := "Hello, world." + if got := Hello(); got != want { + t.Errorf("Hello() = %q, want %q", got, want) + } +}