Skip to content

Commit f5f27a8

Browse files
authored
✨ Remove explicit type dependency from artefacts utils (#103)
<!-- Copyright (C) 2020-2022 Arm Limited or its affiliates and Contributors. All rights reserved. SPDX-License-Identifier: Proprietary --> ### Description This change removes explicit type dependency from artefacts utils structs and functions by using generics instead of the explicit types that were imported from "embedded-development-services-client". The main issue was that the artefacts utils can only work with types defined in "embedded-development-services-client", even if another client package had the same type definitions, Go will still consider these types as incompatible because they come from different packages. My first approach was relying on interfaces and adaptor types that converted specific client's types into types that implemented these interfaces, but this meant that every user SDK will need this boilerplate adaptor code to be able to work with the utils, which is avoided using this approach. Another limitation that I faced, is that Go does not allow type manipulation in Generics (as in we can't take type T as an argument and transform it into pointer type *T), which meant that I had to work with either values only or pointer types, I chose to work with pointer types only to allow for type inference in the user SDK of the utils. This means that the only extra change that is still required to make this work is to provide a static definition in the client generator for "HalCollectionLinks": ``` // GetNextP returns the Next field pointer if set, nil otherwise. func (o *HalCollectionLinks) GetNextP() *HalLinkData { if o == nil || IsNil(o.Next) { return nil } return o.Next } ``` As you can also see in the "artefacts_test.go" file, the only change that is required from the SDKs, is that if they need to instantiate IArtefactManager, it will need explicit types to be passed to it ``` // Example instantiation IArtefactManager[*client.ArtefactManagerItem, *client.HalLinkData] ``` <!-- Please put an `x` in the correct box e.g. `[x]` to indicate the testing coverage of this change. --> - [x] This change is covered by existing or additional automated tests. - [ ] Manual testing has been performed (and evidence provided) as automated testing was not feasible. - [ ] Additional tests are not required for this change (e.g. documentation update). --------- Co-authored-by: aorabdel <[email protected]>
1 parent 30dc1d8 commit f5f27a8

File tree

6 files changed

+89
-45
lines changed

6 files changed

+89
-45
lines changed

changes/20250404125454.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:sparkles: Remove explicit type dependency from artefacts utils

utils/artefacts/artefacts.go

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616

1717
"github.com/ARM-software/embedded-development-services-client-utils/utils/api"
1818
paginationUtils "github.com/ARM-software/embedded-development-services-client-utils/utils/pagination"
19-
"github.com/ARM-software/embedded-development-services-client/client"
2019
"github.com/ARM-software/golang-utils/utils/collection/pagination"
2120
"github.com/ARM-software/golang-utils/utils/commonerrors"
2221
"github.com/ARM-software/golang-utils/utils/filesystem"
@@ -29,17 +28,17 @@ const relativePathKey = "Relative Path"
2928

3029
type (
3130
// GetArtefactManagersFirstPageFunc defines the function which can retrieve the first page of artefact managers.
32-
GetArtefactManagersFirstPageFunc = func(ctx context.Context, job string) (*client.ArtefactManagerCollection, *http.Response, error)
31+
GetArtefactManagersFirstPageFunc[D ILinkData, L ILinks[D], C ICollection[D, L]] = func(ctx context.Context, job string) (C, *http.Response, error)
3332
// FollowLinkToArtefactManagersPageFunc is a function able to follow a link to an artefact manager page.
34-
FollowLinkToArtefactManagersPageFunc = func(ctx context.Context, link *client.HalLinkData) (*client.ArtefactManagerCollection, *http.Response, error)
33+
FollowLinkToArtefactManagersPageFunc[D ILinkData, L ILinks[D], C ICollection[D, L]] = func(ctx context.Context, link D) (C, *http.Response, error)
3534
// GetArtefactManagerFunc is a function which retrieves information about an artefact manager.
36-
GetArtefactManagerFunc = func(ctx context.Context, job, artefact string) (*client.ArtefactManagerItem, *http.Response, error)
35+
GetArtefactManagerFunc[M IManager] = func(ctx context.Context, job, artefact string) (M, *http.Response, error)
3736
// GetArtefactContentFunc is a function able to return the content of any artefact managers.
3837
GetArtefactContentFunc = func(ctx context.Context, job, artefactID string) (*os.File, *http.Response, error)
3938
)
4039

41-
func determineArtefactDestination(outputDir string, maintainTree bool, item *client.ArtefactManagerItem) (artefactFileName string, destinationDir string, err error) {
42-
if item == nil {
40+
func determineArtefactDestination[M IManager](outputDir string, maintainTree bool, item M) (artefactFileName string, destinationDir string, err error) {
41+
if any(item) == nil {
4342
err = fmt.Errorf("%w: missing artefact item", commonerrors.ErrUndefined)
4443
return
4544
}
@@ -76,27 +75,41 @@ func determineArtefactDestination(outputDir string, maintainTree bool, item *cli
7675
return
7776
}
7877

79-
type ArtefactManager struct {
80-
getArtefactManagerFunc GetArtefactManagerFunc
78+
type ArtefactManager[
79+
M IManager,
80+
D ILinkData,
81+
L ILinks[D],
82+
C ICollection[D, L],
83+
] struct {
84+
getArtefactManagerFunc GetArtefactManagerFunc[M]
8185
getArtefactContentFunc GetArtefactContentFunc
82-
getArtefactManagersFirstPageFunc GetArtefactManagersFirstPageFunc
83-
getArtefactManagersFollowLinkFunc FollowLinkToArtefactManagersPageFunc
86+
getArtefactManagersFirstPageFunc GetArtefactManagersFirstPageFunc[D, L, C]
87+
getArtefactManagersFollowLinkFunc FollowLinkToArtefactManagersPageFunc[D, L, C]
8488
}
8589

8690
// NewArtefactManager returns an artefact manager.
87-
func NewArtefactManager(getArtefactManagersFirstPage GetArtefactManagersFirstPageFunc, getArtefactsManagersPage FollowLinkToArtefactManagersPageFunc, getArtefactManager GetArtefactManagerFunc, getOutputArtefact GetArtefactContentFunc) IArtefactManager {
88-
return &ArtefactManager{
91+
func NewArtefactManager[
92+
M IManager,
93+
D ILinkData,
94+
L ILinks[D],
95+
C ICollection[D, L],
96+
](
97+
getArtefactManagersFirstPage GetArtefactManagersFirstPageFunc[D, L, C],
98+
getArtefactsManagersPage FollowLinkToArtefactManagersPageFunc[D, L, C],
99+
getArtefactManager GetArtefactManagerFunc[M],
100+
getOutputArtefact GetArtefactContentFunc) IArtefactManager[M, D] {
101+
return &ArtefactManager[M, D, L, C]{
89102
getArtefactManagerFunc: getArtefactManager,
90103
getArtefactContentFunc: getOutputArtefact,
91104
getArtefactManagersFirstPageFunc: getArtefactManagersFirstPage,
92105
getArtefactManagersFollowLinkFunc: getArtefactsManagersPage,
93106
}
94107
}
95-
func (m *ArtefactManager) DownloadJobArtefact(ctx context.Context, jobName string, outputDirectory string, artefactManager *client.ArtefactManagerItem) (err error) {
108+
func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefact(ctx context.Context, jobName string, outputDirectory string, artefactManager M) (err error) {
96109
return m.DownloadJobArtefactWithTree(ctx, jobName, false, outputDirectory, artefactManager)
97110
}
98111

99-
func (m *ArtefactManager) DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager *client.ArtefactManagerItem) (err error) {
112+
func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager M) (err error) {
100113
err = parallelisation.DetermineContextError(ctx)
101114
if err != nil {
102115
return
@@ -116,7 +129,7 @@ func (m *ArtefactManager) DownloadJobArtefactWithTree(ctx context.Context, jobNa
116129
if err != nil {
117130
return
118131
}
119-
if artefactManager == nil {
132+
if any(artefactManager) == nil {
120133
err = fmt.Errorf("%w: missing artefact manager", commonerrors.ErrUndefined)
121134
return
122135
}
@@ -207,11 +220,11 @@ func (m *ArtefactManager) DownloadJobArtefactWithTree(ctx context.Context, jobNa
207220
return
208221

209222
}
210-
func (m *ArtefactManager) DownloadJobArtefactFromLink(ctx context.Context, jobName string, outputDirectory string, artefactManagerItemLink *client.HalLinkData) error {
223+
func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactFromLink(ctx context.Context, jobName string, outputDirectory string, artefactManagerItemLink D) error {
211224
return m.DownloadJobArtefactFromLinkWithTree(ctx, jobName, false, outputDirectory, artefactManagerItemLink)
212225
}
213226

214-
func (m *ArtefactManager) DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink *client.HalLinkData) (err error) {
227+
func (m *ArtefactManager[M, D, L, C]) DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink D) (err error) {
215228
err = parallelisation.DetermineContextError(ctx)
216229
if err != nil {
217230
return
@@ -220,7 +233,7 @@ func (m *ArtefactManager) DownloadJobArtefactFromLinkWithTree(ctx context.Contex
220233
err = fmt.Errorf("%w: function to retrieve an artefact manager was not properly defined", commonerrors.ErrUndefined)
221234
return
222235
}
223-
if artefactManagerItemLink == nil {
236+
if any(artefactManagerItemLink) == nil {
224237
err = fmt.Errorf("%w: missing artefact link", commonerrors.ErrUndefined)
225238
return
226239
}
@@ -243,7 +256,7 @@ func (m *ArtefactManager) DownloadJobArtefactFromLinkWithTree(ctx context.Contex
243256
return
244257
}
245258

246-
func (m *ArtefactManager) ListJobArtefacts(ctx context.Context, jobName string) (pagination.IPaginatorAndPageFetcher, error) {
259+
func (m *ArtefactManager[M, D, L, C]) ListJobArtefacts(ctx context.Context, jobName string) (pagination.IPaginatorAndPageFetcher, error) {
247260
err := parallelisation.DetermineContextError(ctx)
248261
if err != nil {
249262
return nil, err
@@ -253,7 +266,7 @@ func (m *ArtefactManager) ListJobArtefacts(ctx context.Context, jobName string)
253266
}, m.fetchJobArtefactsNextPage)
254267
}
255268

256-
func (m *ArtefactManager) fetchJobArtefactsFirstPage(ctx context.Context, jobName string) (page pagination.IStaticPage, err error) {
269+
func (m *ArtefactManager[M, D, L, C]) fetchJobArtefactsFirstPage(ctx context.Context, jobName string) (page pagination.IStaticPage, err error) {
257270
if m.getArtefactManagersFirstPageFunc == nil {
258271
err = fmt.Errorf("%w: function to retrieve artefact managers was not properly defined", commonerrors.ErrUndefined)
259272
return
@@ -269,7 +282,7 @@ func (m *ArtefactManager) fetchJobArtefactsFirstPage(ctx context.Context, jobNam
269282
return
270283
}
271284

272-
func (m *ArtefactManager) fetchJobArtefactsNextPage(ctx context.Context, currentPage pagination.IStaticPage) (nextPage pagination.IStaticPage, err error) {
285+
func (m *ArtefactManager[M, D, L, C]) fetchJobArtefactsNextPage(ctx context.Context, currentPage pagination.IStaticPage) (nextPage pagination.IStaticPage, err error) {
273286
err = parallelisation.DetermineContextError(ctx)
274287
if err != nil {
275288
return
@@ -286,7 +299,7 @@ func (m *ArtefactManager) fetchJobArtefactsNextPage(ctx context.Context, current
286299
err = fmt.Errorf("%w: returned artefact managers page is empty", commonerrors.ErrUnexpected)
287300
return
288301
}
289-
page, ok := unwrappedPage.(*client.ArtefactManagerCollection)
302+
page, ok := unwrappedPage.(C)
290303
if !ok {
291304
err = fmt.Errorf("%w: returned artefact managers page[%T] is not of the expected type [%v]", commonerrors.ErrUnexpected, currentPage, "*ArtefactManagerCollection")
292305
return
@@ -300,8 +313,8 @@ func (m *ArtefactManager) fetchJobArtefactsNextPage(ctx context.Context, current
300313
err = fmt.Errorf("%w: returned page of artefact managers has no `next` link", commonerrors.ErrUnexpected)
301314
return
302315
}
303-
link := links.GetNext()
304-
clientPage, resp, apierr := m.getArtefactManagersFollowLinkFunc(ctx, &link)
316+
link := links.GetNextP()
317+
clientPage, resp, apierr := m.getArtefactManagersFollowLinkFunc(ctx, link)
305318
if resp != nil {
306319
_ = resp.Body.Close()
307320
}
@@ -312,11 +325,11 @@ func (m *ArtefactManager) fetchJobArtefactsNextPage(ctx context.Context, current
312325
return
313326
}
314327

315-
func (m *ArtefactManager) DownloadAllJobArtefacts(ctx context.Context, jobName string, outputDirectory string) error {
328+
func (m *ArtefactManager[M, D, L, C]) DownloadAllJobArtefacts(ctx context.Context, jobName string, outputDirectory string) error {
316329
return m.DownloadAllJobArtefactsWithTree(ctx, jobName, false, outputDirectory)
317330
}
318331

319-
func (m *ArtefactManager) DownloadAllJobArtefactsWithTree(ctx context.Context, jobName string, maintainTreeStructure bool, outputDirectory string) (err error) {
332+
func (m *ArtefactManager[M, D, L, C]) DownloadAllJobArtefactsWithTree(ctx context.Context, jobName string, maintainTreeStructure bool, outputDirectory string) (err error) {
320333
err = parallelisation.DetermineContextError(ctx)
321334
if err != nil {
322335
return
@@ -341,7 +354,7 @@ func (m *ArtefactManager) DownloadAllJobArtefactsWithTree(ctx context.Context, j
341354
err = fmt.Errorf("%w: failed getting information about job artefacts: %v", commonerrors.ErrUnexpected, subErr.Error())
342355
return
343356
}
344-
artefactLink, ok := item.(*client.HalLinkData)
357+
artefactLink, ok := item.(D)
345358
if ok {
346359
subErr = m.DownloadJobArtefactFromLinkWithTree(ctx, jobName, maintainTreeStructure, outputDirectory, artefactLink)
347360
if subErr != nil {
@@ -350,7 +363,7 @@ func (m *ArtefactManager) DownloadAllJobArtefactsWithTree(ctx context.Context, j
350363
}
351364

352365
} else {
353-
artefactManager, ok := item.(*client.ArtefactManagerItem)
366+
artefactManager, ok := item.(M)
354367
if ok {
355368
subErr = m.DownloadJobArtefactWithTree(ctx, jobName, maintainTreeStructure, outputDirectory, artefactManager)
356369
if subErr != nil {

utils/artefacts/artefacts_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,12 @@ func (t *testArtefact) testGetOutputArtefact(ctx context.Context, _, artefact st
156156
return nil, &http.Response{StatusCode: http.StatusNotFound, Body: io.NopCloser(safeio.NewByteReader(ctx, []byte("hello")))}, commonerrors.ErrNotFound
157157
}
158158

159-
func newTestArtefactManager(t *testing.T, tmpDir, artefactContent string, linksOnly bool) (IArtefactManager, *testArtefact) {
159+
func newTestArtefactManager(t *testing.T, tmpDir, artefactContent string, linksOnly bool) (IArtefactManager[*client.ArtefactManagerItem, *client.HalLinkData], *testArtefact) {
160160
testArtefact := newTestArtefact(t, tmpDir, artefactContent, !linksOnly)
161161
return NewArtefactManager(testArtefact.testGetArtefactManagers, nil, testArtefact.testGetArtefactManager, testArtefact.testGetOutputArtefact), testArtefact
162162
}
163163

164-
func newTestArtefactManagerWithEmbeddedResources(t *testing.T, tmpDir, artefactContent string) (IArtefactManager, *testArtefact) {
164+
func newTestArtefactManagerWithEmbeddedResources(t *testing.T, tmpDir, artefactContent string) (IArtefactManager[*client.ArtefactManagerItem, *client.HalLinkData], *testArtefact) {
165165
return newTestArtefactManager(t, tmpDir, artefactContent, false)
166166
}
167167

utils/artefacts/interface.go

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,25 @@ package artefacts
88
import (
99
"context"
1010

11-
"github.com/ARM-software/embedded-development-services-client/client"
1211
"github.com/ARM-software/golang-utils/utils/collection/pagination"
1312
)
1413

1514
//go:generate mockgen -destination=../mocks/mock_$GOPACKAGE.go -package=mocks github.com/ARM-software/embedded-development-services-client-utils/utils/$GOPACKAGE IArtefactManager
1615

17-
type IArtefactManager interface {
16+
type IArtefactManager[
17+
M IManager,
18+
D ILinkData,
19+
] interface {
1820
// DownloadJobArtefactFromLink downloads a specific artefact into the output directory from a particular link. The artefact will be placed at the root of the output directory.
19-
DownloadJobArtefactFromLink(ctx context.Context, jobName string, outputDirectory string, artefactManagerItemLink *client.HalLinkData) error
21+
DownloadJobArtefactFromLink(ctx context.Context, jobName string, outputDirectory string, artefactManagerItemLink D) error
2022
// DownloadJobArtefactFromLinkWithTree downloads a specific artefact into the output directory from a particular link.
2123
// maintainTreeLocation specifies whether the artefact will be placed in a tree structure or if it will be flat.
22-
DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink *client.HalLinkData) error
24+
DownloadJobArtefactFromLinkWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManagerItemLink D) error
2325
// DownloadJobArtefact downloads a specific artefact into the output directory. The artefact will be placed at the root of the output directory.
24-
DownloadJobArtefact(ctx context.Context, jobName string, outputDirectory string, artefactManager *client.ArtefactManagerItem) error
26+
DownloadJobArtefact(ctx context.Context, jobName string, outputDirectory string, artefactManager M) error
2527
// DownloadJobArtefactWithTree downloads a specific artefact into the output directory.
2628
// maintainTreeLocation specifies whether the artefact will be placed in a tree structure or if it will be flat.
27-
DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager *client.ArtefactManagerItem) error
29+
DownloadJobArtefactWithTree(ctx context.Context, jobName string, maintainTreeLocation bool, outputDirectory string, artefactManager M) error
2830
// ListJobArtefacts lists all artefact managers associated with a particular job.
2931
ListJobArtefacts(ctx context.Context, jobName string) (pagination.IPaginatorAndPageFetcher, error)
3032
// DownloadAllJobArtefacts downloads all the artefacts produced for a particular job and puts them in an output directory as a flat list.
@@ -33,3 +35,31 @@ type IArtefactManager interface {
3335
// maintainTreeStructure specifies whether to keep the tree structure of the artefacts or not in the output directory.
3436
DownloadAllJobArtefactsWithTree(ctx context.Context, jobName string, maintainTreeStructure bool, outputDirectory string) error
3537
}
38+
39+
type ILinkData interface {
40+
comparable
41+
GetName() string
42+
GetHref() string
43+
}
44+
45+
type ILinks[D ILinkData] interface {
46+
comparable
47+
GetNextP() D
48+
HasNext() bool
49+
}
50+
type ICollection[D ILinkData, L ILinks[D]] interface {
51+
comparable
52+
pagination.IStaticPage
53+
GetLinksOk() (L, bool)
54+
}
55+
56+
type IManager interface {
57+
comparable
58+
GetName() string
59+
GetTitle() string
60+
HasTitle() bool
61+
GetHashOk() (*string, bool)
62+
GetSizeOk() (*int64, bool)
63+
GetExtraMetadata() map[string]string
64+
HasExtraMetadata() bool
65+
}

utils/go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ module github.com/ARM-software/embedded-development-services-client-utils/utils
33
go 1.24
44

55
require (
6-
github.com/ARM-software/embedded-development-services-client/client v1.45.1
6+
github.com/ARM-software/embedded-development-services-client/client v1.50.0
77
github.com/ARM-software/golang-utils/utils v1.89.0
88
github.com/go-faker/faker/v4 v4.6.0
99
github.com/go-logr/logr v1.4.2
1010
github.com/stretchr/testify v1.10.0
1111
go.uber.org/atomic v1.11.0
1212
go.uber.org/goleak v1.3.0
1313
go.uber.org/mock v0.5.0
14-
golang.org/x/sync v0.12.0
14+
golang.org/x/sync v0.13.0
1515
)
1616

1717
require (
@@ -76,7 +76,7 @@ require (
7676
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
7777
golang.org/x/oauth2 v0.28.0 // indirect
7878
golang.org/x/sys v0.31.0 // indirect
79-
golang.org/x/text v0.23.0 // indirect
79+
golang.org/x/text v0.24.0 // indirect
8080
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 // indirect
8181
gopkg.in/yaml.v3 v3.0.1 // indirect
8282
)

utils/go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
bitbucket.org/creachadair/stringset v0.0.9/go.mod h1:t+4WcQ4+PXTa8aQdNKe40ZP6iwesoMFWAxPGd3UGjyY=
2-
github.com/ARM-software/embedded-development-services-client/client v1.45.1 h1:qB/nQm3RtVTLbPXI1BNH8RC8T0Bw06PJPY2geRKTpuw=
3-
github.com/ARM-software/embedded-development-services-client/client v1.45.1/go.mod h1:rQp94BDHwu/+Q27cwS8iObzaJW027hMTRpN5Jj+6Ddc=
2+
github.com/ARM-software/embedded-development-services-client/client v1.50.0 h1:6woKXzWh0XUlBGA2El5XhaW6FY9QxtvQ7Lhkjp+Yi8g=
3+
github.com/ARM-software/embedded-development-services-client/client v1.50.0/go.mod h1:I4n0SrcIgKKVbcJCBBwvANNz+Wjs/EZ9YwzIiFe4fsk=
44
github.com/ARM-software/golang-utils/utils v1.89.0 h1:WyrZiTkzzHemZ4oqS/LbkjukDYyV7TCS1efAT9rmB4A=
55
github.com/ARM-software/golang-utils/utils v1.89.0/go.mod h1:hbOnHpp3NKGQlSwI8YhIBLH5TrlPnFP3OE0HphMNqVI=
66
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ -220,8 +220,8 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx
220220
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
221221
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
222222
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
223-
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
224-
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
223+
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
224+
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
225225
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
226226
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
227227
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -255,8 +255,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn
255255
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
256256
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
257257
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
258-
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
259-
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
258+
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
259+
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
260260
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
261261
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
262262
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

0 commit comments

Comments
 (0)