Skip to content

Commit

Permalink
package_managers: gomod: Allow pre-release IDs & comments in version …
Browse files Browse the repository at this point in the history
…string

Golang allows arbitrary pre-release version identifiers in version
string, i.e. trying to parse the following in a go.mod file passes:

    # go.mod
    go 1.21.0foo458

    $ go mod edit -json | jq .Go
    1.21.0foo458

Golang also allows go.mod files to include commentaries on the version
string line, i.e. the following passes the built-in parser:

    # go.mod
    go 1.21.0rc1//commentary

    go mod edit -json | jq .Go
    1.21.rc1

This patches enhances our regex to support both.

Signed-off-by: Erik Skultety <[email protected]>
  • Loading branch information
eskultety committed Jul 22, 2024
1 parent e391f78 commit e6a8010
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
12 changes: 9 additions & 3 deletions cachi2/core/package_managers/gomod.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,15 @@ def _get_gomod_version(go_mod_file: RootedPath) -> Tuple[Optional[str], Optional
go_version = None
toolchain_version = None

version_str_regex = r"(?P<ver>\d+\.\d+(:?\.\d+)?)"
go_version_regex = rf"^\s*go\s+{version_str_regex}\s*$"
toolchain_version_regex = rf"^\s*toolchain\s+go{version_str_regex}\s*$"
# this needs to be able to handle arbitrary pre-release version identifiers and commentaries
# as well, since Go itself can parse it
# - 'go 1.21.0'
# - ' go 1.21.0rc4'
# - 'go 1.21beta1//commentary'
version_str_regex = r"(?P<ver>\d+\.\d+(:?\.\d+)?(?:[a-zA-Z]+\d+)?)"
post_version_chars_regex = r"\s*(?:\/\/.*)?"
go_version_regex = rf"^\s*go\s+{version_str_regex}{post_version_chars_regex}$"
toolchain_version_regex = rf"^\s*toolchain\s+go{version_str_regex}{post_version_chars_regex}$"

go_pattern = re.compile(go_version_regex)
toolchain_pattern = re.compile(toolchain_version_regex)
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/package_managers/test_gomod.py
Original file line number Diff line number Diff line change
Expand Up @@ -1930,6 +1930,11 @@ def test_fetch_tags_fail(repo_remote_with_tag: tuple[RootedPath, RootedPath]) ->
pytest.param("go 1.21", "1.21", None, id="go_minor"),
pytest.param("go 1.21.0", "1.21.0", None, id="go_micro"),
pytest.param(" go 1.21.4 ", "1.21.4", None, id="go_spaces"),
pytest.param("go 1.21rc4", "1.21rc4", None, id="go_minor_rc"),
pytest.param("go 1.21.0rc4", "1.21.0rc4", None, id="go_micro_rc"),
pytest.param("go 1.21.0 // comment", "1.21.0", None, id="go_commentary"),
pytest.param("go 1.21.0//commentary", "1.21.0", None, id="go_commentary_no_spaces"),
pytest.param("go 1.21.0beta2//comment", "1.21.0beta2", None, id="go_rc_commentary"),
pytest.param(" toolchain go1.21.4 ", None, "1.21.4", id="toolchain_spaces"),
pytest.param("go 1.21\ntoolchain go1.21.6", "1.21", "1.21.6", id="go_and_toolchain"),
],
Expand All @@ -1949,6 +1954,8 @@ def test_get_gomod_version(
"go 1.21.0.100", # non-conforming to the X.Y(.Z)? versioning template
"1.21", # missing 'go' at the beginning
"go 1.21 foo", # extra characters after version string
"go 1.21prerelease", # pre-release with no number
"go 1.21prerelease_4", # pre-release with non-alphanum character
"toolchain 1.21", # missing 'go' prefix for the toolchain spec
]

Expand Down

0 comments on commit e6a8010

Please sign in to comment.