Skip to content

Commit

Permalink
support replace directives with a version qualifier on the left
Browse files Browse the repository at this point in the history
  • Loading branch information
andyscott committed Dec 3, 2023
1 parent d76c08f commit 60081d1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
8 changes: 8 additions & 0 deletions internal/bzlmod/go_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,14 @@ def _go_deps_impl(module_ctx):
# in the module resolutions and swapping out the entry.
for path, replace in replace_map.items():
if path in module_resolutions:

# If the replace directive specified a version then we only
# apply it if the versions match.
if replace.from_version:
comparable_from_version = semver.to_comparable(replace.from_version)
if module_resolutions[path].version != comparable_from_version:
continue

new_version = semver.to_comparable(replace.version)
module_resolutions[path] = with_replaced_or_new_fields(
module_resolutions[path],
Expand Down
27 changes: 20 additions & 7 deletions internal/bzlmod/go_mod.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,26 @@ def _parse_directive(state, directive, tokens, comment, path, line_no):
if len(tokens) == 3 and tokens[2][0] == ".":
fail("{}:{}: local file path not supported in replace directive: '{}'".format(path, line_no, tokens[2]))

if len(tokens) != 4 or tokens[1] != "=>":
fail("{}:{}: replace directive must follow pattern: 'replace from_path => to_path version' ".format(path, line_no))
from_path = tokens[0]
state["replace"][from_path] = struct(
to_path = tokens[2],
version = _canonicalize_raw_version(tokens[3]),
)
# pattern: replace from_path => to_path to_version
if len(tokens) == 4 and tokens[1] == "=>":
state["replace"][tokens[0]] = 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"][tokens[0]] = 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'"
)

# TODO: Handle exclude.

Expand Down
6 changes: 5 additions & 1 deletion tests/bzlmod/go_mod_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,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
module github.com/bazelbuild/bazel-gazelle
Expand All @@ -28,7 +29,10 @@ require golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
_EXPECTED_GO_MOD_PARSE_RESULT = struct(
go = (1, 18),
module = "github.com/bazelbuild/bazel-gazelle",
replace_map = {"github.com/go-fsnotify/fsnotify": struct(to_path = "github.com/fsnotify/fsnotify", version = "1.4.2")},
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"),
},
require = (
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"),
Expand Down

0 comments on commit 60081d1

Please sign in to comment.