main.go raw
1 package main
2
3 import (
4 "fmt"
5 "io/ioutil"
6 "os"
7 "path/filepath"
8 "strings"
9 "time"
10
11 "gopkg.in/src-d/go-git.v4"
12 "gopkg.in/src-d/go-git.v4/plumbing"
13 "gopkg.in/src-d/go-git.v4/plumbing/storer"
14
15 "github.com/p9c/p9/version"
16 )
17
18 var (
19 URL string
20 GitRef string
21 GitCommit string
22 BuildTime string
23 Tag string
24 Major, Minor, Patch int
25 Meta string
26 PathBase string
27 )
28
29 func main() {
30 I.Ln(version.Get())
31 BuildTime = time.Now().Format(time.RFC3339)
32 var cwd string
33 var e error
34 if cwd, e = os.Getwd(); E.Chk(e) {
35 return
36 }
37 cwd = filepath.Dir(cwd)
38 // I.Ln(cwd)
39 var repo *git.Repository
40 if repo, e = git.PlainOpen(cwd); E.Chk(e) {
41 return
42 }
43 var rr []*git.Remote
44 if rr, e = repo.Remotes(); E.Chk(e) {
45 return
46 }
47 for i := range rr {
48 rs := rr[i].String()
49 if strings.HasPrefix(rs, "origin") {
50 rss := strings.Split(rs, "git@")
51 if len(rss) > 1 {
52 rsss := strings.Split(rss[1], ".git")
53 URL = strings.ReplaceAll(rsss[0], ":", "/")
54 break
55 }
56 rss = strings.Split(rs, "https://")
57 if len(rss) > 1 {
58 rsss := strings.Split(rss[1], ".git")
59 URL = rsss[0]
60 break
61 }
62
63 }
64 }
65 var tr *git.Worktree
66 if tr, e = repo.Worktree(); E.Chk(e) {
67 }
68 var rh *plumbing.Reference
69 if rh, e = repo.Head(); E.Chk(e) {
70 return
71 }
72 rhs := rh.Strings()
73 GitRef = rhs[0]
74 GitCommit = rhs[1]
75 var rt storer.ReferenceIter
76 if rt, e = repo.Tags(); E.Chk(e) {
77 return
78 }
79 var maxVersion int
80 var maxString string
81 var maxIs bool
82 if e = rt.ForEach(
83 func(pr *plumbing.Reference) (e error) {
84 s := strings.Split(pr.String(), "/")
85 prs := s[2]
86 if strings.HasPrefix(prs, "v") {
87 var va [3]int
88 var meta string
89 _, _ = fmt.Sscanf(prs, "v%d.%d.%d%s", &va[0], &va[1], &va[2], &meta)
90 vn := va[0]*1000000 + va[1]*1000 + va[2]
91 if maxVersion < vn {
92 maxVersion = vn
93 maxString = prs
94 Major = va[0]
95 Minor = va[1]
96 Patch = va[2]
97 Meta = meta
98 }
99 if pr.Hash() == rh.Hash() {
100 maxIs = true
101 return
102 }
103 }
104 return
105 },
106 ); E.Chk(e) {
107 return
108 }
109 if !maxIs {
110 maxString += "+"
111 }
112 Tag = maxString
113 PathBase = tr.Filesystem.Root() + "/"
114 // I.Ln(PathBase)
115 versionFile := `package version
116
117 `+`//go:generate go run ./update/.
118
119 import (
120 "fmt"
121 )
122
123 var (
124
125 // URL is the git URL for the repository
126 URL = "%s"
127 // GitRef is the gitref, as in refs/heads/branchname
128 GitRef = "%s"
129 // GitCommit is the commit hash of the current HEAD
130 GitCommit = "%s"
131 // BuildTime stores the time when the current binary was built
132 BuildTime = "%s"
133 // Tag lists the Tag on the build, adding a + to the newest Tag if the commit is
134 // not that commit
135 Tag = "%s"
136 // PathBase is the path base returned from runtime caller
137 PathBase = "%s"
138 // Major is the major number from the tag
139 Major = %d
140 // Minor is the minor number from the tag
141 Minor = %d
142 // Patch is the patch version number from the tag
143 Patch = %d
144 // Meta is the extra arbitrary string field from Semver spec
145 Meta = "%s"
146 )
147
148 // Get returns a pretty printed version information string
149 func Get() string {
150 return fmt.Sprint(
151 "\nRepository Information\n"+
152 "\tGit repository: "+URL+"\n",
153 "\tBranch: "+GitRef+"\n"+
154 "\tCommit: "+GitCommit+"\n"+
155 "\tBuilt: "+BuildTime+"\n"+
156 "\tTag: "+Tag+"\n",
157 "\tMajor:", Major, "\n",
158 "\tMinor:", Minor, "\n",
159 "\tPatch:", Patch, "\n",
160 "\tMeta: ", Meta, "\n",
161 )
162 }
163 `
164 versionFileOut := fmt.Sprintf(
165 versionFile,
166 URL,
167 GitRef,
168 GitCommit,
169 BuildTime,
170 Tag,
171 PathBase,
172 Major,
173 Minor,
174 Patch,
175 Meta,
176 )
177 path := filepath.Join(filepath.Join(PathBase, "version"), "version.go")
178 if e = ioutil.WriteFile(path, []byte(versionFileOut), 0666); E.Chk(e) {
179 }
180 // I.Ln("updated version.go written")
181 return
182 }
183