Send versioned User-Agent (entire-cli/{version}) · Entire

Send versioned User-Agent (entire-cli/{version})

0847cb9→main·

toothbrush·3w ago·7 files·+27 added/-13 removed

Route every outbound User-Agent through versioninfo.UserAgent(), which returns "entire-cli/" using the already-resolved build version. Previously the api client, search, and the stable-version check sent a bare "entire-cli".

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

Sessions

0b56179691eeView transcript

Changes

7

8 unmodified lines
9
10
11
12
13
14
15
16
17
16
18
19
20
59 unmodified lines
80
81
82
82
83
84
85
86

8 unmodified lines
    
    "io"
    "net/http"
    "strings"

"github.com/entireio/cli/cmd/entire/cli/versioninfo"
)

const (
    maxResponseBytes = 16 << 20
    userAgent        = "entire-cli"
)

// Client is an authenticated HTTP client for the Entire API.
59 unmodified lines

if t.token != "" {
        r.Header.Set("Authorization", "Bearer "+t.token)
    }
    r.Header.Set("User-Agent", userAgent)
    r.Header.Set("User-Agent", versioninfo.UserAgent())
    if r.Header.Get("Accept") == "" {
        r.Header.Set("Accept", "application/json")
    }

Mcmd/entire/cli/api/client.go+3/-2

7 unmodified lines

8
9
10
11
12
13
14
15
33 unmodified lines

49
50
51
50
51
52
53
54
55
56
32 unmodified lines

89
90
91
90
91
92
93
94
95
96

7 unmodified lines

"net/http/httptest"
    "strings"
    "testing"

"github.com/entireio/cli/cmd/entire/cli/versioninfo"

const testBearerHeader = "Bearer tok"
33 unmodified lines

if gotAuth != "Bearer test-token-123" {
        t.Errorf("Authorization = %q, want %q", gotAuth, "Bearer test-token-123")
    }
    if gotUA != "entire-cli" {
        t.Errorf("User-Agent = %q, want %q", gotUA, "entire-cli")
    }
    if want := versioninfo.UserAgent(); gotUA != want {
        t.Errorf("User-Agent = %q, want %q", gotUA, want)
    }
    if gotAccept != "application/json" {
        t.Errorf("Accept = %q, want %q", gotAccept, "application/json")
    }

Mcmd/entire/cli/api/client_test.go+6/-4

10 unmodified lines

11
12
13
14
15
16
17
18
573 unmodified lines

592
593
594
593
595
596
597
598

10 unmodified lines

"strconv"
    "strings"
    "time"

"github.com/entireio/cli/cmd/entire/cli/versioninfo"

const apiTimeout = 30 * time.Second
573 unmodified lines

return nil, fmt.Errorf("creating request: %w", err)
    }
    req.Header.Set("Authorization", "Bearer "+cfg.GitHubToken)
    req.Header.Set("User-Agent", "entire-cli")
    req.Header.Set("User-Agent", versioninfo.UserAgent())

resp, err := httpClient.Do(req)
    if err != nil {

Mcmd/entire/cli/search/search.go+3/-1

6 unmodified lines

7
8
9
10
11
12
13
14
160 unmodified lines

175
176
177
176
177
178
179
180
181
182

6 unmodified lines

"net/http/httptest"
    "strings"
    "testing"

"github.com/entireio/cli/cmd/entire/cli/versioninfo"

const testOwner = "entirehq"
160 unmodified lines

if capturedReq.Header.Get("Authorization") != "Bearer ghp_test123" {
        t.Errorf("auth header = %s, want 'Bearer ghp_test123'", capturedReq.Header.Get("Authorization"))
    }
    if capturedReq.Header.Get("User-Agent") != "entire-cli" {
        t.Errorf("user-agent = %s, want 'entire-cli'", capturedReq.Header.Get("User-Agent"))
    if want := versioninfo.UserAgent(); capturedReq.Header.Get("User-Agent") != want {
        t.Errorf("user-agent = %s, want %q", capturedReq.Header.Get("User-Agent"), want)
    }
}

Mcmd/entire/cli/search/search_test.go+4/-2

184 unmodified lines

185
186
187
188
188
189
190
191
37 unmodified lines

229
230
231
232
232
233
234
235

184 unmodified lines

}

req.Header.Set("Accept", "application/vnd.github+json")
    req.Header.Set("User-Agent", "entire-cli")
    req.Header.Set("User-Agent", versioninfo.UserAgent());

client := &http.Client{}
    resp, err := client.Do(req)
37 unmodified lines

}

req.Header.Set("Accept", "application/vnd.github+json")
    req.Header.Set("User-Agent", "entire-cli/"+versioninfo.Version)
    req.Header.Set("User-Agent", versioninfo.UserAgent());

client := &http.Client{}
    resp, err := client.Do(req)

Mcmd/entire/cli/versioncheck/versioncheck.go+2/-2

13 unmodified lines

14
15
16
17
18
19
20
228 unmodified lines

249
250
251
251
252
252
253
254
255
256

13 unmodified lines

"testing"
    "time"

"github.com/entireio/cli/cmd/entire/cli/versioninfo"
    "github.com/spf13/cobra"

228 unmodified lines

if r.Header.Get("Accept") != "application/vnd.github+json" {
            t.Errorf("Accept header = %q, want application/vnd.github+json", r.Header.Get("Accept"))
        }
        if r.Header.Get("User-Agent") != "entire-cli" {
            t.Errorf("User-Agent header = %q, want entire-cli", r.Header.Get("User-Agent"))
        if want := versioninfo.UserAgent(); r.Header.Get("User-Agent") != want {
            t.Errorf("User-Agent header = %q, want %q", r.Header.Get("User-Agent"), want)
        }

release := GitHubRelease{

Mcmd/entire/cli/versioncheck/versioncheck_test.go+3/-2

17 unmodified lines

18
19
20
21
22
23
24
25
26
27
28
29

17 unmodified lines

Commit  = "unknown"
)

// UserAgent is the HTTP User-Agent the CLI sends on outbound requests:
// "entire-cli/<version>". Call after Load() so the version is resolved.
func UserAgent() string {
    return "entire-cli/" + Version
}

// Load fills Version and Commit from the binary's build info when ldflags left
// them at their defaults. Call once from main() before either is read.
func Load() {