Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package gh for openSUSE:Factory checked in at 2022-09-22 18:21:12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/gh (Old) and /work/SRC/openSUSE:Factory/.gh.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "gh" Thu Sep 22 18:21:12 2022 rev:22 rq:1005419 version:2.14.2 Changes: -------- --- /work/SRC/openSUSE:Factory/gh/gh.changes 2022-07-14 16:34:41.920652688 +0200 +++ /work/SRC/openSUSE:Factory/.gh.new.2275/gh.changes 2022-09-22 18:21:13.353843169 +0200 @@ -1,0 +2,9 @@ +Wed Sep 07 13:52:22 UTC 2022 - ka...@b1-systems.de + +- Update to version 2.14.2: + * Remove accidental caching from `repo list` and other commands + * strip whitespace when adding topics + * Set blank headers so they are not automatically resolved by go-gh (#5935) + * Post go-gh integration cleanup (#5933) + +------------------------------------------------------------------- Old: ---- cli-2.14.1.tar.gz New: ---- cli-2.14.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ gh.spec ++++++ --- /var/tmp/diff_new_pack.8rjgi6/_old 2022-09-22 18:21:14.225844530 +0200 +++ /var/tmp/diff_new_pack.8rjgi6/_new 2022-09-22 18:21:14.229844537 +0200 @@ -19,7 +19,7 @@ %define goflags "-buildmode=pie -trimpath -mod=vendor -modcacherw" %define sname cli Name: gh -Version: 2.14.1 +Version: 2.14.2 Release: 0 Summary: The official CLI for GitHub License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.8rjgi6/_old 2022-09-22 18:21:14.273844606 +0200 +++ /var/tmp/diff_new_pack.8rjgi6/_new 2022-09-22 18:21:14.277844612 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/cli/cli</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v2.14.1</param> + <param name="revision">v2.14.2</param> <param name="versionformat">@PARENT_TAG@</param> <param name="changesgenerate">enable</param> <param name="versionrewrite-pattern">v(.*)</param> @@ -16,7 +16,7 @@ <param name="compression">gz</param> </service> <service name="go_modules" mode="disabled"> - <param name="archive">cli-2.14.1.tar.gz</param> + <param name="archive">cli-2.14.2.tar.gz</param> </service> </services> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.8rjgi6/_old 2022-09-22 18:21:14.301844649 +0200 +++ /var/tmp/diff_new_pack.8rjgi6/_new 2022-09-22 18:21:14.305844655 +0200 @@ -1,5 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/cli/cli</param> - <param name="changesrevision">1e8cb9c1b2ec0ee6c2ba0f970286a8c7c3431328</param></service></servicedata> + <param name="changesrevision">c22a85e2b56696b50dd08efd4ecf5ac668db365c</param></service></servicedata> +(No newline at EOF) ++++++ cli-2.14.1.tar.gz -> cli-2.14.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/api/client.go new/cli-2.14.2/api/client.go --- old/cli-2.14.1/api/client.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/api/client.go 2022-07-14 19:17:23.000000000 +0200 @@ -14,6 +14,17 @@ ghAPI "github.com/cli/go-gh/pkg/api" ) +const ( + accept = "Accept" + authorization = "Authorization" + cacheTTL = "X-GH-CACHE-TTL" + contentType = "Content-Type" + graphqlFeatures = "GraphQL-Features" + mergeQueue = "merge_queue" + timeZone = "Time-Zone" + userAgent = "User-Agent" +) + var linkRE = regexp.MustCompile(`<([^>]+)>;\s*rel="([^"]+)"`) func NewClientFromHTTP(httpClient *http.Client) *Client { @@ -45,9 +56,8 @@ // GraphQL performs a GraphQL request and parses the response. If there are errors in the response, // GraphQLError will be returned, but the data will also be parsed into the receiver. func (c Client) GraphQL(hostname string, query string, variables map[string]interface{}, data interface{}) error { - // AuthToken is being handled by Transport, so let go-gh know that it does not need to resolve it. - opts := ghAPI.ClientOptions{Host: hostname, AuthToken: "none", Transport: c.http.Transport} - opts.Headers = map[string]string{"GraphQL-Features": "merge_queue"} + opts := clientOptions(hostname, c.http.Transport) + opts.Headers[graphqlFeatures] = mergeQueue gqlClient, err := gh.GQLClient(&opts) if err != nil { return err @@ -58,8 +68,7 @@ // GraphQL performs a GraphQL mutation and parses the response. If there are errors in the response, // GraphQLError will be returned, but the data will also be parsed into the receiver. func (c Client) Mutate(hostname, name string, mutation interface{}, variables map[string]interface{}) error { - // AuthToken is being handled by Transport, so let go-gh know that it does not need to resolve it. - opts := ghAPI.ClientOptions{Host: hostname, AuthToken: "none", Transport: c.http.Transport} + opts := clientOptions(hostname, c.http.Transport) gqlClient, err := gh.GQLClient(&opts) if err != nil { return err @@ -70,8 +79,7 @@ // GraphQL performs a GraphQL query and parses the response. If there are errors in the response, // GraphQLError will be returned, but the data will also be parsed into the receiver. func (c Client) Query(hostname, name string, query interface{}, variables map[string]interface{}) error { - // AuthToken is being handled by Transport, so let go-gh know that it does not need to resolve it. - opts := ghAPI.ClientOptions{Host: hostname, AuthToken: "none", Transport: c.http.Transport} + opts := clientOptions(hostname, c.http.Transport) gqlClient, err := gh.GQLClient(&opts) if err != nil { return err @@ -81,8 +89,7 @@ // REST performs a REST request and parses the response. func (c Client) REST(hostname string, method string, p string, body io.Reader, data interface{}) error { - // AuthToken is being handled by Transport, so let go-gh know that it does not need to resolve it. - opts := ghAPI.ClientOptions{Host: hostname, AuthToken: "none", Transport: c.http.Transport} + opts := clientOptions(hostname, c.http.Transport) restClient, err := gh.RESTClient(&opts) if err != nil { return err @@ -91,8 +98,7 @@ } func (c Client) RESTWithNext(hostname string, method string, p string, body io.Reader, data interface{}) (string, error) { - // AuthToken is being handled by Transport, so let go-gh know that it does not need to resolve it. - opts := ghAPI.ClientOptions{Host: hostname, AuthToken: "none", Transport: c.http.Transport} + opts := clientOptions(hostname, c.http.Transport) restClient, err := gh.RESTClient(&opts) if err != nil { return "", err @@ -237,3 +243,22 @@ return "" } + +func clientOptions(hostname string, transport http.RoundTripper) ghAPI.ClientOptions { + // AuthToken, and Headers are being handled by transport, + // so let go-gh know that it does not need to resolve them. + opts := ghAPI.ClientOptions{ + AuthToken: "none", + // Blank values for Accept, Authorization, Content-Type, Time-Zone, and User-Agent headers. + Headers: map[string]string{ + accept: "", + authorization: "", + contentType: "", + timeZone: "", + userAgent: "", + }, + Host: hostname, + Transport: transport, + } + return opts +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/api/client_test.go new/cli-2.14.2/api/client_test.go --- old/cli-2.14.1/api/client_test.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/api/client_test.go 2022-07-14 19:17:23.000000000 +0200 @@ -5,9 +5,11 @@ "errors" "io" "net/http" + "net/http/httptest" "testing" "github.com/cli/cli/v2/pkg/httpmock" + "github.com/cli/cli/v2/pkg/iostreams" "github.com/stretchr/testify/assert" ) @@ -221,3 +223,36 @@ }) } } + +func TestHTTPHeaders(t *testing.T) { + var gotReq *http.Request + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotReq = r + w.WriteHeader(http.StatusNoContent) + })) + defer ts.Close() + + ios, _, _, stderr := iostreams.Test() + httpClient, err := NewHTTPClient(HTTPClientOptions{ + AppVersion: "v1.2.3", + Config: tinyConfig{ts.URL[7:] + ":oauth_token": "MYTOKEN"}, + Log: ios.ErrOut, + SkipAcceptHeaders: false, + }) + assert.NoError(t, err) + client := NewClientFromHTTP(httpClient) + + err = client.REST(ts.URL, "GET", ts.URL+"/user/repos", nil, nil) + assert.NoError(t, err) + + wantHeader := map[string]string{ + "Accept": "application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview", + "Authorization": "token MYTOKEN", + "Content-Type": "application/json; charset=utf-8", + "User-Agent": "GitHub CLI v1.2.3", + } + for name, value := range wantHeader { + assert.Equal(t, value, gotReq.Header.Get(name), name) + } + assert.Equal(t, "", stderr.String()) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/api/http_client.go new/cli-2.14.2/api/http_client.go --- old/cli-2.14.1/api/http_client.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/api/http_client.go 2022-07-14 19:17:23.000000000 +0200 @@ -12,15 +12,14 @@ ghAPI "github.com/cli/go-gh/pkg/api" ) -type configGetter interface { - Get(string, string) (string, error) +type tokenGetter interface { AuthToken(string) (string, string) } type HTTPClientOptions struct { AppVersion string CacheTTL time.Duration - Config configGetter + Config tokenGetter EnableCache bool Log io.Writer SkipAcceptHeaders bool @@ -36,10 +35,10 @@ } headers := map[string]string{ - "User-Agent": fmt.Sprintf("GitHub CLI %s", opts.AppVersion), + userAgent: fmt.Sprintf("GitHub CLI %s", opts.AppVersion), } if opts.SkipAcceptHeaders { - headers["Accept"] = "" + headers[accept] = "" } clientOpts.Headers = headers @@ -61,25 +60,32 @@ } func NewCachedHTTPClient(httpClient *http.Client, ttl time.Duration) *http.Client { - httpClient.Transport = AddCacheTTLHeader(httpClient.Transport, ttl) - return httpClient + newClient := *httpClient + newClient.Transport = AddCacheTTLHeader(httpClient.Transport, ttl) + return &newClient } // AddCacheTTLHeader adds an header to the request telling the cache that the request // should be cached for a specified amount of time. func AddCacheTTLHeader(rt http.RoundTripper, ttl time.Duration) http.RoundTripper { return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) { - req.Header.Set("X-GH-CACHE-TTL", ttl.String()) + // If the header is already set in the request, don't overwrite it. + if req.Header.Get(cacheTTL) == "" { + req.Header.Set(cacheTTL, ttl.String()) + } return rt.RoundTrip(req) }} } // AddAuthToken adds an authentication token header for the host specified by the request. -func AddAuthTokenHeader(rt http.RoundTripper, cfg configGetter) http.RoundTripper { +func AddAuthTokenHeader(rt http.RoundTripper, cfg tokenGetter) http.RoundTripper { return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) { - hostname := ghinstance.NormalizeHostname(getHost(req)) - if token, _ := cfg.AuthToken(hostname); token != "" { - req.Header.Set("Authorization", fmt.Sprintf("token %s", token)) + // If the header is already set in the request, don't overwrite it. + if req.Header.Get(authorization) == "" { + hostname := ghinstance.NormalizeHostname(getHost(req)) + if token, _ := cfg.AuthToken(hostname); token != "" { + req.Header.Set(authorization, fmt.Sprintf("token %s", token)) + } } return rt.RoundTrip(req) }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/api/http_client_test.go new/cli-2.14.2/api/http_client_test.go --- old/cli-2.14.1/api/http_client_test.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/api/http_client_test.go 2022-07-14 19:17:23.000000000 +0200 @@ -16,7 +16,7 @@ func TestNewHTTPClient(t *testing.T) { type args struct { - config configGetter + config tokenGetter appVersion string setAccept bool } @@ -207,10 +207,6 @@ type tinyConfig map[string]string -func (c tinyConfig) Get(host, key string) (string, error) { - return c[fmt.Sprintf("%s:%s", host, key)], nil -} - func (c tinyConfig) AuthToken(host string) (string, string) { return c[fmt.Sprintf("%s:%s", host, "oauth_token")], "oauth_token" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/cmd/gh/main.go new/cli-2.14.2/cmd/gh/main.go --- old/cli-2.14.1/cmd/gh/main.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/cmd/gh/main.go 2022-07-14 19:17:23.000000000 +0200 @@ -98,9 +98,6 @@ return exitError } - host, _ := cfg.DefaultHost() - ghrepo.SetDefaultHost(host) - expandedArgs := []string{} if len(os.Args) > 0 { expandedArgs = os.Args[1:] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/internal/authflow/flow.go new/cli-2.14.2/internal/authflow/flow.go --- old/cli-2.14.1/internal/authflow/flow.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/internal/authflow/flow.go 2022-07-14 19:17:23.000000000 +0200 @@ -141,12 +141,8 @@ authToken string } -func (c cfg) Get(_, _ string) (string, error) { - return "", nil -} - -func (c cfg) AuthToken(_ string) (string, string) { - return c.authToken, "" +func (c cfg) AuthToken(hostname string) (string, string) { + return c.authToken, "oauth_token" } func getViewer(hostname, token string) (string, error) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/internal/ghrepo/repo.go new/cli-2.14.2/internal/ghrepo/repo.go --- old/cli-2.14.1/internal/ghrepo/repo.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/internal/ghrepo/repo.go 2022-07-14 19:17:23.000000000 +0200 @@ -6,6 +6,7 @@ "strings" "github.com/cli/cli/v2/internal/ghinstance" + ghAuth "github.com/cli/go-gh/pkg/auth" "github.com/cli/go-gh/pkg/repository" ) @@ -35,19 +36,9 @@ return fmt.Sprintf("%s/%s", r.RepoOwner(), r.RepoName()) } -var defaultHostOverride string - func defaultHost() string { - if defaultHostOverride != "" { - return defaultHostOverride - } - return ghinstance.Default() -} - -// SetDefaultHost overrides the default GitHub hostname for FromFullName. -// TODO: remove after FromFullName approach is revisited -func SetDefaultHost(host string) { - defaultHostOverride = host + host, _ := ghAuth.DefaultHost() + return host } // FromFullName extracts the GitHub repository information from the following diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/internal/ghrepo/repo_test.go new/cli-2.14.2/internal/ghrepo/repo_test.go --- old/cli-2.14.1/internal/ghrepo/repo_test.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/internal/ghrepo/repo_test.go 2022-07-14 19:17:23.000000000 +0200 @@ -4,6 +4,7 @@ "errors" "fmt" "net/url" + "os" "testing" ) @@ -194,7 +195,9 @@ for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if tt.hostOverride != "" { - SetDefaultHost(tt.hostOverride) + old := os.Getenv("GH_HOST") + os.Setenv("GH_HOST", tt.hostOverride) + defer os.Setenv("GH_HOST", old) } r, err := FromFullName(tt.input) if tt.wantErr != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/pkg/cmd/repo/edit/edit.go new/cli-2.14.2/pkg/cmd/repo/edit/edit.go --- old/cli-2.14.1/pkg/cmd/repo/edit/edit.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/pkg/cmd/repo/edit/edit.go 2022-07-14 19:17:23.000000000 +0200 @@ -326,7 +326,7 @@ return err } if len(strings.TrimSpace(addTopics)) > 0 { - opts.AddTopics = strings.Split(addTopics, ",") + opts.AddTopics = parseTopics(addTopics) } if len(opts.topicsCache) > 0 { @@ -454,6 +454,14 @@ return nil } +func parseTopics(s string) []string { + topics := strings.Split(s, ",") + for i, topic := range topics { + topics[i] = strings.TrimSpace(topic) + } + return topics +} + func getTopics(ctx context.Context, httpClient *http.Client, repo ghrepo.Interface) ([]string, error) { apiPath := fmt.Sprintf("repos/%s/%s/topics", repo.RepoOwner(), repo.RepoName()) req, err := http.NewRequestWithContext(ctx, "GET", ghinstance.RESTPrefix(repo.RepoHost())+apiPath, nil) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cli-2.14.1/pkg/cmd/repo/edit/edit_test.go new/cli-2.14.2/pkg/cmd/repo/edit/edit_test.go --- old/cli-2.14.1/pkg/cmd/repo/edit/edit_test.go 2022-07-12 15:46:35.000000000 +0200 +++ new/cli-2.14.2/pkg/cmd/repo/edit/edit_test.go 2022-07-14 19:17:23.000000000 +0200 @@ -215,7 +215,7 @@ askStubs: func(as *prompt.AskStubber) { as.StubPrompt("What do you want to edit?").AnswerWith([]string{"Description", "Topics"}) as.StubPrompt("Description of the repository").AnswerWith("awesome repo description") - as.StubPrompt("Add topics?(csv format)").AnswerWith("a,b,c,d") + as.StubPrompt("Add topics?(csv format)").AnswerWith("a, b,c,d ") as.StubPrompt("Remove Topics").AnswerWith([]string{"x"}) }, httpStubs: func(t *testing.T, reg *httpmock.Registry) { ++++++ vendor.tar.gz ++++++