Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
Sakura-Byte committed Jan 26, 2025
1 parent db0d506 commit 5572538
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 21 deletions.
40 changes: 20 additions & 20 deletions backend/115/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,18 +462,18 @@ func (f *Fs) tryHashUpload(
o *Object,
leaf, dirID string,
size int64,
) (bool, *api.UploadInitInfo, error) {
) (bool, *api.UploadInitInfo, io.Reader, error) {
fs.Debugf(o, "tryHashUpload: attempting 秒传...")

// 1) Get or compute the file's SHA-1
hashStr, err := src.Hash(ctx, hash.SHA1)
var cleanup func()
if err != nil || hashStr == "" {
fs.Debugf(o, "tryHashUpload: computing SHA1 locally...")
var cleanup func()
hashStr, in, cleanup, err = bufferIOwithSHA1(in, size, int64(f.opt.HashMemoryThreshold))
defer cleanup()
if err != nil {
return false, nil, fmt.Errorf("failed to calculate SHA1: %w", err)
return false, nil, nil, fmt.Errorf("failed to calculate SHA1: %w", err)
}
} else {
fs.Debugf(o, "tryHashUpload: using precomputed SHA1=%s", hashStr)
Expand All @@ -483,7 +483,7 @@ func (f *Fs) tryHashUpload(
// 2) Call initUpload with that SHA-1
ui, err := f.initUpload(ctx, size, leaf, dirID, hashStr, "", "")
if err != nil {
return false, nil, fmt.Errorf("秒传 initUpload failed: %w", err)
return false, nil, nil, fmt.Errorf("秒传 initUpload failed: %w", err)
}

// 3) Handle different statuses
Expand All @@ -502,29 +502,29 @@ func (f *Fs) tryHashUpload(
if info, err2 := f.getFile(ctx, "", ui.PickCode); err2 == nil {
_ = o.setMetaData(info)
}
return true, ui, nil
return true, ui, in, nil

case 1:
// status=1 => server doesn't have file => need actual upload
fs.Debugf(o, "tryHashUpload: 秒传 not possible => server requires real upload.")
return false, ui, nil
return false, ui, in, nil

case 7:
// partial-block check
fs.Debugf(o, "tryHashUpload: 秒传 partial-block check => signCheck=%q", ui.SignCheck)
signKey = ui.SignKey
if signVal, err = calcBlockSHA1(ctx, in, src, ui.SignCheck); err != nil {
return false, nil, fmt.Errorf("calcBlockSHA1 error: %w", err)
return false, nil, nil, fmt.Errorf("calcBlockSHA1 error: %w", err)
}
ui, err = f.initUpload(ctx, size, leaf, dirID, hashStr, signKey, signVal)
if err != nil {
return false, nil, fmt.Errorf("tryHashUpload: 秒传 re-init error: %w", err)
return false, nil, nil, fmt.Errorf("tryHashUpload: 秒传 re-init error: %w", err)
}
continue

default:
// Unexpected status => treat as error
return false, nil, fmt.Errorf("tryHashUpload: 秒传 error: unexpected status=%d", ui.Status)
return false, nil, nil, fmt.Errorf("tryHashUpload: 秒传 error: unexpected status=%d", ui.Status)
}
}
}
Expand Down Expand Up @@ -695,8 +695,8 @@ func (f *Fs) upload(
}
return obj, nil
}
return nil, fmt.Errorf("OnlyStream is enabled but file size %d exceeds StreamUploadLimit %d",
size, StreamUploadLimit)
return nil, fserrors.NoRetryError(fmt.Errorf("OnlyStream is enabled but file size %d exceeds StreamUploadLimit %d",
size, StreamUploadLimit))
}

