From 847cae43e792549e91b046696d96ead4f3016d53 Mon Sep 17 00:00:00 2001 From: stefanpenner Date: Tue, 20 Feb 2024 12:09:53 -0700 Subject: [PATCH] [Feature] bzlmod & go.work * adds go_deps.from_file(go_work = "//:go.work") * adds ability to op-out of version conflict failures go_deps.from_file(go_work = "//:go.work, fail_on_version_conflict = False) * parses go.work files to discover used go modules and replace statements * generates repos for all deps specified in go.mod's referenced by the //:go.work * handle replace statements (both at the go.work and the go.mod level) * Errors with actionable error message if duplicate dependencies with differing versions arise (Question: can we do better?) Caveats: * allows for dependency bleed between different go modules in the workspace - this is sorta by design for this stepping stone, but is ideal * doesn't support replace statements in go.work yet (but that shouldn't be to hard to add in a follow up) --- .bazelci/presubmit.yml | 1 + .bazelversion | 1 + MODULE.bazel | 1 - internal/bzlmod/go_deps.bzl | 140 ++++++++++++++++++++-- internal/bzlmod/go_mod.bzl | 199 +++++++++++++++++++++++++------- internal/bzlmod/semver.bzl | 25 ++++ repository.md | 8 +- tests/BUILD.bazel | 1 - tests/bcr/MODULE.bazel | 11 +- tests/bcr/go.mod | 24 +--- tests/bcr/go.work | 6 + tests/bcr/go.work.sum | 0 tests/bcr/pkg/go.mod | 29 +++++ tests/bcr/pkg/go.sum | 119 +++++++++++++++++++ tests/bcr/test_dep/MODULE.bazel | 3 +- tests/bcr/test_dep/go.mod | 11 ++ tests/bcr/test_dep/go.sum | 10 ++ tests/bcr/tools/go.mod | 6 +- tests/bcr/tools/go.sum | 12 +- tests/bzlmod/go_deps_test.bzl | 9 ++ tests/bzlmod/go_mod_test.bzl | 56 ++++++++- tests/bzlmod/semver_test.bzl | 17 ++- tests/bzlmod/utils_test.bzl | 2 +- 23 files changed, 592 insertions(+), 99 deletions(-) create mode 100644 .bazelversion create mode 100644 tests/bcr/go.work create mode 100644 tests/bcr/go.work.sum create mode 100644 tests/bcr/pkg/go.mod create mode 100644 tests/bcr/pkg/go.sum create mode 100644 tests/bcr/test_dep/go.mod create mode 100644 tests/bcr/test_dep/go.sum create mode 100644 tests/bzlmod/go_deps_test.bzl diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index 97f66c112..dfaedb31d 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -41,6 +41,7 @@ tasks: # Regenerate the BUILD files for the test module using Gazelle. # Also verify -repo_config are generated correctly in gazelle.bash - rm pkg/BUILD.bazel proto/BUILD.bazel + - touch pkg/BUILD.bazel proto/BUILD.bazel # ensure empty pkg/BUILD.bazel exists - bazel run //:gazelle -- update pkg proto - bazel run //:gazelle -- pkg proto build_targets: diff --git a/.bazelversion b/.bazelversion new file mode 100644 index 000000000..19b860c18 --- /dev/null +++ b/.bazelversion @@ -0,0 +1 @@ +6.4.0 diff --git a/MODULE.bazel b/MODULE.bazel index 6207d1ccc..4ed18fe1f 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -56,7 +56,6 @@ use_repo( bazel_dep(name = "bazel_skylib_gazelle_plugin", version = "1.4.1", dev_dependency = True) bazel_dep(name = "stardoc", version = "0.6.2", dev_dependency = True, repo_name = "io_bazel_stardoc") - go_sdk_dev = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk", dev_dependency = True) # Known to exist since it is instantiated by rules_go itself. diff --git a/internal/bzlmod/go_deps.bzl b/internal/bzlmod/go_deps.bzl index f741291d1..24d5ddc2f 100644 --- a/internal/bzlmod/go_deps.bzl +++ b/internal/bzlmod/go_deps.bzl @@ -13,14 +13,14 @@ # limitations under the License. load("//internal:go_repository.bzl", "go_repository") -load(":go_mod.bzl", "deps_from_go_mod", "sums_from_go_mod") +load(":go_mod.bzl", "deps_from_go_mod", "parse_go_work", "sums_from_go_mod", "sums_from_go_work") load( ":default_gazelle_overrides.bzl", "DEFAULT_BUILD_EXTRA_ARGS_BY_PATH", "DEFAULT_BUILD_FILE_GENERATION_BY_PATH", "DEFAULT_DIRECTIVES_BY_PATH", ) -load(":semver.bzl", "semver") +load(":semver.bzl", "humanize_comparable_version", "semver") load( ":utils.bzl", "drop_nones", @@ -82,6 +82,12 @@ _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 @@ -271,6 +277,78 @@ _go_repository_config = repository_rule( }, ) +def fail_on_version_conflict(version, previous, module_tag, module_name_to_go_dot_mod_label, go_works, fail_or_warn): + """ + Check if duplicate modules have different versions, and fail with a useful error message if they do. + + Args: + version: The version of the module. + previous: The previous module object. + module_tag: The module tag. + module_name_to_go_dot_mod_label: A dictionary mapping module paths to go.mod labels. + go_works: A list of go_work objects representing use statements in the go.work file. + previous: The previous module object. + """ + + if not previous: + # no previous module, so no possible error + return + + if not previous or version == previous.version: + # version is the same, skip because we won't error + 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 + + previous_label = previous.module_tag.parent_label + + corrective_measure = None + default_corrective_mesasure = "To correct this:\n 1. manually update: all go.mod files to ensure the versions of '{}' are the same.\n 2. in the folder where you made changes to run: go mod tidy\n 3. run: go work sync.".format(module_tag.path) + + if previous.version[0] == version[0] or str(current_label).endswith("go.work") or str(previous_label).endswith("go.work"): + corrective_measure = default_corrective_mesasure + else: + label = module_name_to_go_dot_mod_label.get(module_tag.path) + + print(dir(previous.module_tag)) + if label: + # if the label is present that means the module_tag is of a go.mod file, which means the correct action may be different. + + # if the duplicate module in question is provided by go.work use statement then only manual intervention can fix it + # from_file_tags on go_work represents use statements in the go.work file + for from_file_tags in [go_work.from_file_tags for go_work in go_works]: + for from_file_tag in from_file_tags: + if from_file_tag.go_mod == label: + corrective_measure = default_corrective_mesasure + break + elif previous.module_tag.indirect or module_tag.indirect: + # if the dependency indirect, the user will need to manually update go.mod, run go mod tidy in that directory and then run go work sync + corrective_measure = default_corrective_mesasure + else: + # TODO: if the version are v0.8.0 and v0.17.0 go work sync wont work + # ensure the corrective measure describes this. Maybe this is limited to indirect dependencies + corrective_measure = "To correct this, run:\n 1. go work sync." + + message = "Multiple versions of {} found:\n - {} contains: {}\n - {} contains {}.\n{}".format(module_tag.path, current_label, humanize_comparable_version(version), previous_label, humanize_comparable_version(previous.version), corrective_measure) + + if fail_or_warn: + fail(message) + else: + print(message) + +def _fail_if_not_root(module, from_file_tag): + if module.is_root != True: + fail("go_deps.from_file(go_work = '{}') tag can only be used from a root module but: '{}' is not a root module.".format(from_file_tag.go_work, module.name)) + +def _fail_if_invalid_from_file_usage(from_file_tag): + if ( + (from_file_tag.go_work == None and from_file_tag.go_mod == None) and + (from_file_tag.go_work != None and from_file_tag.go_mod != None) + ): + fail("go_deps.from_file tag must have either go_work or go_mod attribute, but not both.") + def _noop(_): pass @@ -329,9 +407,40 @@ def _go_deps_impl(module_ctx): ", ".join([str(tag.go_mod) for tag in module.tags.from_file]), ), ) + additional_module_tags = [] + from_file_tags = [] + go_works = [] + module_name_to_go_dot_mod_label = {} + for from_file_tag in module.tags.from_file: - module_path, module_tags_from_go_mod, go_mod_replace_map = deps_from_go_mod(module_ctx, from_file_tag.go_mod) + _fail_if_invalid_from_file_usage(from_file_tag) + + if from_file_tag.go_mod: + from_file_tags.append(from_file_tag) + elif from_file_tag.go_work: + _fail_if_not_root(module, from_file_tag) + + go_work = go_work_from_label(module_ctx, from_file_tag.go_work) + go_works.append(go_work) + + # this ensures go.work replacements as considered + additional_module_tags += [ + with_replaced_or_new_fields(tag, _is_dev_dependency = False) + for tag in go_work.module_tags + ] + + for entry, new_sum in sums_from_go_work(module_ctx, from_file_tag.go_work).items(): + _safe_insert_sum(sums, entry, new_sum) + + replace_map.update(go_work.replace_map) + from_file_tags = from_file_tags + go_work.from_file_tags + else: + fail("Either \"go_mod\" or \"go_work\" must be specified in \"go_deps.from_file\" tags.") + + for from_file_tag in from_file_tags: + module_path, module_tags_from_go_mod, go_mod_replace_map, module_name = deps_from_go_mod(module_ctx, from_file_tag.go_mod) + module_name_to_go_dot_mod_label[module_name] = from_file_tag.go_mod is_dev_dependency = _is_dev_dependency(module_ctx, from_file_tag) additional_module_tags += [ with_replaced_or_new_fields(tag, _is_dev_dependency = is_dev_dependency) @@ -382,12 +491,12 @@ def _go_deps_impl(module_ctx): # transitive dependencies have also been declared - we may end up # resolving them to higher versions, but only compatible ones. paths = {} + for module_tag in module.tags.module + additional_module_tags: - if module_tag.path in paths: - fail("Duplicate Go module path \"{}\" in module \"{}\".".format(module_tag.path, module.name)) + if not module_tag.path in paths: + paths[module_tag.path] = None if module_tag.path in bazel_deps: continue - paths[module_tag.path] = None raw_version = _canonicalize_raw_version(module_tag.version) # For modules imported from a go.sum, we know which ones are direct @@ -403,6 +512,14 @@ def _go_deps_impl(module_ctx): root_module_direct_deps[_repo_name(module_tag.path)] = None version = semver.to_comparable(raw_version) + previous = paths.get(module_tag.path) + + fail_or_warn = len([x for x in module.tags.from_file if x.fail_on_version_conflict == True]) > 0 + + # rather then failing, we could do MVS here, or some other heuristic + fail_on_version_conflict(version, previous, module_tag, module_name_to_go_dot_mod_label, go_works, fail_or_warn) + 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: module_resolutions[module_tag.path] = struct( repo_name = _repo_name(module_tag.path), @@ -553,13 +670,14 @@ def _get_sum_from_module(path, module, sums): entry = (module.replace, module.raw_version) if entry not in sums: + # TODO: if no sum exist, this is probably because a go mod tidy was missed fail("No sum for {}@{} found".format(path, module.raw_version)) return sums[entry] def _safe_insert_sum(sums, entry, new_sum): if entry in sums and new_sum != sums[entry]: - fail("Multiple mismatching sums for {}@{} found.".format(entry[0], entry[1])) + fail("Multiple mismatching sums for {}@{} found. {} vs {}".format(entry[0], entry[1], new_sum, sums[entry])) sums[entry] = new_sum def _canonicalize_raw_version(raw_version): @@ -577,7 +695,9 @@ _config_tag = tag_class( _from_file_tag = tag_class( attrs = { - "go_mod": attr.label(mandatory = True), + "go_mod": attr.label(mandatory = False), + "go_work": attr.label(mandatory = False), + "fail_on_version_conflict": attr.bool(default = True), }, ) @@ -592,6 +712,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 = ""), + "parent_label": attr.label( + doc = """The label of the go.mod or go.work file that this module was imported from.""", + default = Label("//:MODULE.bazel"), + ), }, ) diff --git a/internal/bzlmod/go_mod.bzl b/internal/bzlmod/go_mod.bzl index 59e134670..024bf170b 100644 --- a/internal/bzlmod/go_mod.bzl +++ b/internal/bzlmod/go_mod.bzl @@ -16,6 +16,94 @@ visibility([ "//tests/bzlmod/...", ]) +def _validate_go_version(path, state, tokens, line_no): + if len(tokens) == 1: + fail("{}:{}: expected another token after 'go'".format(path, line_no)) + if state["go"] != None: + fail("{}:{}: unexpected second 'go' directive".format(path, line_no)) + if len(tokens) > 2: + fail("{}:{}: unexpected token '{}' after '{}'".format(path, line_no, tokens[2], tokens[1])) + +def use_spec_to_label(workspace_name, use_directive): + if use_directive.find("..") >= 0: + fail("go.work use directive: '{}' contains '..' which is not currently supported.".format(use_directive)) + + if use_directive.startswith("./"): + use_directive = use_directive[2:] + + if use_directive.startswith("."): + use_directive = use_directive[1:] + + if use_directive.endswith("/"): + use_directive = use_directive[:-1] + + return Label("@@{}//{}:go.mod".format(workspace_name, use_directive)) + +def parse_go_work(content, go_work_label): + # see: https://go.dev/ref/mod#go-work-file + + # Valid directive values understood by this parser never contain tabs or + # carriage returns, so we can simplify the parsing below by canonicalizing + # whitespace upfront. + content = content.replace("\t", " ").replace("\r", " ") + + state = { + "go": None, + "use": [], + "replace": {}, + } + + current_directive = None + for line_no, line in enumerate(content.splitlines(), 1): + tokens, _ = _tokenize_line(line, go_work_label.name, line_no) + + if not tokens: + continue + + if current_directive: + if tokens[0] == ")": + current_directive = None + elif current_directive == "use": + state["use"].append(tokens[0]) + elif current_directive == "replace": + _parse_replace_directive(state, tokens, go_work_label.name, line_no) + else: + fail("{}:{}: unexpected directive '{}'".format(go_work_label.name, line_no, current_directive)) + elif tokens[0] == "go": + _validate_go_version(go_work_label.name, state, tokens, line_no) + go = tokens[1] + elif tokens[0] == "replace": + if tokens[1] == "(": + current_directive = tokens[0] + continue + else: + _parse_replace_directive(state, tokens[1:], go_work_label.name, line_no) + elif tokens[0] == "use": + if len(tokens) != 2: + fail("{}:{}: expected path or block in 'use' directive".format(go_work_label.name, line_no)) + elif tokens[1] == "(": + current_directive = tokens[0] + continue + else: + state["use"].append(tokens[1]) + else: + fail("{}:{}: unexpected directive '{}'".format(go_work_label.name, line_no, tokens[0])) + + major, minor = go.split(".")[:2] + + 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()] + + return struct( + go = (int(major), int(minor)), + from_file_tags = from_file_tags, + replace_map = state["replace"], + module_tags = module_tags, + use = state["use"], + ) + def deps_from_go_mod(module_ctx, go_mod_label): """Loads the entries from a go.mod file. @@ -45,9 +133,10 @@ def deps_from_go_mod(module_ctx, go_mod_label): path = require.path, version = require.version, indirect = require.indirect, + parent_label = go_mod_label, )) - return go_mod.module, deps, go_mod.replace_map + return go_mod.module, deps, go_mod.replace_map, go_mod.module def parse_go_mod(content, path): # See https://go.dev/ref/mod#go-mod-file. @@ -79,13 +168,8 @@ def parse_go_mod(content, path): # The 'go' directive only has a single-line form and is thus parsed # here rather than in _parse_directive. if tokens[0] == "go": - if len(tokens) == 1: - fail("{}:{}: expected another token after 'go'".format(path, line_no)) - if state["go"] != None: - fail("{}:{}: unexpected second 'go' directive".format(path, line_no)) + _validate_go_version(path, state, tokens, line_no) state["go"] = tokens[1] - if len(tokens) > 2: - fail("{}:{}: unexpected token '{}' after '{}'".format(path, line_no, tokens[2], tokens[1])) if tokens[1] == "(": current_directive = tokens[0] @@ -139,37 +223,41 @@ def _parse_directive(state, directive, tokens, comment, path, line_no): indirect = comment == "indirect", )) elif directive == "replace": - # 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] - - # pattern: replace from_path => to_path to_version - if len(tokens) == 4 and tokens[1] == "=>": - state["replace"][from_path] = struct( - from_version = None, - to_path = tokens[2], - version = _canonicalize_raw_version(tokens[3]), - ) - # 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]), - ) - 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'" - ) + _parse_replace_directive(state, tokens, 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] + + # pattern: replace from_path => to_path to_version + if len(tokens) == 4 and tokens[1] == "=>": + state["replace"][from_path] = struct( + from_version = None, + to_path = tokens[2], + version = _canonicalize_raw_version(tokens[3]), + ) + # 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]), + ) + 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'", + ) + def _tokenize_line(line, path, line_no): tokens = [] r = line @@ -240,16 +328,37 @@ def sums_from_go_mod(module_ctx, go_mod_label): """ _check_go_mod_name(go_mod_label.name) - # We go through a Label so that the module extension is restarted if go.sum + return parse_sumfile(module_ctx, go_mod_label, "go.sum") + +def sums_from_go_work(module_ctx, go_work_label): + """Loads the entries from a go.work.sum file given a go.workLabel. + + Args: + module_ctx: a https://bazel.build/rules/lib/module_ctx object + passed from the MODULE.bazel call. + go_work_label: a Label for a `go.work` file. This label is used + to find the associated `go.work.sum` file. + + Returns: + A Dict[(string, string) -> (string)] is retruned where each entry + is defined by a Go Module's sum: + (path, version) -> (sum) + """ + _check_go_work_name(go_work_label.name) + + return parse_sumfile(module_ctx, go_work_label, "go.work.sum") + +def parse_sumfile(module_ctx, label, somefile): + # We go through a Label so that the module extension is restarted if the sumfile # changes. We have to use a canonical label as we may not have visibility - # into the module that provides the go.sum. - go_sum_label = Label("@@{}//{}:{}".format( - go_mod_label.workspace_name, - go_mod_label.package, - "go.sum", + # into the module that provides the sumfile + sum_label = Label("@@{}//{}:{}".format( + label.workspace_name, + label.package, + somefile, )) - go_sum_content = module_ctx.read(go_sum_label) - return parse_go_sum(go_sum_content) + sum_content = module_ctx.read(sum_label) + return parse_go_sum(sum_content) def parse_go_sum(content): hashes = {} @@ -264,6 +373,10 @@ def _check_go_mod_name(name): if name != "go.mod": fail("go_deps.from_file requires a 'go.mod' file, not '{}'".format(name)) +def _check_go_work_name(name): + if name != "go.work": + fail("go_deps.from_file requires a 'go.work' file, not '{}'".format(name)) + def _canonicalize_raw_version(raw_version): if raw_version.startswith("v"): return raw_version[1:] diff --git a/internal/bzlmod/semver.bzl b/internal/bzlmod/semver.bzl index d79a4f4bf..cebd94a2d 100644 --- a/internal/bzlmod/semver.bzl +++ b/internal/bzlmod/semver.bzl @@ -78,3 +78,28 @@ def _semver_to_comparable(v, *, relaxed = False): semver = struct( to_comparable = _semver_to_comparable, ) + +def humanize_comparable_version(version): + """ + Returns a human-readable representation of a comparable version object. + + This is useful for providing more helpful error messages. + + Please note, this is lossy as + meta segments are replaced with sentinal value to preserve expected sorting + + Args: + version: The comparable version object. + + Returns: + A human-readable representation of the version. + """ + core = [_flatten_segment(segment) for segment in version[0]] + meta = [_flatten_segment(segment) for segment in version[1] if segment[0] != "{"] + result = ".".join(core) + + if (len(meta) > 0): + result += "-" + ".".join(meta) + return "v" + result + +def _flatten_segment(segment): + return "".join([str(atom) for atom in segment]) diff --git a/repository.md b/repository.md index ea7ea2175..406c69d4f 100644 --- a/repository.md +++ b/repository.md @@ -91,7 +91,7 @@ git_repository( | commit | The git commit to check out. Either `commit` or `tag` may be specified. | String | optional | `""` | | overlay | A set of files to copy into the downloaded repository. The keys in this dictionary are Bazel labels that point to the files to copy. These must be fully qualified labels (i.e., `@repo//pkg:name`) because relative labels are interpreted in the checked out repository, not the repository containing the WORKSPACE file. The values in this dictionary are root-relative paths where the overlay files should be written.

