forked from Debian/dh-make-golang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
version.go
109 lines (100 loc) · 3.34 KB
/
version.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
import (
"fmt"
"log"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"time"
)
var (
// describeRegexp parses the count and revision part of the “git describe --long” output.
describeRegexp = regexp.MustCompile(`-(\d+)-g([0-9a-f]+)\s*$`)
)
// TODO: also support other VCS
func pkgVersionFromGit(gitdir string) (string, error) {
cmd := exec.Command("git", "describe", "--exact-match")
cmd.Dir = gitdir
if tag, err := cmd.Output(); err == nil {
version := strings.TrimSpace(string(tag))
if strings.HasPrefix(version, "v") {
version = version[1:]
}
return version, nil
}
cmd = exec.Command("git", "log", "--pretty=format:%ct", "-n1")
cmd.Dir = gitdir
lastCommitUnixBytes, err := cmd.Output()
if err != nil {
return "", err
}
lastCommitUnix, err := strconv.ParseInt(strings.TrimSpace(string(lastCommitUnixBytes)), 0, 64)
if err != nil {
return "", err
}
// Find the most recent tag (whether annotated or not)
cmd = exec.Command("git", "describe", "--abbrev=0", "--tags")
cmd.Dir = gitdir
// 1.0~rc1 < 1.0 < 1.0+b1, as per
// https://www.debian.org/doc/manuals/maint-guide/first.en.html#namever
lastTag := "0.0~"
if lastTagBytes, err := cmd.Output(); err == nil {
lastTag = strings.TrimSpace(string(lastTagBytes))
// Compare with the most recent annotated tag
foundLightweightTag := false
cmd = exec.Command("git", "describe", "--abbrev=0")
cmd.Dir = gitdir
if lastAnnotatedTagBytes, err := cmd.Output(); err == nil {
lastAnnotatedTag := strings.TrimSpace(string(lastAnnotatedTagBytes))
if lastTag != lastAnnotatedTag {
log.Printf("WARNING: Lightweight tag %q found, but the most recent annotated tag is %q\n", lastTag, lastAnnotatedTag)
foundLightweightTag = true
}
} else {
log.Printf("WARNING: Annotated tag not found, using lightweight tag %q\n", lastTag)
foundLightweightTag = true
}
if foundLightweightTag {
log.Printf(" Lightweight tags (created by e.g. \"git tag %s\"", lastTag)
log.Printf(" with no flag) are problematic because, among other\n")
log.Printf(" things, they are ignored by \"git describe\" by default.\n")
log.Printf(" Please suggest that the upstream replaces the\n")
log.Printf(" lightweight tags with annotated ones. See\n")
log.Printf(" https://github.com/russross/blackfriday/issues/196\n")
log.Printf(" for details.\n")
log.Printf("\n")
}
lastTag += "+"
if strings.HasPrefix(lastTag, "v") {
lastTag = lastTag[1:]
}
}
// This results in an output like 4.10.2-232-g9f107c8
cmd = exec.Command("git", "describe", "--long", "--tags")
cmd.Dir = gitdir
describeBytes, err := cmd.Output()
if err != nil {
// In case there are no tags at all, we need to pass --all, but we
// cannot use --all unconditionally because then git will describe
// e.g. heads/master instead of tags.
cmd = exec.Command("git", "describe", "--long", "--all")
cmd.Dir = gitdir
cmd.Stderr = os.Stderr
describeBytes, err = cmd.Output()
if err != nil {
return "", err
}
}
submatches := describeRegexp.FindSubmatch(describeBytes)
if submatches == nil {
return "", fmt.Errorf("git describe output %q does not match expected format", string(describeBytes))
}
version := fmt.Sprintf("%sgit%s.%s.%s",
lastTag,
time.Unix(lastCommitUnix, 0).UTC().Format("20060102"),
string(submatches[1]),
string(submatches[2]))
return version, nil
}