From 6ea075869e4ae378c9e2af33628f6e1a912008f3 Mon Sep 17 00:00:00 2001 From: HNO3Miracle Date: Sat, 6 Jun 2026 15:40:18 +0800 Subject: [PATCH] [Fix] fix hash version date. --- check_version.go | 77 +++++++++++------------------------------------- pkgsite_test.go | 57 +++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 60 deletions(-) diff --git a/check_version.go b/check_version.go index 665c945..c99cb65 100644 --- a/check_version.go +++ b/check_version.go @@ -3,7 +3,6 @@ package main import ( "fmt" "log" - "os" "os/exec" "regexp" "slices" @@ -14,9 +13,6 @@ import ( ) var ( - // describeRegexp parses the count and revision part of the “git describe --long” output. - describeRegexp = regexp.MustCompile(`-\d+-g([0-9a-f]+)\s*$`) - // semverRegexp checks if a string is a valid Go semver, // from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string // with leading "v" added. @@ -25,8 +21,21 @@ var ( // uversionPrereleaseRegexp checks for upstream pre-release // so that '-' can be replaced with '~' in pkgVersionFromGit. uversionPrereleaseRegexp = regexp.MustCompile(`(\d)[_\.\-\+]?(RC|rc|pre|dev|beta|alpha)[.]?(\d*)$`) + + packagingDateNow = time.Now ) +func packagingDateString() string { + return packagingDateNow().Format("20060102") +} + +func shortCommitHash(hash string) string { + if len(hash) > 7 { + return hash[:7] + } + return hash +} + // pkgVersionFromGit determines the actual version to be packaged // from the git repository status and user preference. // Besides returning the upstream version, the "upstream" struct @@ -111,50 +120,6 @@ func pkgVersionFromGit(gitdir string, u *upstream, preferredRev string, forcePre // Packaging @master (prerelease) - mainVer := "" - //if u.hasRelease { - // mainVer = u.version + "+" - //} - - // Find committer date, UNIX timestamp - cmd = exec.Command("git", "log", "--pretty=format:%ct", "-n1", "--no-show-signature") - cmd.Dir = gitdir - lastCommitUnixBytes, err := cmd.Output() - if err != nil { - return "", fmt.Errorf("git log: %w", err) - } - lastCommitUnix, err := strconv.ParseInt(strings.TrimSpace(string(lastCommitUnixBytes)), 0, 64) - if err != nil { - return "", fmt.Errorf("parse last commit date: %w", err) - } - - dateStr := time.Unix(lastCommitUnix, 0).UTC().Format("20060102") - - // Fetch commit hash - cmd = exec.Command("git", "describe", "--long", "--tags") - cmd.Dir = gitdir - lastCommitHash := "" - describeBytes, err := cmd.Output() - if err != nil { - // In case there are no tags at all, we just use the sha of the current commit - cmd = exec.Command("git", "rev-parse", "--short", "HEAD") - cmd.Dir = gitdir - cmd.Stderr = os.Stderr - revparseBytes, err := cmd.Output() - if err != nil { - return "", fmt.Errorf("git rev-parse: %w", err) - } - lastCommitHash = strings.TrimSpace(string(revparseBytes)) - u.commitIsh = lastCommitHash - } else { - submatches := describeRegexp.FindSubmatch(describeBytes) - if submatches == nil { - return "", fmt.Errorf("git describe output %q does not match expected format", string(describeBytes)) - } - lastCommitHash = string(submatches[1]) - u.commitIsh = strings.TrimSpace(string(describeBytes)) - } - // Fetch full commit hash cmd = exec.Command("git", "rev-parse", "HEAD") cmd.Dir = gitdir @@ -163,18 +128,10 @@ func pkgVersionFromGit(gitdir string, u *upstream, preferredRev string, forcePre return "", fmt.Errorf("git rev-parse HEAD: %w", err) } fullCommitHash := strings.TrimSpace(string(fullCommitHashBytes)) + lastCommitHash := shortCommitHash(fullCommitHash) + u.commitIsh = lastCommitHash - u.version = fmt.Sprintf("%sgit%s.%s", - mainVer, - time.Unix(lastCommitUnix, 0).UTC().Format("20060102"), - lastCommitHash) - - if u.hasRelease { - // have tag: 1.2.3.20250101+git9f107c8 - u.version = fmt.Sprintf("%s.%s+git%s", u.version, dateStr, lastCommitHash) - } else { - // without tag: 0.git20250101.96ee002 96ee0021ea0fb9174681b8004d8deba3c499d7f5 - u.version = fmt.Sprintf("0+git%s.%s\n%%define commit_id %s", dateStr, lastCommitHash, fullCommitHash) - } + // Snapshot versions are based on the packaging date, not the commit date. + u.version = fmt.Sprintf("0+git%s.%s\n%%define commit_id %s", packagingDateString(), lastCommitHash, fullCommitHash) return u.version, nil } diff --git a/pkgsite_test.go b/pkgsite_test.go index f6716e7..599b334 100644 --- a/pkgsite_test.go +++ b/pkgsite_test.go @@ -3,8 +3,12 @@ package main import ( "io" "net/http" + "os" + "os/exec" + "path/filepath" "strings" "testing" + "time" ) type roundTripFunc func(*http.Request) (*http.Response, error) @@ -457,3 +461,56 @@ func TestSourceURLForSpecRejectsCommitIDForRepoSubmodule(t *testing.T) { t.Fatalf("sourceURLForSpec() error = %v, want canonical pseudo-version message", err) } } + +func TestPkgVersionFromGitUsesPackagingDateAndSevenCharHash(t *testing.T) { + oldNow := packagingDateNow + packagingDateNow = func() time.Time { + return time.Date(2025, 8, 8, 12, 0, 0, 0, time.UTC) + } + defer func() { packagingDateNow = oldNow }() + + dir := t.TempDir() + runGit(t, dir, nil, "init") + if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module example.com/project\n"), 0644); err != nil { + t.Fatalf("write go.mod: %v", err) + } + runGit(t, dir, nil, "add", "go.mod") + runGit(t, dir, []string{ + "GIT_AUTHOR_NAME=Test", + "GIT_AUTHOR_EMAIL=test@example.invalid", + "GIT_COMMITTER_NAME=Test", + "GIT_COMMITTER_EMAIL=test@example.invalid", + "GIT_AUTHOR_DATE=1999-01-02T03:04:05Z", + "GIT_COMMITTER_DATE=1999-01-02T03:04:05Z", + }, "commit", "-m", "initial") + + fullHash := strings.TrimSpace(runGit(t, dir, nil, "rev-parse", "HEAD")) + want := "0+git20250808." + fullHash[:7] + "\n%define commit_id " + fullHash + + u := upstream{} + got, err := pkgVersionFromGit(dir, &u, "", false) + if err != nil { + t.Fatalf("pkgVersionFromGit() returned error: %v", err) + } + if got != want { + t.Fatalf("pkgVersionFromGit() = %q, want %q", got, want) + } + if strings.Contains(got, "19990102") { + t.Fatalf("pkgVersionFromGit() used commit date: %q", got) + } + if u.commitIsh != fullHash[:7] { + t.Fatalf("commitIsh = %q, want %q", u.commitIsh, fullHash[:7]) + } +} + +func runGit(t *testing.T, dir string, env []string, args ...string) string { + t.Helper() + cmd := exec.Command("git", args...) + cmd.Dir = dir + cmd.Env = append(os.Environ(), env...) + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("git %s failed: %v\n%s", strings.Join(args, " "), err, out) + } + return string(out) +} -- 2.52.0