It's convenient to store the overlay dictionaries for all repositories in a separate .bzl file. See Gazelle's `manifest.bzl`_ for an example. | Dictionary: Label -> String | optional | `{}` | | remote | The remote repository to download. | String | required | | -| repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | Dictionary: String -> String | optional | | +| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`). | Dictionary: String -> String | required | | | tag | The git tag to check out. Either `commit` or `tag` may be specified. | String | optional | `""` | @@ -172,7 +172,7 @@ go_repository( | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this repository. | Name | required | | | auth_patterns | An optional dict mapping host names to custom authorization patterns.

If a URL's host name is present in this dict the value will be used as a pattern when generating the authorization header for the http request. This enables the use of custom authorization schemes used in a lot of common cloud storage providers.

The pattern currently supports 2 tokens: <login> and <password>, which are replaced with their equivalent value in the netrc file for the same host name. After formatting, the result is set as the value for the Authorization field of the HTTP request.

Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token:

 auth_patterns = {     "storage.cloudprovider.com": "Bearer <password>" } 


netrc:

 machine storage.cloudprovider.com         password RANDOM-TOKEN 


The final HTTP request would have the following header:

 Authorization: Bearer RANDOM-TOKEN 
| Dictionary: String -> String | optional | `{}` | -| build_config | A file that Gazelle should read to learn about external repositories before generating build files. This is useful for dependency resolution. For example, a `go_repository` rule in this file establishes a mapping between a repository name like `golang.org/x/tools` and a workspace name like `org_golang_x_tools`. Workspace directives like `# gazelle:repository_macro` are recognized.

