Skip to content

Commit 13a8a58

Browse files
committed
allow setting user agent products
Signed-off-by: CrazyMax <[email protected]>
1 parent fe5efe0 commit 13a8a58

File tree

3 files changed

+99
-28
lines changed

3 files changed

+99
-28
lines changed

version/ua.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package version
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
"strings"
7+
"sync"
8+
)
9+
10+
var (
11+
reRelease *regexp.Regexp
12+
reDev *regexp.Regexp
13+
reOnce sync.Once
14+
uapCbs map[string]func() string
15+
)
16+
17+
func UserAgent() string {
18+
uaVersion := defaultVersion
19+
20+
reOnce.Do(func() {
21+
reRelease = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+$`)
22+
reDev = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+`)
23+
})
24+
25+
if matches := reRelease.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
26+
uaVersion = matches[0][1]
27+
} else if matches := reDev.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
28+
uaVersion = matches[0][1] + "-dev"
29+
}
30+
31+
res := &strings.Builder{}
32+
fmt.Fprintf(res, "buildkit/%s", uaVersion)
33+
for pname, pver := range uapCbs {
34+
fmt.Fprintf(res, " %s/%s", pname, pver())
35+
}
36+
37+
return res.String()
38+
}
39+
40+
// SetUserAgentProduct sets a callback to get the version of a product to be
41+
// included in the User-Agent header. The callback is called every time the
42+
// User-Agent header is generated. Caller must ensure that the callback is
43+
// cached if it is expensive to compute.
44+
func SetUserAgentProduct(name string, cb func() (version string)) {
45+
if uapCbs == nil {
46+
uapCbs = make(map[string]func() string)
47+
}
48+
uapCbs[name] = cb
49+
}

version/ua_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package version
2+
3+
import "testing"
4+
5+
func TestUserAgent(t *testing.T) {
6+
cases := []struct {
7+
name string
8+
version string
9+
products map[string]string
10+
want string
11+
}{
12+
{
13+
name: "dev",
14+
version: defaultVersion,
15+
want: "buildkit/v0.0-dev",
16+
},
17+
{
18+
name: "unknown",
19+
version: "0.0.0+unknown",
20+
want: "buildkit/v0.0.0+unknown",
21+
},
22+
{
23+
name: "release",
24+
version: "v0.11.6",
25+
want: "buildkit/v0.11",
26+
},
27+
{
28+
name: "product",
29+
version: "v0.11.6",
30+
products: map[string]string{
31+
"moby": "v24.0",
32+
},
33+
want: "buildkit/v0.11 moby/v24.0",
34+
},
35+
}
36+
for _, tt := range cases {
37+
tt := tt
38+
t.Run(tt.name, func(t *testing.T) {
39+
Version = tt.version
40+
for pname, pver := range tt.products {
41+
SetUserAgentProduct(pname, func() string {
42+
return pver
43+
})
44+
}
45+
if g, w := UserAgent(), tt.want; g != w {
46+
t.Fatalf("got: %q\nwant: %q", g, w)
47+
}
48+
})
49+
}
50+
}

version/version.go

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,6 @@
1717

1818
package version
1919

20-
import (
21-
"regexp"
22-
"sync"
23-
)
24-
2520
const (
2621
defaultVersion = "v0.0.0+unknown"
2722
)
@@ -37,26 +32,3 @@ var (
3732
// the program at linking time.
3833
Revision = ""
3934
)
40-
41-
var (
42-
reRelease *regexp.Regexp
43-
reDev *regexp.Regexp
44-
reOnce sync.Once
45-
)
46-
47-
func UserAgent() string {
48-
uaVersion := defaultVersion
49-
50-
reOnce.Do(func() {
51-
reRelease = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+$`)
52-
reDev = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+`)
53-
})
54-
55-
if matches := reRelease.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
56-
uaVersion = matches[0][1]
57-
} else if matches := reDev.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
58-
uaVersion = matches[0][1] + "-dev"
59-
}
60-
61-
return "buildkit/" + uaVersion
62-
}

0 commit comments

Comments
 (0)