Skip to content

Commit

Permalink
allow setting user agent products
Browse files Browse the repository at this point in the history
Signed-off-by: CrazyMax <[email protected]>
  • Loading branch information
crazy-max committed Apr 27, 2023
1 parent fe5efe0 commit 13a8a58
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 28 deletions.
49 changes: 49 additions & 0 deletions version/ua.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package version

import (
"fmt"
"regexp"
"strings"
"sync"
)

var (
reRelease *regexp.Regexp
reDev *regexp.Regexp
reOnce sync.Once
uapCbs map[string]func() string
)

func UserAgent() string {
uaVersion := defaultVersion

reOnce.Do(func() {
reRelease = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+$`)
reDev = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+`)
})

if matches := reRelease.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
uaVersion = matches[0][1]
} else if matches := reDev.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
uaVersion = matches[0][1] + "-dev"
}

res := &strings.Builder{}
fmt.Fprintf(res, "buildkit/%s", uaVersion)
for pname, pver := range uapCbs {
fmt.Fprintf(res, " %s/%s", pname, pver())
}

return res.String()
}

// SetUserAgentProduct sets a callback to get the version of a product to be
// included in the User-Agent header. The callback is called every time the
// User-Agent header is generated. Caller must ensure that the callback is
// cached if it is expensive to compute.
func SetUserAgentProduct(name string, cb func() (version string)) {
if uapCbs == nil {
uapCbs = make(map[string]func() string)
}
uapCbs[name] = cb
}
50 changes: 50 additions & 0 deletions version/ua_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package version

import "testing"

func TestUserAgent(t *testing.T) {
cases := []struct {
name string
version string
products map[string]string
want string
}{
{
name: "dev",
version: defaultVersion,
want: "buildkit/v0.0-dev",
},
{
name: "unknown",
version: "0.0.0+unknown",
want: "buildkit/v0.0.0+unknown",
},
{
name: "release",
version: "v0.11.6",
want: "buildkit/v0.11",
},
{
name: "product",
version: "v0.11.6",
products: map[string]string{
"moby": "v24.0",
},
want: "buildkit/v0.11 moby/v24.0",
},
}
for _, tt := range cases {
tt := tt
t.Run(tt.name, func(t *testing.T) {
Version = tt.version
for pname, pver := range tt.products {
SetUserAgentProduct(pname, func() string {
return pver
})
}
if g, w := UserAgent(), tt.want; g != w {
t.Fatalf("got: %q\nwant: %q", g, w)
}
})
}
}
28 changes: 0 additions & 28 deletions version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@

package version

import (
"regexp"
"sync"
)

const (
defaultVersion = "v0.0.0+unknown"
)
Expand All @@ -37,26 +32,3 @@ var (
// the program at linking time.
Revision = ""
)

var (
reRelease *regexp.Regexp
reDev *regexp.Regexp
reOnce sync.Once
)

func UserAgent() string {
uaVersion := defaultVersion

reOnce.Do(func() {
reRelease = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+$`)
reDev = regexp.MustCompile(`^(v[0-9]+\.[0-9]+)\.[0-9]+`)
})

if matches := reRelease.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
uaVersion = matches[0][1]
} else if matches := reDev.FindAllStringSubmatch(Version, 1); len(matches) > 0 {
uaVersion = matches[0][1] + "-dev"
}

return "buildkit/" + uaVersion
}

0 comments on commit 13a8a58

Please sign in to comment.