`go_repository` rules will be re-evaluated when parts of WORKSPACE related to Gazelle's configuration are changed, including Gazelle directives and `go_repository` `name` and `importpath` attributes. Their content should still be fetched from a local cache, but build files will be regenerated. If this is not desirable, `build_config` may be set to a less frequently updated file or `None` to disable this functionality. | Label | optional | `"@bazel_gazelle_go_repository_config//:WORKSPACE"` | +| build_config | A file that Gazelle should read to learn about external repositories before generating build files. This is useful for dependency resolution. For example, a `go_repository` rule in this file establishes a mapping between a repository name like `golang.org/x/tools` and a workspace name like `org_golang_x_tools`. Workspace directives like `# gazelle:repository_macro` are recognized.

`go_repository` rules will be re-evaluated when parts of WORKSPACE related to Gazelle's configuration are changed, including Gazelle directives and `go_repository` `name` and `importpath` attributes. Their content should still be fetched from a local cache, but build files will be regenerated. If this is not desirable, `build_config` may be set to a less frequently updated file or `None` to disable this functionality. | Label | optional | `@bazel_gazelle_go_repository_config//:WORKSPACE` | | build_directives | A list of directives to be written to the root level build file before Calling Gazelle to generate build files. Each string in the list will be prefixed with `#` automatically. A common use case is to pass a list of Gazelle directives. | List of strings | optional | `[]` | | build_external | One of `"external"`, `"static"` or `"vendored"`.

