[Fix] fix hash version date. #4

Merged
misaka00251 merged 1 commits from HNO3Miracle/go2spec:fix-date into master 2026-06-11 02:23:13 +00:00
2 changed files with 74 additions and 60 deletions
+17 -60
View File
@@ -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
}
+57
View File
@@ -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)
}