diff --git a/internal/cli/main.go b/internal/cli/main.go index 023e798..29b1532 100644 --- a/internal/cli/main.go +++ b/internal/cli/main.go @@ -97,7 +97,7 @@ func Initialize(ctx *cli.Context) { } if ok, err := config.CheckGitVersion(gitVersion); err != nil { - log.Fatal().Err(err).Send() + log.Warn().Err(err).Msg("Could not determine the git version; some features may not work as expected") } else if !ok { log.Warn().Msg("Git version may be too old, as Opengist has not been tested prior git version 2.28 and some features would not work. " + "Current git version: " + gitVersion) diff --git a/internal/config/config.go b/internal/config/config.go index 3167a98..1fbc063 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "reflect" + "regexp" "slices" "strconv" "strings" @@ -244,16 +245,22 @@ func InitLog() { } } +// gitVersionRegex extracts the major and minor numbers from a git version string. +// It tolerates a leading "git version " prefix as well as suffixes such as the +// ".windows.1" appended by Git for Windows (e.g. "git version 2.50.1.windows.1"). +var gitVersionRegex = regexp.MustCompile(`(\d+)\.(\d+)`) + func CheckGitVersion(version string) (bool, error) { - versionParts := strings.Split(version, ".") - if len(versionParts) < 2 { - return false, fmt.Errorf("invalid version string") + matches := gitVersionRegex.FindStringSubmatch(version) + if matches == nil { + return false, fmt.Errorf("invalid version string: %q", version) } - major, err := strconv.Atoi(versionParts[0]) + + major, err := strconv.Atoi(matches[1]) if err != nil { return false, fmt.Errorf("invalid major version number") } - minor, err := strconv.Atoi(versionParts[1]) + minor, err := strconv.Atoi(matches[2]) if err != nil { return false, fmt.Errorf("invalid minor version number") } diff --git a/internal/config/config_test.go b/internal/config/config_test.go new file mode 100644 index 0000000..92c1a24 --- /dev/null +++ b/internal/config/config_test.go @@ -0,0 +1,33 @@ +package config + +import "testing" + +func TestCheckGitVersion(t *testing.T) { + tests := []struct { + name string + version string + wantOk bool + wantError bool + }{ + {"recent version", "2.50.1", true, false}, + {"git for windows suffix", "2.50.1.windows.1", true, false}, + {"full git --version output", "git version 2.50.1.windows.1", true, false}, + {"exactly 2.28", "2.28.0", true, false}, + {"too old", "2.27.0", false, false}, + {"major too old", "1.99.0", false, false}, + {"empty string", "", false, true}, + {"no version numbers", "git version unknown", false, true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ok, err := CheckGitVersion(tt.version) + if (err != nil) != tt.wantError { + t.Fatalf("CheckGitVersion(%q) error = %v, wantError %v", tt.version, err, tt.wantError) + } + if ok != tt.wantOk { + t.Errorf("CheckGitVersion(%q) ok = %v, want %v", tt.version, ok, tt.wantOk) + } + }) + } +}