This sets Gazelle's `-external` command line flag. In `"static"` mode, Gazelle will not call out to the network to resolve imports.

**NOTE:** This cannot be used to ignore the `vendor` directory in a repository. The `-external` flag only controls how Gazelle resolves imports which are not present in the repository. Use `build_extra_args = ["-exclude=vendor"]` instead. | String | optional | `"static"` | | build_extra_args | A list of additional command line arguments to pass to Gazelle when generating build files. | List of strings | optional | `[]` | @@ -191,7 +191,7 @@ go_repository( | patches | A list of patches to apply to the repository after gazelle runs. | List of labels | optional | `[]` | | remote | The VCS location where the repository should be downloaded from. This is usually inferred from `importpath`, but you can set `remote` to download from a private repository or a fork. | String | optional | `""` | | replace | A replacement for the module named by `importpath`. The module named by `replace` will be downloaded at `version` and verified with `sum`.

NOTE: There is no `go_repository` equivalent to file path `replace` directives. Use `local_repository` instead. | String | optional | `""` | -| repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | Dictionary: String -> String | optional | | +| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`). | Dictionary: String -> String | required | | | sha256 | If the repository is downloaded via HTTP (`urls` is set), this is the SHA-256 sum of the downloaded archive. When set, Bazel will verify the archive against this sum before extracting it.

**CAUTION:** Do not use this with services that prepare source archives on demand, such as codeload.github.com. Any minor change in the server software can cause differences in file order, alignment, and compression that break SHA-256 sums. | String | optional | `""` | | strip_prefix | If the repository is downloaded via HTTP (`urls` is set), this is a directory prefix to strip. See [`http_archive.strip_prefix`]. | String | optional | `""` | | sum | A hash of the module contents. In module mode, `go_repository` will verify the downloaded module matches this sum. May only be set when `version` is also set.

A value for `sum` may be found in the `go.sum` file or by running `go mod download -json @`. | String | optional | `""` | @@ -241,7 +241,7 @@ http_archive( | :------------- | :------------- | :------------- | :------------- | :------------- | | name | A unique name for this repository. | Name | required | | | overlay | A set of files to copy into the downloaded repository. The keys in this dictionary are Bazel labels that point to the files to copy. These must be fully qualified labels (i.e., `@repo//pkg:name`) because relative labels are interpreted in the checked out repository, not the repository containing the WORKSPACE file. The values in this dictionary are root-relative paths where the overlay files should be written.

It's convenient to store the overlay dictionaries for all repositories in a separate .bzl file. See Gazelle's `manifest.bzl`_ for an example. | Dictionary: Label -> String | optional | `{}` | -| repo_mapping | In `WORKSPACE` context only: a dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`).

This attribute is _not_ supported in `MODULE.bazel` context (when invoking a repository rule inside a module extension's implementation function). | Dictionary: String -> String | optional | | +| repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.

For example, an entry `"@foo": "@bar"` declares that, for any time this repository depends on `@foo` (such as a dependency on `@foo//some:target`, it should actually resolve that dependency within globally-declared `@bar` (`@bar//some:target`). | Dictionary: String -> String | required | | | sha256 | The SHA-256 sum of the downloaded archive. When set, Bazel will verify the archive against this sum before extracting it.

**CAUTION:** Do not use this with services that prepare source archives on demand, such as codeload.github.com. Any minor change in the server software can cause differences in file order, alignment, and compression that break SHA-256 sums. | String | optional | `""` | | strip_prefix | A directory prefix to strip. See [http_archive.strip_prefix]. | String | optional | `""` | | type | One of `"zip"`, `"tar.gz"`, `"tgz"`, `"tar.bz2"`, `"tar.xz"`.

The file format of the repository archive. This is normally inferred from the downloaded file name. | String | optional | `""` | diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index e2ebfeaf6..17f1aa607 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -3,7 +3,6 @@ load( "gazelle_binary", "gazelle_generation_test", ) - load("//tests:tools.bzl", "get_binary") # Exclude this entire directly from having anything gnerated by Gazelle. That diff --git a/tests/bcr/MODULE.bazel b/tests/bcr/MODULE.bazel index cc0026e03..08ef0d7a1 100644 --- a/tests/bcr/MODULE.bazel +++ b/tests/bcr/MODULE.bazel @@ -15,7 +15,7 @@ local_path_override( ) bazel_dep(name = "protobuf", version = "23.1", repo_name = "my_protobuf") -bazel_dep(name = "rules_go", version = "0.42.0", repo_name = "my_rules_go") +bazel_dep(name = "rules_go", version = "0.44.0", repo_name = "my_rules_go") bazel_dep(name = "rules_proto", version = "6.0.0-rc2", repo_name = "my_rules_proto") # This bazel_dep provides the Go dependency github.com/cloudflare/circl, which requires custom @@ -25,6 +25,8 @@ bazel_dep(name = "circl", version = "1.3.7") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") # Validate a go.mod replace directive works. +# Validate a full go workspace +go_deps.from_file(go_work = "//:go.work") go_deps.from_file(go_mod = "//:go.mod") go_deps.gazelle_default_attributes( build_file_generation = "on", @@ -56,8 +58,8 @@ go_deps.gazelle_override( # respected. go_deps.module( path = "github.com/stretchr/testify", - sum = "h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=", - version = "v1.8.0", + sum = "h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=", + version = "v1.8.4", ) go_deps.gazelle_override( directives = [ @@ -118,6 +120,7 @@ go_deps.module( ) use_repo( go_deps, + "com_github_99designs_gqlgen", "com_github_bazelbuild_buildtools", "com_github_bmatcuk_doublestar_v4", "com_github_datadog_sketches_go", @@ -127,8 +130,6 @@ use_repo( "com_github_stretchr_testify", "org_golang_google_protobuf", "org_golang_x_sys", - # It is not necessary to list transitive dependencies here, only direct ones. - # "in_gopkg_yaml_v3", # Only used for testing. "bazel_gazelle_go_repository_config", ) diff --git a/tests/bcr/go.mod b/tests/bcr/go.mod index d4f1957f5..8f806b156 100644 --- a/tests/bcr/go.mod +++ b/tests/bcr/go.mod @@ -1,25 +1,3 @@ -// This will stop go mod from descending into this directory. module github.com/bazelbuild/bazel-gazelle/tests/bcr -go 1.19 - -// Validate go.mod replace directives can be properly used: -replace github.com/bmatcuk/doublestar/v4 => github.com/bmatcuk/doublestar v1.3.4 - -require ( - github.com/DataDog/sketches-go v1.4.1 - 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 - 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/kr/text v0.2.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect -) +go 1.21.5 diff --git a/tests/bcr/go.work b/tests/bcr/go.work new file mode 100644 index 000000000..66fd10058 --- /dev/null +++ b/tests/bcr/go.work @@ -0,0 +1,6 @@ +go 1.21.5 + +use ( + ./pkg + ./tools +) diff --git a/tests/bcr/go.work.sum b/tests/bcr/go.work.sum new file mode 100644 index 000000000..e69de29bb diff --git a/tests/bcr/pkg/go.mod b/tests/bcr/pkg/go.mod new file mode 100644 index 000000000..671161724 --- /dev/null +++ b/tests/bcr/pkg/go.mod @@ -0,0 +1,29 @@ +module github.com/bazelbuild/bazel-gazelle/tests/bcr/pkg + +go 1.21.5 + +require ( + 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 + github.com/bmatcuk/doublestar/v4 v4.6.1 + github.com/cloudflare/circl v1.3.7 + github.com/envoyproxy/protoc-gen-validate v1.0.4 + github.com/fmeum/dep_on_gazelle v1.0.0 + github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f + github.com/stretchr/testify v1.8.4 + golang.org/x/sys v0.17.0 +) + +require ( + github.com/bazelbuild/bazel-gazelle v0.30.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + 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 + google.golang.org/protobuf v1.32.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +// Validate go.mod replace directives can be properly used: +replace github.com/bmatcuk/doublestar/v4 => github.com/bmatcuk/doublestar v1.3.4 diff --git a/tests/bcr/pkg/go.sum b/tests/bcr/pkg/go.sum new file mode 100644 index 000000000..d3b2c1dc6 --- /dev/null +++ b/tests/bcr/pkg/go.sum @@ -0,0 +1,119 @@ +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.4 h1:dF52vzXRFSPOj2IjXSWLvXq3jubL4CI69kwYjJ1w5Z8= +github.com/DataDog/sketches-go v1.4.4/go.mod h1:XR0ns2RtEEF09mDKXiKZiQg+nfZStrq1ZuL1eezeZe0= +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-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/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= +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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/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.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +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/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-20240104143208-7a7d9b3d812f h1:o2yGZLlsOj5H5uvtQNEdi6DeA0GbUP3lm0gWW5RvY0s= +github.com/google/safetext v0.0.0-20240104143208-7a7d9b3d812f/go.mod h1:H3K1Iu/utuCfa10JO+GsmKUYSWi7ug57Rk6GaDRHaaQ= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= +github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +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/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.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.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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.28.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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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= diff --git a/tests/bcr/test_dep/MODULE.bazel b/tests/bcr/test_dep/MODULE.bazel index c2278edf2..340ade58b 100644 --- a/tests/bcr/test_dep/MODULE.bazel +++ b/tests/bcr/test_dep/MODULE.bazel @@ -28,7 +28,6 @@ go_deps.module_override( ], path = "github.com/stretchr/testify", ) - go_deps.module( indirect = True, path = "gopkg.in/yaml.v3", @@ -36,10 +35,10 @@ go_deps.module( version = "v3.0.1", ) go_deps.gazelle_override( - path = "gopkg.in/yaml.v3", directives = [ "gazelle:go_naming_convention import", ], + path = "gopkg.in/yaml.v3", ) go_deps.module( indirect = True, diff --git a/tests/bcr/test_dep/go.mod b/tests/bcr/test_dep/go.mod new file mode 100644 index 000000000..b990a2ae3 --- /dev/null +++ b/tests/bcr/test_dep/go.mod @@ -0,0 +1,11 @@ +module github.com/bazelbuild/bazel-gazelle/tests/bcr/test_dep + +go 1.21.5 + +require github.com/stretchr/testify v1.8.4 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/tests/bcr/test_dep/go.sum b/tests/bcr/test_dep/go.sum new file mode 100644 index 000000000..fa4b6e682 --- /dev/null +++ b/tests/bcr/test_dep/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tests/bcr/tools/go.mod b/tests/bcr/tools/go.mod index 29249d341..2646af128 100644 --- a/tests/bcr/tools/go.mod +++ b/tests/bcr/tools/go.mod @@ -4,7 +4,7 @@ go 1.21.0 require ( github.com/99designs/gqlgen v0.17.40 - github.com/bazelbuild/buildtools v0.0.0-20231115204819-d4c9dccdfbb1 + github.com/bazelbuild/buildtools v0.0.0-20240207142252-03bf520394af ) require ( @@ -18,9 +18,9 @@ require ( github.com/vektah/gqlparser/v2 v2.5.10 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/sys v0.8.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.9.3 // indirect - google.golang.org/protobuf v1.30.0 // indirect + google.golang.org/protobuf v1.32.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/tests/bcr/tools/go.sum b/tests/bcr/tools/go.sum index 0804de90c..589dc7022 100644 --- a/tests/bcr/tools/go.sum +++ b/tests/bcr/tools/go.sum @@ -8,8 +8,8 @@ github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNg github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= -github.com/bazelbuild/buildtools v0.0.0-20231115204819-d4c9dccdfbb1 h1:2Gc2Q6hVR1SJ8bBI9Ybzoggp8u/ED2WkM4MfvEIn9+c= -github.com/bazelbuild/buildtools v0.0.0-20231115204819-d4c9dccdfbb1/go.mod h1:689QdV3hBP7Vo9dJMmzhoYIyo/9iMhEmHkJcnaPRCbo= +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/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= @@ -90,8 +90,8 @@ golang.org/x/sync v0.2.0/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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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.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= @@ -122,8 +122,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/tests/bzlmod/go_deps_test.bzl b/tests/bzlmod/go_deps_test.bzl new file mode 100644 index 000000000..796d02eb7 --- /dev/null +++ b/tests/bzlmod/go_deps_test.bzl @@ -0,0 +1,9 @@ +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//internal/bzlmod:go_deps.bzl", "fail_on_version_conflict") + +def _go_sum_test_impl(ctx): + env = unittest.begin(ctx) + asserts.equals(env, _EXPECTED_GO_SUM_PARSE_RESULT, parse_go_sum(_GO_SUM_CONTENT)) + return unittest.end(env) + +go_sum_test = unittest.make(_go_sum_test_impl) diff --git a/tests/bzlmod/go_mod_test.bzl b/tests/bzlmod/go_mod_test.bzl index c4287074a..68cfb1105 100644 --- a/tests/bzlmod/go_mod_test.bzl +++ b/tests/bzlmod/go_mod_test.bzl @@ -1,5 +1,5 @@ load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") -load("//internal/bzlmod:go_mod.bzl", "parse_go_mod", "parse_go_sum") +load("//internal/bzlmod:go_mod.bzl", "parse_go_mod", "parse_go_sum", "parse_go_work", "use_spec_to_label") _GO_MOD_CONTENT = """ go 1.18 @@ -64,6 +64,18 @@ _EXPECTED_GO_MOD_21_PARSE_RESULT = struct( require = (), ) +def _use_spec_to_label_test_impl(ctx): + env = unittest.begin(ctx) + + asserts.equals(env, Label("@@org_example//:go.mod"), use_spec_to_label("org_example", ".")) + asserts.equals(env, Label("@@org_example//go_mod_one:go.mod"), use_spec_to_label("org_example", "./go_mod_one")) + asserts.equals(env, Label("@@org_example//go_mod_one:go.mod"), use_spec_to_label("org_example", "./go_mod_one/")) + asserts.equals(env, Label("@@org_example//bar/go_mod_one:go.mod"), use_spec_to_label("org_example", "./bar/go_mod_one")) + + return unittest.end(env) + +use_spec_test = unittest.make(_use_spec_to_label_test_impl) + def _go_mod_21_test_impl(ctx): env = unittest.begin(ctx) asserts.equals(env, _EXPECTED_GO_MOD_21_PARSE_RESULT, parse_go_mod(_GO_MOD_21_CONTENT, "/go.mod")) @@ -91,10 +103,52 @@ def _go_sum_test_impl(ctx): go_sum_test = unittest.make(_go_sum_test_impl) +_GO_WORK_CONTENT = """go 1.18 +use ./go_mod_one +use ( + ./foo/go_mod_two + ./bar/baz/go_mod_three +) + +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 +""" + +_EXPECTED_GO_WORK_PARSE_RESULT = struct( + go = (1, 18), + from_file_tags = [ + struct(_is_dev_dependency = False, go_mod = Label("//go_mod_one:go.mod")), + struct(_is_dev_dependency = False, go_mod = Label("//foo/go_mod_two:go.mod")), + 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"), + ], + 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"), + }, + use = [ + "./go_mod_one", + "./foo/go_mod_two", + "./bar/baz/go_mod_three", + ], +) + +def _go_work_test_impl(ctx): + env = unittest.begin(ctx) + asserts.equals(env, _EXPECTED_GO_WORK_PARSE_RESULT, parse_go_work(_GO_WORK_CONTENT, Label("@@//:go.work"))) + return unittest.end(env) + +go_work_test = unittest.make(_go_work_test_impl) + def go_mod_test_suite(name): unittest.suite( name, go_mod_test, go_mod_21_test, go_sum_test, + go_work_test, + use_spec_test, ) diff --git a/tests/bzlmod/semver_test.bzl b/tests/bzlmod/semver_test.bzl index 610d3cfce..0f0bd30dc 100644 --- a/tests/bzlmod/semver_test.bzl +++ b/tests/bzlmod/semver_test.bzl @@ -1,5 +1,5 @@ load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") -load("//internal/bzlmod:semver.bzl", "semver") +load("//internal/bzlmod:semver.bzl", "humanize_comparable_version", "semver") _SORTED_TEST_VERSIONS = [ "0.1-a", @@ -77,8 +77,23 @@ def _semver_test_impl(ctx): semver_test = unittest.make(_semver_test_impl) +def _humanize_test_impl(ctx): + env = unittest.begin(ctx) + + # remove everything after and including the frist + as it is not preserved in a comparable + RESTORABLE_VERSIONS = [version.split("+")[0] for version in _SORTED_TEST_VERSIONS] + + for version in RESTORABLE_VERSIONS: + humanized = humanize_comparable_version(semver.to_comparable(version, relaxed = RESTORABLE_VERSIONS)) + asserts.equals(env, "v" + version, humanized) + + return unittest.end(env) + +humanize_test = unittest.make(_humanize_test_impl) + def semver_test_suite(name): unittest.suite( name, semver_test, + humanize_test, ) diff --git a/tests/bzlmod/utils_test.bzl b/tests/bzlmod/utils_test.bzl index 99239822f..87cd9f98b 100644 --- a/tests/bzlmod/utils_test.bzl +++ b/tests/bzlmod/utils_test.bzl @@ -11,7 +11,7 @@ _EXPECT_REPLACED_STRUCT = struct( direct = True, path = "github.com/bazelbuild/buildtools", replace = "path/to/add/replace", - version = "v1.2.2" + version = "v1.2.2", ) def _with_replaced_or_new_fields_test_impl(ctx):