Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bzlmod: Return extension_metadata to automate use_repo fixes #1511

Merged
merged 1 commit into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 58 additions & 7 deletions internal/bzlmod/go_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ visibility("//")

# These Go modules are imported as Bazel modules via bazel_dep, not as
# go_repository.
IGNORED_MODULE_PATHS = [
_IGNORED_MODULE_PATHS = [
"github.com/bazelbuild/bazel-gazelle",
"github.com/bazelbuild/rules_go",
]
Expand Down Expand Up @@ -143,6 +143,24 @@ def _repo_name(importpath):
candidate_name = "_".join(segments).replace("-", "_")
return "".join([c.lower() if c.isalnum() else "_" for c in candidate_name.elems()])

def _is_dev_dependency(module_ctx, tag):
if hasattr(tag, "_is_dev_dependency"):
# Synthetic tags generated from go_deps.from_file have this "hidden" attribute.
return tag._is_dev_dependency

# This function is available in Bazel 6.2.0 and later. This is the same version that has
# module_ctx.extension_metadata, so the return value of this function is not used if it is
# not available.
return module_ctx.is_dev_dependency(tag) if hasattr(module_ctx, "is_dev_dependency") else False

def _extension_metadata(module_ctx, *, root_module_direct_deps, root_module_direct_dev_deps):
if not hasattr(module_ctx, "extension_metadata"):
return None
return module_ctx.extension_metadata(
root_module_direct_deps = root_module_direct_deps,
root_module_direct_dev_deps = root_module_direct_dev_deps,
)

def _go_repository_config_impl(ctx):
repos = []
for name, importpath in sorted(ctx.attr.importpaths.items()):
Expand All @@ -169,12 +187,19 @@ def _noop(_):

def _go_deps_impl(module_ctx):
module_resolutions = {}
sums = {}
replace_map = {}

gazelle_overrides = {}
module_overrides = {}

root_versions = {}
root_fixups = []
sums = {}
replace_map = {}
root_module_direct_deps = {}
root_module_direct_dev_deps = {}

if module_ctx.modules[0].name == "gazelle":
root_module_direct_deps["bazel_gazelle_go_repository_config"] = None

outdated_direct_dep_printer = print
for module in module_ctx.modules:
Expand Down Expand Up @@ -221,7 +246,11 @@ def _go_deps_impl(module_ctx):
additional_module_tags = []
for from_file_tag in module.tags.from_file:
module_tags_from_go_mod, go_mod_replace_map = deps_from_go_mod(module_ctx, from_file_tag.go_mod)
additional_module_tags += module_tags_from_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)
for tag in module_tags_from_go_mod
]

if module.is_root:
replace_map.update(go_mod_replace_map)
Expand Down Expand Up @@ -254,7 +283,7 @@ def _go_deps_impl(module_ctx):
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 module_tag.path in IGNORED_MODULE_PATHS:
if module_tag.path in _IGNORED_MODULE_PATHS:
continue
paths[module_tag.path] = None
raw_version = _canonicalize_raw_version(module_tag.version)
Expand All @@ -266,9 +295,15 @@ def _go_deps_impl(module_ctx):
# For modules imported from a go.sum, we know which ones are direct
# dependencies and can thus only report implicit version upgrades
# for direct dependencies. For manually specified go_deps.module
# tags, we always report version upgrades.
if module.is_root and getattr(module_tag, "direct", True):
# tags, we always report version upgrades unless users override with
# the "indirect" attribute.
if module.is_root and not module_tag.indirect:
root_versions[module_tag.path] = raw_version
if _is_dev_dependency(module_ctx, module_tag):
root_module_direct_dev_deps[_repo_name(module_tag.path)] = None
else:
root_module_direct_deps[_repo_name(module_tag.path)] = None

version = semver.to_comparable(raw_version)
if module_tag.path not in module_resolutions or version > module_resolutions[module_tag.path].version:
module_resolutions[module_tag.path] = struct(
Expand Down Expand Up @@ -367,6 +402,18 @@ build_naming_convention) or "gazelle:proto <value>" (for build_file_proto_mode)
to its 'directives' attribute.
""" + format_module_file_fixup(root_fixups))

return _extension_metadata(
module_ctx,
root_module_direct_deps = root_module_direct_deps.keys(),
# If a Go module appears as both a dev and a non-dev dependency, it has to be imported as a
# non-dev dependency.
root_module_direct_dev_deps = {
repo_name: None
for repo_name in root_module_direct_dev_deps.keys()
if repo_name not in root_module_direct_deps
}.keys(),
)

def _get_sum_from_module(path, module, sums):
entry = (path, module.raw_version)
if hasattr(module, "replace"):
Expand Down Expand Up @@ -438,6 +485,10 @@ _module_tag = tag_class(
"package",
],
),
"indirect": attr.bool(
doc = """Whether this Go module is an indirect dependency.""",
default = False,
),
},
)

Expand Down
4 changes: 2 additions & 2 deletions internal/bzlmod/go_mod.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def deps_from_go_mod(module_ctx, go_mod_label):
deps.append(struct(
path = require.path,
version = require.version,
direct = require.direct,
indirect = require.indirect,
))

return deps, go_mod.replace_map
Expand Down Expand Up @@ -120,7 +120,7 @@ def _parse_directive(state, directive, tokens, comment, path, line_no):
state["require"].append(struct(
path = tokens[0],
version = tokens[1],
direct = comment != "indirect",
indirect = comment == "indirect",
))
elif directive == "replace":
# A replace directive might use a local file path beginning with ./ or ../
Expand Down
2 changes: 2 additions & 0 deletions tests/bcr/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ go_deps.module(
path = "gopkg.in/yaml.v3",
sum = "h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=",
version = "v3.0.1",
indirect = True,
)
go_deps.module(
path = "github.com/davecgh/go-spew",
sum = "h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=",
version = "v1.1.1",
indirect = True,
)
use_repo(
go_deps,
Expand Down
12 changes: 6 additions & 6 deletions tests/bzlmod/go_mod_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ _EXPECTED_GO_MOD_PARSE_RESULT = struct(
module = "github.com/bazelbuild/bazel-gazelle",
replace_map = {"github.com/go-fsnotify/fsnotify": struct(to_path = "github.com/fsnotify/fsnotify", version = "1.4.2")},
require = (
struct(direct = True, path = "github.com/bazelbuild/buildtools", version = "v0.0.0-20220531122519-a43aed7014c8"),
struct(direct = True, path = "github.com/bazelbuild/rules_go", version = "v0.n\\\"33.0"),
struct(direct = False, path = "github.com/bmatcuk/doublestar/v4", version = "v4.0.2"),
struct(direct = True, path = "golang.org/x/tools", version = "v0.1.11"),
struct(direct = True, path = "github.com/go-fsnotify/fsnotify", version = "v1.5.4"),
struct(direct = False, path = "golang.org/x/sys", version = "v0.0.0-20220624220833-87e55d714810"),
struct(indirect = False, path = "github.com/bazelbuild/buildtools", version = "v0.0.0-20220531122519-a43aed7014c8"),
struct(indirect = False, path = "github.com/bazelbuild/rules_go", version = "v0.n\\\"33.0"),
struct(indirect = True, path = "github.com/bmatcuk/doublestar/v4", version = "v4.0.2"),
struct(indirect = False, path = "golang.org/x/tools", version = "v0.1.11"),
struct(indirect = False, path = "github.com/go-fsnotify/fsnotify", version = "v1.5.4"),
struct(indirect = True, path = "golang.org/x/sys", version = "v0.0.0-20220624220833-87e55d714810"),
),
)

Expand Down