From 4d3868aad0cbdc83cab549dff51a3266afb0576e Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Fri, 21 Jun 2024 09:30:56 +0300 Subject: [PATCH] Add support for Git 2.45+ iso-strict date format Git 2.45+ introduced a backward incompatible change in the iso-strict date format, showing time in the Zulu timezone with Z suffix instead of +00:00. This commit adds parsing for the new date format before falling back to the old format. Ignore errors for old git versions where %cI is not defined. Revise GetCGRVersion error messages. Revise GetCGRVersion unit test. --- utils/coreutils.go | 40 +++++++++++----- utils/coreutils_test.go | 104 +++++++++++++++++++++++++++++----------- 2 files changed, 105 insertions(+), 39 deletions(-) diff --git a/utils/coreutils.go b/utils/coreutils.go index cd2796198..974a8e64e 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -758,23 +758,41 @@ func GetCGRVersion() (vers string, err error) { if GitCommitDate == "" || GitCommitHash == "" { return vers, nil } - var commitHash string - var commitDate time.Time var matched bool - commitDate, _ = time.Parse("2006-01-02T15:04:05-07:00", strings.TrimSpace(GitCommitDate)) - //ignoring err temporarily until a future fix since we dont get correct date format in older linux distributions - //if err != nil { - //return vers, fmt.Errorf("Building version - error: <%s> compiling commit date", err.Error()) - //} + /* + Git v2.45 relevant release note: + * The output format for dates "iso-strict" has been tweaked to show + a time in the Zulu timezone with "Z" suffix, instead of "+00:00". + */ + + // Parse the git commit date, which might be in different formats depending on the git version + trimmedCommitDate := strings.TrimSpace(GitCommitDate) + commitDate, err := time.Parse("2006-01-02T15:04:05Z", trimmedCommitDate) + if err != nil { + // Failed to parse iso-strict date format for git version 2.45+. Try to parse with the previous format. + var fallbackErr error + commitDate, fallbackErr = time.Parse("2006-01-02T15:04:05-07:00", trimmedCommitDate) + if fallbackErr != nil { + // Both parsing attempts failed, group the errors together. + err = fmt.Errorf( + "failed to parse date:\ngit2.45+ iso-strict format: %w\nprevious iso-strict format: %w", + err, fallbackErr) + } else { + err = nil // successfully parsed with fallback format + } + } + if err != nil && GitCommitDate != "%cI" { // ignore error for old git versions where %cI is not defined + return vers, fmt.Errorf("version build error: %w", err) + } matched, err = regexp.MatchString("^[0-9a-f]{12,}$", GitCommitHash) if err != nil { - return vers, fmt.Errorf("Building version - error: <%s> compiling commit hash", err.Error()) + return vers, fmt.Errorf("version build error: commit hash compilation failed: %v", err) } else if !matched { - return vers, fmt.Errorf("Building version - error: <%s> compiling commit hash", "Regex not matched") + return vers, fmt.Errorf("version build error: commit hash does not match expected format") } - commitHash = GitCommitHash - //CGRateS@v0.11.0~dev-20200110075344-7572e7b11e00 + commitHash := GitCommitHash + //CGRateS@v0.10.1~dev-20200110075344-7572e7b11e00 return fmt.Sprintf("%s@%s-%s-%s", CGRateS, Version, commitDate.UTC().Format("20060102150405"), commitHash[:12]), nil } diff --git a/utils/coreutils_test.go b/utils/coreutils_test.go index c699b5da9..262177a74 100644 --- a/utils/coreutils_test.go +++ b/utils/coreutils_test.go @@ -1304,35 +1304,83 @@ func TestLess(t *testing.T) { } func TestGetCGRVersion(t *testing.T) { - GitCommitDate = "2016-12-30T19:48:09+01:00" - GitCommitHash = "73014daa0c1d7edcb532d5fe600b8a20d588cdf8" - expVers := "CGRateS@" + Version - eVers := expVers + "-20161230184809-73014daa0c1d" - if vers, err := GetCGRVersion(); err != nil { - t.Error(err) - } else if vers != eVers { - t.Errorf("Expecting: <%s>, received: <%s>", eVers, vers) + tests := []struct { + name string + date string + hash string + want string + wantErr string + parseErr bool + }{ + { + name: "successful version build (git2.45+ date format)", + date: "2016-12-30T19:48:09Z", + hash: "73014daa0c1d7edcb532d5fe600b8a20d588cdf8", + want: "CGRateS@" + Version + "-20161230194809-73014daa0c1d", + }, + { + name: "successful version build (previous date format)", + date: "2016-12-30T19:48:09+01:00", + hash: "73014daa0c1d7edcb532d5fe600b8a20d588cdf8", + want: "CGRateS@" + Version + "-20161230184809-73014daa0c1d", + }, + { + name: "unknown verb %cI (git version is too old)", + date: "%cI", + hash: "73014daa0c1d7edcb532d5fe600b8a20d588cdf8", + want: "CGRateS@v0.11.0~dev-00010101000000-73014daa0c1d", + }, + { + name: "successful version build (default)", + date: "", + hash: "", + want: "CGRateS@" + Version, + }, + { + name: "wrong date format", + date: "wrong format", + hash: "73014daa0c1d7edcb532d5fe600b8a20d588cdf8", + parseErr: true, + }, + { + name: "wrong hash", + date: "2016-12-30T19:48:09+01:00", + hash: "73014DAA0C1D7EDCB532D5FE600B8A20D588CDF8", + want: "CGRateS@" + Version + "-20161230184809-73014daa0c1d", + wantErr: "version build error: commit hash does not match expected format", + parseErr: false, + }, } - GitCommitDate = "" - GitCommitHash = "" - if vers, err := GetCGRVersion(); err != nil { - t.Error(err) - } else if vers != expVers { - t.Errorf("Expecting: <%s>, received: <%s>", expVers, vers) - } - // GitCommitDate = "wrong format" - // GitCommitHash = "73014daa0c1d7edcb532d5fe600b8a20d588cdf8" - // if vers, err := GetCGRVersion(); err == nil || err.Error() != `Building version - error: compiling commit date` { - // t.Error(err) - // } else if vers != expVers { - // t.Errorf("Expecting: <%s>, received: <%s>", expVers, vers) - // } - GitCommitDate = "2016-12-30T19:48:09+01:00" - GitCommitHash = "73014DAA0C1D7EDCB532D5FE600B8A20D588CDF8" - if vers, err := GetCGRVersion(); err == nil || err.Error() != `Building version - error: compiling commit hash` { - t.Error(err) - } else if vers != expVers { - t.Errorf("Expecting: <%s>, received: <%s>", expVers, vers) + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + GitCommitDate = test.date + GitCommitHash = test.hash + got, err := GetCGRVersion() + switch { + case test.parseErr: + var parseError *time.ParseError + if !errors.As(err, &parseError) { + t.Fatalf("\nCommitDate: %q\nCommitHash: %q\nGetCGRVersion() err %q, want error of type *time.ParseError", + test.date, test.hash, err) + } + case err != nil: + if test.wantErr == "" { + t.Fatalf("\nCommitDate: %q\nCommitHash: %q\nGetCGRVersion() err %s, want nil", + test.date, test.hash, err) + } + if err.Error() != test.wantErr { + t.Fatalf("\nCommitDate: %q\nCommitHash: %q\nGetCGRVersion() err %q, want %q", + test.date, test.hash, err, test.wantErr) + } + case test.wantErr != "": + t.Fatalf("\nCommitDate: %q\nCommitHash: %q\nGetCGRVersion() err nil, want %q", + test.date, test.hash, test.wantErr) + case got != test.want: + t.Errorf("\nCommitDate: %q\nCommitHash: %q\nGetCGRVersion() = %q, want %q", + test.date, test.hash, got, test.want) + } + }) } }