forked from misaka00251/go2spec
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34f3ab2c70 | |||
| 6ea075869e |
+17
-60
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -87,6 +91,30 @@ func TestCleanSpecAssetPath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteLicenseAndDocFilesOrdersDocBeforeSortedLicenses(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "files")
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
t.Fatalf("create temp file: %v", err)
|
||||
}
|
||||
writeLicenseAndDocFiles(f, specAssetFiles{
|
||||
licenseFiles: []string{"zLICENSE", "COPYING", "LICENSE"},
|
||||
readmeFile: "README.md",
|
||||
}, true)
|
||||
if err := f.Close(); err != nil {
|
||||
t.Fatalf("close temp file: %v", err)
|
||||
}
|
||||
|
||||
content, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("read temp file: %v", err)
|
||||
}
|
||||
want := "%doc README.md\n%license COPYING\n%license LICENSE\n%license zLICENSE\n"
|
||||
if got := string(content); got != want {
|
||||
t.Fatalf("writeLicenseAndDocFiles() = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSummaryFromReadme(t *testing.T) {
|
||||
readme := `
|
||||
# Project
|
||||
@@ -457,3 +485,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)
|
||||
}
|
||||
|
||||
@@ -260,12 +260,14 @@ func writeRPMProgramSubpackage(f *os.File, gopkg, openRuyiProgram, openRuyiSrc,
|
||||
}
|
||||
|
||||
func writeLicenseAndDocFiles(f *os.File, assetFiles specAssetFiles, includeDoc bool) {
|
||||
for _, licenseFile := range assetFiles.licenseFiles {
|
||||
fmt.Fprintf(f, "%%license %s\n", licenseFile)
|
||||
}
|
||||
if includeDoc && assetFiles.readmeFile != "" {
|
||||
fmt.Fprintf(f, "%%doc %s\n", assetFiles.readmeFile)
|
||||
}
|
||||
licenseFiles := append([]string(nil), assetFiles.licenseFiles...)
|
||||
sort.Strings(licenseFiles)
|
||||
for _, licenseFile := range licenseFiles {
|
||||
fmt.Fprintf(f, "%%license %s\n", licenseFile)
|
||||
}
|
||||
}
|
||||
|
||||
func writeRPMFilesSection(f *os.File, openRuyiSrc, openRuyiLib, openRuyiProgram string, pkgType packageType, assetFiles specAssetFiles) {
|
||||
|
||||
Reference in New Issue
Block a user