Skip to content

Commit b9c8d8e

Browse files
authored
Merge branch 'trunk' into issue-close-duplicate-of
2 parents 2265820 + d6d0cb7 commit b9c8d8e

60 files changed

Lines changed: 1481 additions & 216 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deployment.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ jobs:
5050
with:
5151
go-version-file: 'go.mod'
5252
- name: Install GoReleaser
53-
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
53+
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
5454
with:
5555
# The version is pinned not only for security purposes, but also to avoid breaking
5656
# our scripts, which rely on the specific file names generated by GoReleaser.
@@ -70,7 +70,7 @@ jobs:
7070
run: |
7171
go run ./cmd/gen-docs --website --doc-path dist/manual
7272
tar -czvf dist/manual.tar.gz -C dist -- manual
73-
- uses: actions/upload-artifact@v6
73+
- uses: actions/upload-artifact@v7
7474
with:
7575
name: linux
7676
if-no-files-found: error
@@ -111,7 +111,7 @@ jobs:
111111
security set-key-partition-list -S "apple-tool:,apple:,codesign:" -s -k "$keychain_password" "$keychain"
112112
rm "$RUNNER_TEMP/cert.p12"
113113
- name: Install GoReleaser
114-
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
114+
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
115115
with:
116116
# The version is pinned not only for security purposes, but also to avoid breaking
117117
# our scripts, which rely on the specific file names generated by GoReleaser.
@@ -150,7 +150,7 @@ jobs:
150150
run: |
151151
shopt -s failglob
152152
script/pkgmacos "$TAG_NAME"
153-
- uses: actions/upload-artifact@v6
153+
- uses: actions/upload-artifact@v7
154154
with:
155155
name: macos
156156
if-no-files-found: error
@@ -173,7 +173,7 @@ jobs:
173173
with:
174174
go-version-file: 'go.mod'
175175
- name: Install GoReleaser
176-
uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0
176+
uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 # v7.0.0
177177
with:
178178
# The version is pinned not only for security purposes, but also to avoid breaking
179179
# our scripts, which rely on the specific file names generated by GoReleaser.
@@ -263,7 +263,7 @@ jobs:
263263
Get-ChildItem -Path .\dist -Filter *.msi | ForEach-Object {
264264
.\script\sign.ps1 $_.FullName
265265
}
266-
- uses: actions/upload-artifact@v6
266+
- uses: actions/upload-artifact@v7
267267
with:
268268
name: windows
269269
if-no-files-found: error
@@ -281,7 +281,7 @@ jobs:
281281
- name: Checkout cli/cli
282282
uses: actions/checkout@v6
283283
- name: Merge built artifacts
284-
uses: actions/download-artifact@v7
284+
uses: actions/download-artifact@v8
285285
- name: Checkout documentation site
286286
uses: actions/checkout@v6
287287
with:
@@ -334,7 +334,7 @@ jobs:
334334
rpmsign --addsign dist/*.rpm
335335
- name: Attest release artifacts
336336
if: inputs.environment == 'production'
337-
uses: actions/attest-build-provenance@96278af6caaf10aea03fd8d33a09a777ca52d62f # v3.2.0
337+
uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0
338338
with:
339339
subject-path: "dist/gh_*"
340340
create-storage-record: false # (default: true)

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
# Windows resource files
1919
/cmd/gh/*.syso
2020

21+
# Third-party licenses
22+
/internal/licenses/embed/*/*
23+
!/internal/licenses/embed/*/PLACEHOLDER
24+
2125
# VS Code
2226
.vscode
2327

api/client.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"regexp"
1111
"strings"
1212

13+
"github.com/cli/cli/v2/pkg/set"
1314
ghAPI "github.com/cli/go-gh/v2/pkg/api"
1415
ghauth "github.com/cli/go-gh/v2/pkg/auth"
1516
)
@@ -180,6 +181,10 @@ func handleResponse(err error) error {
180181

181182
var gqlErr *ghAPI.GraphQLError
182183
if errors.As(err, &gqlErr) {
184+
scopeErr := GenerateScopeErrorForGQL(gqlErr)
185+
if scopeErr != nil {
186+
return scopeErr
187+
}
183188
return GraphQLError{
184189
GraphQLError: gqlErr,
185190
}
@@ -188,6 +193,40 @@ func handleResponse(err error) error {
188193
return err
189194
}
190195

196+
func GenerateScopeErrorForGQL(gqlErr *ghAPI.GraphQLError) error {
197+
missing := set.NewStringSet()
198+
for _, e := range gqlErr.Errors {
199+
if e.Type != "INSUFFICIENT_SCOPES" {
200+
continue
201+
}
202+
missing.AddValues(requiredScopesFromServerMessage(e.Message))
203+
}
204+
if missing.Len() > 0 {
205+
s := missing.ToSlice()
206+
// TODO: this duplicates parts of generateScopesSuggestion
207+
return fmt.Errorf(
208+
"error: your authentication token is missing required scopes %v\n"+
209+
"To request it, run: gh auth refresh -s %s",
210+
s,
211+
strings.Join(s, ","))
212+
}
213+
return nil
214+
}
215+
216+
var scopesRE = regexp.MustCompile(`one of the following scopes: \[(.+?)]`)
217+
218+
func requiredScopesFromServerMessage(msg string) []string {
219+
m := scopesRE.FindStringSubmatch(msg)
220+
if m == nil {
221+
return nil
222+
}
223+
var scopes []string
224+
for _, mm := range strings.Split(m[1], ",") {
225+
scopes = append(scopes, strings.Trim(mm, "' "))
226+
}
227+
return scopes
228+
}
229+
191230
// ScopesSuggestion is an error messaging utility that prints the suggestion to request additional OAuth
192231
// scopes in case a server response indicates that there are missing scopes.
193232
func ScopesSuggestion(resp *http.Response) string {

api/client_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/cli/cli/v2/pkg/httpmock"
1212
"github.com/cli/cli/v2/pkg/iostreams"
13+
"github.com/cli/go-gh/v2/pkg/api"
1314
"github.com/stretchr/testify/assert"
1415
)
1516

@@ -256,3 +257,79 @@ func TestHTTPHeaders(t *testing.T) {
256257
}
257258
assert.Equal(t, "", stderr.String())
258259
}
260+
261+
func TestGenerateScopeErrorForGQL(t *testing.T) {
262+
tests := []struct {
263+
name string
264+
gqlError *api.GraphQLError
265+
wantErr bool
266+
expected string
267+
}{
268+
{
269+
name: "missing scope",
270+
gqlError: &api.GraphQLError{
271+
Errors: []api.GraphQLErrorItem{
272+
{
273+
Type: "INSUFFICIENT_SCOPES",
274+
Message: "The 'addProjectV2ItemById' field requires one of the following scopes: ['project']",
275+
},
276+
},
277+
},
278+
wantErr: true,
279+
expected: "error: your authentication token is missing required scopes [project]\n" +
280+
"To request it, run: gh auth refresh -s project",
281+
},
282+
283+
{
284+
name: "ignore non-scope errors",
285+
gqlError: &api.GraphQLError{
286+
Errors: []api.GraphQLErrorItem{
287+
{
288+
Type: "NOT_FOUND",
289+
Message: "Could not resolve to a Repository",
290+
},
291+
},
292+
},
293+
wantErr: false,
294+
},
295+
}
296+
297+
for _, tt := range tests {
298+
t.Run(tt.name, func(t *testing.T) {
299+
err := GenerateScopeErrorForGQL(tt.gqlError)
300+
if tt.wantErr {
301+
assert.NotNil(t, err)
302+
assert.Equal(t, tt.expected, err.Error())
303+
} else {
304+
assert.Nil(t, err)
305+
}
306+
})
307+
}
308+
}
309+
310+
func TestRequiredScopesFromServerMessage(t *testing.T) {
311+
tests := []struct {
312+
msg string
313+
expected []string
314+
}{
315+
{
316+
msg: "requires one of the following scopes: ['project']",
317+
expected: []string{"project"},
318+
},
319+
{
320+
msg: "requires one of the following scopes: ['repo', 'read:org']",
321+
expected: []string{"repo", "read:org"},
322+
},
323+
{
324+
msg: "no match here",
325+
expected: nil,
326+
},
327+
}
328+
329+
for _, tt := range tests {
330+
t.Run(tt.msg, func(t *testing.T) {
331+
output := requiredScopesFromServerMessage(tt.msg)
332+
assert.Equal(t, tt.expected, output)
333+
})
334+
}
335+
}

api/queries_pr.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,10 @@ type PullRequestCommitCommit struct {
296296
}
297297

298298
type PullRequestFile struct {
299-
Path string `json:"path"`
300-
Additions int `json:"additions"`
301-
Deletions int `json:"deletions"`
299+
Path string `json:"path"`
300+
Additions int `json:"additions"`
301+
Deletions int `json:"deletions"`
302+
ChangeType string `json:"changeType"`
302303
}
303304

304305
type ReviewRequests struct {

api/query_builder.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ var prFiles = shortenQuery(`
148148
nodes {
149149
additions,
150150
deletions,
151-
path
151+
path,
152+
changeType
152153
}
153154
}
154155
`)

api/query_builder_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestPullRequestGraphQL(t *testing.T) {
2626
{
2727
name: "compressed query",
2828
fields: []string{"files"},
29-
want: "files(first: 100) {nodes {additions,deletions,path}}",
29+
want: "files(first: 100) {nodes {additions,deletions,path,changeType}}",
3030
},
3131
{
3232
name: "invalid fields",
@@ -72,7 +72,7 @@ func TestIssueGraphQL(t *testing.T) {
7272
{
7373
name: "compressed query",
7474
fields: []string{"files"},
75-
want: "files(first: 100) {nodes {additions,deletions,path}}",
75+
want: "files(first: 100) {nodes {additions,deletions,path,changeType}}",
7676
},
7777
{
7878
name: "projectItems",

go.mod

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ require (
2121
github.com/creack/pty v1.1.24
2222
github.com/digitorus/timestamp v0.0.0-20250524132541-c45532741eea
2323
github.com/distribution/reference v0.6.0
24-
github.com/gabriel-vasile/mimetype v1.4.11
24+
github.com/gabriel-vasile/mimetype v1.4.13
2525
github.com/gdamore/tcell/v2 v2.13.8
2626
github.com/golang/snappy v1.0.0
2727
github.com/google/go-cmp v0.7.0
@@ -54,7 +54,7 @@ require (
5454
golang.org/x/sync v0.19.0
5555
golang.org/x/term v0.40.0
5656
golang.org/x/text v0.34.0
57-
google.golang.org/grpc v1.78.0
57+
google.golang.org/grpc v1.79.1
5858
google.golang.org/protobuf v1.36.11
5959
gopkg.in/h2non/gock.v1 v1.1.2
6060
gopkg.in/yaml.v3 v3.0.1
@@ -72,6 +72,7 @@ require (
7272
github.com/aymerick/douceur v0.2.0 // indirect
7373
github.com/blang/semver v3.5.1+incompatible // indirect
7474
github.com/catppuccin/go v0.3.0 // indirect
75+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
7576
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 // indirect
7677
github.com/charmbracelet/bubbletea v1.3.10 // indirect
7778
github.com/charmbracelet/colorprofile v0.3.1 // indirect
@@ -173,9 +174,9 @@ require (
173174
github.com/yuin/goldmark-emoji v1.0.6 // indirect
174175
go.mongodb.org/mongo-driver v1.17.6 // indirect
175176
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
176-
go.opentelemetry.io/otel v1.38.0 // indirect
177-
go.opentelemetry.io/otel/metric v1.38.0 // indirect
178-
go.opentelemetry.io/otel/trace v1.38.0 // indirect
177+
go.opentelemetry.io/otel v1.39.0 // indirect
178+
go.opentelemetry.io/otel/metric v1.39.0 // indirect
179+
go.opentelemetry.io/otel/trace v1.39.0 // indirect
179180
go.yaml.in/yaml/v3 v3.0.4 // indirect
180181
golang.org/x/mod v0.32.0 // indirect
181182
golang.org/x/net v0.49.0 // indirect

go.sum

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
102102
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
103103
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
104104
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
105+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
106+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
105107
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7 h1:JFgG/xnwFfbezlUnFMJy0nusZvytYysV4SCS2cYbvws=
106108
github.com/charmbracelet/bubbles v0.21.1-0.20250623103423-23b8fd6302d7/go.mod h1:ISC1gtLcVilLOf23wvTfoQuYbW2q0JevFxPfUzZ9Ybw=
107109
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
@@ -193,8 +195,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
193195
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
194196
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
195197
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
196-
github.com/gabriel-vasile/mimetype v1.4.11 h1:AQvxbp830wPhHTqc1u7nzoLT+ZFxGY7emj5DR5DYFik=
197-
github.com/gabriel-vasile/mimetype v1.4.11/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
198+
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
199+
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
198200
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
199201
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
200202
github.com/gdamore/tcell/v2 v2.13.8 h1:Mys/Kl5wfC/GcC5Cx4C2BIQH9dbnhnkPgS9/wF3RlfU=
@@ -548,16 +550,16 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6
548550
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ=
549551
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
550552
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg=
551-
go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8=
552-
go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM=
553-
go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA=
554-
go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI=
555-
go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E=
556-
go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg=
557-
go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM=
558-
go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA=
559-
go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE=
560-
go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs=
553+
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
554+
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
555+
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
556+
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
557+
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
558+
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
559+
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
560+
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
561+
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
562+
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
561563
go.step.sm/crypto v0.74.0 h1:/APBEv45yYR4qQFg47HA8w1nesIGcxh44pGyQNw6JRA=
562564
go.step.sm/crypto v0.74.0/go.mod h1:UoXqCAJjjRgzPte0Llaqen7O9P7XjPmgjgTHQGkKCDk=
563565
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -638,8 +640,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:
638640
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
639641
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
640642
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
641-
google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
642-
google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
643+
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
644+
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
643645
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
644646
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
645647
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

internal/licenses/embed/darwin-amd64/PLACEHOLDER

Whitespace-only changes.

0 commit comments

Comments
 (0)