//----------------------------------------------------------------
Expand All @@ -713,7 +713,7 @@ func (f *Fs) upload(
return obj, nil
}
// Attempt fast upload (秒传)
gotIt, ui, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
gotIt, ui, newIn, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
if err != nil {
return nil, fmt.Errorf("FastUpload: 秒传 error: %w", err)
}
Expand All @@ -723,27 +723,27 @@ func (f *Fs) upload(
// Fallback to uploadToOSS using the obtained UploadInitInfo
if ui != nil {
if size <= int64(StreamUploadLimit) {
obj, err := f.doSampleUpload(ctx, in, o, leaf, dirID, size, options...)
obj, err := f.doSampleUpload(ctx, newIn, o, leaf, dirID, size, options...)
if err != nil {
return nil, err
}
return obj, nil
}
obj, err := f.uploadToOSS(ctx, in, src, o, leaf, dirID, size, ui, options...)
obj, err := f.uploadToOSS(ctx, newIn, src, o, leaf, dirID, size, ui, options...)
if err != nil {
return nil, err
}
return obj, nil
}
// If ui is nil, fallback to standard upload
if size <= int64(StreamUploadLimit) {
obj, err := f.doSampleUpload(ctx, in, o, leaf, dirID, size, options...)
obj, err := f.doSampleUpload(ctx, newIn, o, leaf, dirID, size, options...)
if err != nil {
return nil, err
}
return obj, nil
}
obj, err := f.uploadToOSS(ctx, in, src, o, leaf, dirID, size, nil, options...)
obj, err := f.uploadToOSS(ctx, newIn, src, o, leaf, dirID, size, nil, options...)
if err != nil {
return nil, err
}
Expand All @@ -758,7 +758,7 @@ func (f *Fs) upload(
if hashStr == "" {
return nil, fserrors.NoRetryError(errors.New("UploadHashOnly: skipping since no SHA1"))
}
gotIt, _, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
gotIt, _, _, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
if err != nil {
return nil, err
}
Expand All @@ -782,10 +782,10 @@ func (f *Fs) upload(
}

// Attempt fast upload (秒传)
gotIt, ui, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
gotIt, ui, newIn, err := f.tryHashUpload(ctx, in, src, o, leaf, dirID, size)
if err != nil {
fs.Debugf(o, "normal: 秒传 error => fallback to uploadToOSS: %v", err)
obj, uploadErr := f.uploadToOSS(ctx, in, src, o, leaf, dirID, size, ui, options...)
obj, uploadErr := f.uploadToOSS(ctx, newIn, src, o, leaf, dirID, size, ui, options...)
if uploadErr != nil {
return nil, uploadErr
}
Expand All @@ -796,7 +796,7 @@ func (f *Fs) upload(
return o, nil
}
// Fallback to actual upload to OSS
obj, err := f.uploadToOSS(ctx, in, src, o, leaf, dirID, size, ui, options...)
obj, err := f.uploadToOSS(ctx, newIn, src, o, leaf, dirID, size, ui, options...)
if err != nil {
return nil, err
}
Expand Down
14 changes: 13 additions & 1 deletion backend/mega/mega.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"sync"
"time"

mega "github.com/Sakura-Byte/go-mega"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
"github.com/rclone/rclone/fs/config/configmap"
Expand All @@ -36,7 +37,6 @@ import (
"github.com/rclone/rclone/lib/encoder"
"github.com/rclone/rclone/lib/pacer"
"github.com/rclone/rclone/lib/readers"
mega "github.com/t3rm1n4l/go-mega"
)

const (
Expand Down Expand Up @@ -102,6 +102,11 @@ Enabling it will increase CPU usage and add network overhead.`,
// Encode invalid UTF-8 bytes as json doesn't handle them properly.
Default: (encoder.Base |
encoder.EncodeInvalidUtf8),
}, {
Name: "use_ipv6",
Help: `Use multiple IPv6 addresses to bypass bandwidth limits`,
Default: false,
Advanced: true,
}},
})
}
Expand All @@ -114,6 +119,7 @@ type Options struct {
HardDelete bool `config:"hard_delete"`
UseHTTPS bool `config:"use_https"`
Enc encoder.MultiEncoder `config:"encoding"`
UseIPv6 bool `config:"use_ipv6"`
}

// Fs represents a remote mega
Expand Down Expand Up @@ -216,6 +222,12 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
srv := megaCache[opt.User]
if srv == nil {
srv = mega.New().SetClient(fshttp.NewClient(ctx))
// Configure IPv6 if enabled
if opt.UseIPv6 {
if err := srv.AutoConfigureIPv6CIDR(); err != nil {
fs.Logf("mega", "IPv6 bypass unavailable: %v", err)
}
}
srv.SetRetries(ci.LowLevelRetries) // let mega do the low level retries
srv.SetHTTPS(opt.UseHTTPS)
srv.SetLogger(func(format string, v ...interface{}) {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ require (
github.com/ProtonMail/go-srp v0.0.7 // indirect
github.com/ProtonMail/gopenpgp/v2 v2.7.4 // indirect
github.com/PuerkitoBio/goquery v1.8.1 // indirect
github.com/Sakura-Byte/go-mega v0.0.0-20250124051730-c5abedf423a2 // indirect
github.com/akavel/rsrc v0.10.2 // indirect
github.com/anacrolix/generics v0.0.1 // indirect
github.com/andybalholm/cascadia v1.3.2 // indirect
Expand Down
23 changes: 23 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ github.com/ProtonMail/gopenpgp/v2 v2.7.4 h1:Vz/8+HViFFnf2A6XX8JOvZMrA6F5puwNvvF2
github.com/ProtonMail/gopenpgp/v2 v2.7.4/go.mod h1:IhkNEDaxec6NyzSI0PlxapinnwPVIESk8/76da3Ct3g=
github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
github.com/Sakura-Byte/go-mega v0.0.0-20250124050230-1e6bcc10647e h1:82/lt8xULsZIE7TkSV3MUH7lGMw6MFkBuCiQAI1XhCU=
github.com/Sakura-Byte/go-mega v0.0.0-20250124050230-1e6bcc10647e/go.mod h1:nl/671m018cbqvVIGv7yRS0/DOsc3XOvGo3ATa0TO7M=
github.com/Sakura-Byte/go-mega v0.0.0-20250124051730-c5abedf423a2 h1:FnBtaOUXasTbvn+hrNqLzHcDaps7xKyP9ibGh16/w/E=
github.com/Sakura-Byte/go-mega v0.0.0-20250124051730-c5abedf423a2/go.mod h1:nl/671m018cbqvVIGv7yRS0/DOsc3XOvGo3ATa0TO7M=
github.com/a8m/tree v0.0.0-20240104212747-2c8764a5f17e h1:KMVieI1/Ub++GYfnhyFPoGE3g5TUiG4srE3TMGr5nM4=
github.com/a8m/tree v0.0.0-20240104212747-2c8764a5f17e/go.mod h1:j5astEcUkZQX8lK+KKlQ3NRQ50f4EE8ZjyZpCz3mrH4=
github.com/aalpar/deheap v0.0.0-20210914013432-0cc84d79dec3 h1:hhdWprfSpFbN7lz3W1gM40vOgvSh1WCSMxYD6gGB4Hs=
Expand Down Expand Up @@ -685,7 +689,10 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down Expand Up @@ -725,6 +732,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -769,7 +779,10 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand All @@ -793,6 +806,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down Expand Up @@ -848,10 +863,13 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand All @@ -860,8 +878,10 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -877,6 +897,7 @@ golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down Expand Up @@ -933,6 +954,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down

0 comments on commit 5572538

Please sign in to comment.