diff --git a/internal/pkg/update/github_test.go b/internal/pkg/update/github_test.go index 822cf60..067a01a 100644 --- a/internal/pkg/update/github_test.go +++ b/internal/pkg/update/github_test.go @@ -58,6 +58,18 @@ func TestLatestGithub(t *testing.T) { BaseURL: "https://github.com/protocolbuffers/protobuf/releases/", LatestURL: "https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz", }, + + // https://github.com/opencontainers/runc/releases has releases with extra assets (and no version in the file name). + "https://github.com/opencontainers/runc/releases/download/v1.0.0/runc.tar.xz": { + HasUpdate: true, + BaseURL: "https://github.com/opencontainers/runc/releases/", + LatestURL: "", + }, + "https://github.com/opencontainers/runc/releases/download/v1.0.1/runc.tar.xz": { + HasUpdate: false, + BaseURL: "https://github.com/opencontainers/runc/releases/", + LatestURL: "https://github.com/opencontainers/runc/releases/download/v1.0.1/runc.tar.xz", + }, } { source, expected := source, expected diff --git a/internal/pkg/update/version.go b/internal/pkg/update/version.go index 6acd2a9..e0e2518 100644 --- a/internal/pkg/update/version.go +++ b/internal/pkg/update/version.go @@ -6,14 +6,16 @@ package update import ( "fmt" - "net/url" "path/filepath" + "regexp" "strings" "github.com/Masterminds/semver" ) var ( + versionRE = regexp.MustCompile(semver.SemVerRegex) // the same as semver.versionRegex except "^" and "$" + commonExtensions = map[string]struct{}{ ".bz2": {}, ".diff": {}, @@ -28,15 +30,7 @@ var ( // extractVersion extracts SemVer version from file name or URL. func extractVersion(s string) (*semver.Version, error) { - // extract file name - u, err := url.Parse(s) - if err != nil { - return nil, err - } - - s = filepath.Base(u.Path) - - // remove common extensions + // remove common extensions like .bz2 that would confuse SemVer parser found := true for found { ext := filepath.Ext(s) @@ -45,15 +39,13 @@ func extractVersion(s string) (*semver.Version, error) { } } - // remove package name, keep only version - i := strings.IndexAny(s, "0123456789") - if i < 0 { - return nil, fmt.Errorf("failed to remove package name from %q", s) + matches := versionRE.FindAllString(s, -1) + if len(matches) == 0 { + return nil, fmt.Errorf("failed to find version in %q", s) } - s = s[i:] - - res, err := semver.NewVersion(s) + // use the last match to skip hostnames, folders, etc + res, err := semver.NewVersion(matches[len(matches)-1]) if err != nil { return nil, fmt.Errorf("%q: %w", s, err) } diff --git a/internal/pkg/update/version_test.go b/internal/pkg/update/version_test.go index 87ee130..b3d78a2 100644 --- a/internal/pkg/update/version_test.go +++ b/internal/pkg/update/version_test.go @@ -23,6 +23,7 @@ func TestExtractVersion(t *testing.T) { "https://github.com/pullmoll/void-linux/archive/refs/tags/v1.2.7.tar.gz": "1.2.7", "https://github.com/protocolbuffers/protobuf/releases/download/v3.17.3/protobuf-cpp-3.17.3.tar.gz": "3.17.3", + "https://github.com/opencontainers/runc/releases/download/v1.0.1/runc.tar.xz": "1.0.1", } { s, expected := s, expected t.Run(s, func(t *testing.T) {