From 775d3734eb75fa3aa0183fff136765d872ae53e6 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Thu, 12 Feb 2026 17:49:14 +0100 Subject: [PATCH] modernize code Automated fixing, using Go's "modernize" tool; go install golang.org/x/tools/go/analysis/passes/modernize/cmd/modernize@latest modernize -fix ./... Signed-off-by: Sebastiaan van Stijn --- blobs.go | 2 +- configuration/configuration.go | 30 +++++------ configuration/configuration_test.go | 10 ++-- configuration/parser.go | 6 +-- configuration/parser_test.go | 8 +-- internal/client/auth/api_version.go | 2 +- .../client/auth/challenge/authchallenge.go | 2 +- .../auth/challenge/authchallenge_test.go | 4 +- internal/client/auth/session.go | 12 ++--- internal/client/auth/session_test.go | 18 +++---- internal/client/repository.go | 16 ++---- internal/client/repository_test.go | 10 ++-- internal/dcontext/context.go | 10 ++-- internal/dcontext/http.go | 6 +-- internal/dcontext/http_test.go | 4 +- internal/dcontext/logger.go | 50 +++++++++---------- internal/dcontext/trace.go | 6 +-- internal/dcontext/trace_test.go | 2 +- internal/dcontext/util.go | 4 +- manifest/manifestlist/manifestlist.go | 4 +- manifest/ocischema/index.go | 4 +- manifest/ocischema/manifest.go | 2 +- notifications/event.go | 10 ++-- notifications/listener_test.go | 2 +- notifications/metrics.go | 6 +-- notifications/metrics_test.go | 4 +- registry/api/errcode/errors.go | 21 ++++---- registry/api/errcode/errors_test.go | 4 +- registry/auth/auth.go | 4 +- registry/auth/htpasswd/access.go | 4 +- registry/auth/htpasswd/access_test.go | 6 +-- registry/auth/silly/access.go | 2 +- registry/auth/token/accesscontroller.go | 6 +-- registry/auth/token/accesscontroller_test.go | 8 +-- registry/auth/token/token_test.go | 8 +-- registry/auth/token/types.go | 4 +- registry/auth/token/util.go | 9 +--- registry/handlers/api_test.go | 24 ++++----- registry/handlers/app.go | 14 +++--- registry/handlers/app_test.go | 2 +- registry/handlers/context.go | 6 +-- registry/handlers/health_test.go | 6 +-- registry/handlers/helpers.go | 2 +- registry/handlers/manifests.go | 10 ++-- registry/middleware/registry/middleware.go | 4 +- registry/middleware/repository/middleware.go | 4 +- registry/proxy/proxyauth_exec_test.go | 2 +- registry/proxy/proxyblobstore_test.go | 10 ++-- registry/proxy/proxymanifeststore_test.go | 2 +- registry/proxy/proxymetrics.go | 4 +- registry/registry.go | 2 +- registry/registry_test.go | 4 +- registry/storage/blobwriter.go | 2 +- registry/storage/blobwriter_resumable.go | 1 - registry/storage/catalog.go | 5 +- registry/storage/driver/azure/azure.go | 7 +-- registry/storage/driver/azure/azure_test.go | 10 ++-- registry/storage/driver/azure/parser.go | 2 +- registry/storage/driver/base/regulator.go | 2 +- .../storage/driver/base/regulator_test.go | 8 +-- registry/storage/driver/factory/factory.go | 4 +- registry/storage/driver/filesystem/driver.go | 6 +-- .../storage/driver/filesystem/driver_test.go | 14 +++--- registry/storage/driver/gcs/gcs.go | 12 ++--- registry/storage/driver/inmemory/driver.go | 2 +- registry/storage/driver/inmemory/mfs.go | 9 ++-- .../middleware/cloudfront/middleware.go | 4 +- .../middleware/cloudfront/middleware_test.go | 4 +- .../driver/middleware/cloudfront/s3filter.go | 6 +-- .../middleware/cloudfront/s3filter_test.go | 6 +-- .../driver/middleware/redirect/middleware.go | 2 +- .../middleware/redirect/middleware_test.go | 10 ++-- .../driver/middleware/rewrite/middleware.go | 4 +- .../middleware/rewrite/middleware_test.go | 8 +-- .../driver/middleware/storagemiddleware.go | 4 +- registry/storage/driver/s3-aws/s3.go | 4 +- registry/storage/driver/s3-aws/s3_test.go | 14 ++---- registry/storage/driver/storagedriver.go | 7 +-- .../storage/driver/testsuites/testsuites.go | 13 ++--- registry/storage/garbagecollect.go | 2 +- registry/storage/linkedblobstore.go | 6 +-- registry/storage/linkedblobstore_test.go | 6 +-- registry/storage/manifeststore_test.go | 6 +-- registry/storage/purgeuploads_test.go | 4 +- registry/storage/tagstore_test.go | 2 +- testutil/tarfile.go | 4 +- 86 files changed, 285 insertions(+), 321 deletions(-) diff --git a/blobs.go b/blobs.go index 3de30b592..80f6cebba 100644 --- a/blobs.go +++ b/blobs.go @@ -157,7 +157,7 @@ type BlobIngester interface { // BlobIngester receiving them. // TODO (brianbland): unify this with ManifestServiceOption in the future type BlobCreateOption interface { - Apply(interface{}) error + Apply(any) error } // CreateOptions is a collection of blob creation modifiers relevant to general diff --git a/configuration/configuration.go b/configuration/configuration.go index 5127c975e..5d6456ea5 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -105,7 +105,7 @@ type Log struct { // Fields allows users to specify static string fields to include in // the logger context. - Fields map[string]interface{} `yaml:"fields,omitempty"` + Fields map[string]any `yaml:"fields,omitempty"` // Hooks allows users to configure the log hooks, to enabling the // sequent handling behavior, when defined levels of log message emit. @@ -409,7 +409,7 @@ type v0_1Configuration Configuration // UnmarshalYAML implements the yaml.Unmarshaler interface // Unmarshals a string of the form X.Y into a Version, validating that X and Y can represent unsigned integers -func (version *Version) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (version *Version) UnmarshalYAML(unmarshal func(any) error) error { var versionString string err := unmarshal(&versionString) if err != nil { @@ -439,7 +439,7 @@ type Loglevel string // UnmarshalYAML implements the yaml.Umarshaler interface // Unmarshals a string into a Loglevel, lowercasing the string and validating that it represents a // valid loglevel -func (loglevel *Loglevel) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (loglevel *Loglevel) UnmarshalYAML(unmarshal func(any) error) error { var loglevelString string err := unmarshal(&loglevelString) if err != nil { @@ -458,7 +458,7 @@ func (loglevel *Loglevel) UnmarshalYAML(unmarshal func(interface{}) error) error } // Parameters defines a key-value parameters mapping -type Parameters map[string]interface{} +type Parameters map[string]any // Storage defines the configuration for registry object storage type Storage map[string]Parameters @@ -499,7 +499,7 @@ func (storage Storage) TagParameters() Parameters { } // setTagParameter changes the parameter at the provided key to the new value -func (storage Storage) setTagParameter(key string, value interface{}) { +func (storage Storage) setTagParameter(key string, value any) { if _, ok := storage["tag"]; !ok { storage["tag"] = make(Parameters) } @@ -512,13 +512,13 @@ func (storage Storage) Parameters() Parameters { } // setParameter changes the parameter at the provided key to the new value -func (storage Storage) setParameter(key string, value interface{}) { +func (storage Storage) setParameter(key string, value any) { storage[storage.Type()][key] = value } // UnmarshalYAML implements the yaml.Unmarshaler interface // Unmarshals a single item map into a Storage or a string into a Storage type with no parameters -func (storage *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (storage *Storage) UnmarshalYAML(unmarshal func(any) error) error { var storageMap map[string]Parameters err := unmarshal(&storageMap) if err == nil { @@ -560,7 +560,7 @@ func (storage *Storage) UnmarshalYAML(unmarshal func(interface{}) error) error { } // MarshalYAML implements the yaml.Marshaler interface -func (storage Storage) MarshalYAML() (interface{}, error) { +func (storage Storage) MarshalYAML() (any, error) { if storage.Parameters() == nil { return storage.Type(), nil } @@ -585,13 +585,13 @@ func (auth Auth) Parameters() Parameters { } // setParameter changes the parameter at the provided key to the new value -func (auth Auth) setParameter(key string, value interface{}) { +func (auth Auth) setParameter(key string, value any) { auth[auth.Type()][key] = value } // UnmarshalYAML implements the yaml.Unmarshaler interface // Unmarshals a single item map into a Storage or a string into a Storage type with no parameters -func (auth *Auth) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (auth *Auth) UnmarshalYAML(unmarshal func(any) error) error { var m map[string]Parameters err := unmarshal(&m) if err == nil { @@ -621,7 +621,7 @@ func (auth *Auth) UnmarshalYAML(unmarshal func(interface{}) error) error { } // MarshalYAML implements the yaml.Marshaler interface -func (auth Auth) MarshalYAML() (interface{}, error) { +func (auth Auth) MarshalYAML() (any, error) { if auth.Parameters() == nil { return auth.Type(), nil } @@ -760,7 +760,7 @@ type Platforms string // UnmarshalYAML implements the yaml.Umarshaler interface // Unmarshals a string into a Platforms option, lowercasing the string and validating that it represents a // valid option -func (platforms *Platforms) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (platforms *Platforms) UnmarshalYAML(unmarshal func(any) error) error { var platformsString string err := unmarshal(&platformsString) if err != nil { @@ -794,8 +794,8 @@ func Parse(rd io.Reader) (*Configuration, error) { p := NewParser("registry", []VersionedParseInfo{ { Version: MajorMinorVersion(0, 1), - ParseAs: reflect.TypeOf(v0_1Configuration{}), - ConversionFunc: func(c interface{}) (interface{}, error) { + ParseAs: reflect.TypeFor[v0_1Configuration](), + ConversionFunc: func(c any) (any, error) { if v0_1, ok := c.(*v0_1Configuration); ok { if v0_1.Log.Level == Loglevel("") { if v0_1.Loglevel != Loglevel("") { @@ -971,7 +971,7 @@ type ClientAuth string // UnmarshalYAML implements the yaml.Umarshaler interface // Unmarshals a string into a ClientAuth, validating that it represents a valid ClientAuth mod -func (clientAuth *ClientAuth) UnmarshalYAML(unmarshal func(interface{}) error) error { +func (clientAuth *ClientAuth) UnmarshalYAML(unmarshal func(any) error) error { var clientAuthString string err := unmarshal(&clientAuthString) if err != nil { diff --git a/configuration/configuration_test.go b/configuration/configuration_test.go index 33bed3b7f..08acb891f 100644 --- a/configuration/configuration_test.go +++ b/configuration/configuration_test.go @@ -18,7 +18,7 @@ var configStruct = Configuration{ Version: "0.1", Log: Log{ Level: "info", - Fields: map[string]interface{}{"environment": "test"}, + Fields: map[string]any{"environment": "test"}, }, Storage: Storage{ "somedriver": Parameters{ @@ -395,10 +395,10 @@ func (suite *ConfigSuite) TestParseExtraneousVars() { // TestParseEnvVarImplicitMaps validates that environment variables can set // values in maps that don't already exist. func (suite *ConfigSuite) TestParseEnvVarImplicitMaps() { - readonly := make(map[string]interface{}) + readonly := make(map[string]any) readonly["enabled"] = true - maintenance := make(map[string]interface{}) + maintenance := make(map[string]any) maintenance["readonly"] = readonly suite.expectedConfig.Storage["maintenance"] = maintenance @@ -497,7 +497,7 @@ func checkStructs(tt *testing.T, t reflect.Type, structsChecked map[string]struc // with yaml tags that would be ambiguous to the environment variable parser. func (suite *ConfigSuite) TestValidateConfigStruct() { structsChecked := make(map[string]struct{}) - checkStructs(suite.T(), reflect.TypeOf(Configuration{}), structsChecked) + checkStructs(suite.T(), reflect.TypeFor[Configuration](), structsChecked) } func copyConfig(config Configuration) *Configuration { @@ -507,7 +507,7 @@ func copyConfig(config Configuration) *Configuration { configCopy.Loglevel = config.Loglevel configCopy.Log = config.Log configCopy.Catalog = config.Catalog - configCopy.Log.Fields = make(map[string]interface{}, len(config.Log.Fields)) + configCopy.Log.Fields = make(map[string]any, len(config.Log.Fields)) maps.Copy(configCopy.Log.Fields, config.Log.Fields) configCopy.Storage = Storage{config.Storage.Type(): Parameters{}} diff --git a/configuration/parser.go b/configuration/parser.go index 1a9201986..1f520406a 100644 --- a/configuration/parser.go +++ b/configuration/parser.go @@ -57,7 +57,7 @@ type VersionedParseInfo struct { // ConversionFunc defines a method for converting the parsed configuration // (of type ParseAs) into the current configuration version // Note: this method signature is very unclear with the absence of generics - ConversionFunc func(interface{}) (interface{}, error) + ConversionFunc func(any) (any, error) } type envVar struct { @@ -111,7 +111,7 @@ func NewParser(prefix string, parseInfos []VersionedParseInfo) *Parser { // than version, following the scheme below: // v.Abc may be replaced by the value of PREFIX_ABC, // v.Abc.Xyz may be replaced by the value of PREFIX_ABC_XYZ, and so forth -func (p *Parser) Parse(in []byte, v interface{}) error { +func (p *Parser) Parse(in []byte, v any) error { var versionedStruct struct { Version Version } @@ -191,7 +191,7 @@ func (p *Parser) overwriteFields(v reflect.Value, fullpath string, path []string return p.overwriteFields(v.Elem(), fullpath, path, payload) } // Interface was empty; create an implicit map - var template map[string]interface{} + var template map[string]any wrappedV := reflect.MakeMap(reflect.TypeOf(template)) v.Set(wrappedV) return p.overwriteMap(wrappedV, fullpath, path, payload) diff --git a/configuration/parser_test.go b/configuration/parser_test.go index 636f3291c..8b08fae90 100644 --- a/configuration/parser_test.go +++ b/configuration/parser_test.go @@ -45,8 +45,8 @@ func TestParserOverwriteIninitializedPoiner(t *testing.T) { p := NewParser("registry", []VersionedParseInfo{ { Version: "0.1", - ParseAs: reflect.TypeOf(config), - ConversionFunc: func(c interface{}) (interface{}, error) { + ParseAs: reflect.TypeFor[localConfiguration](), + ConversionFunc: func(c any) (any, error) { return c, nil }, }, @@ -78,8 +78,8 @@ func TestParseOverwriteUnininitializedPoiner(t *testing.T) { p := NewParser("registry", []VersionedParseInfo{ { Version: "0.1", - ParseAs: reflect.TypeOf(config), - ConversionFunc: func(c interface{}) (interface{}, error) { + ParseAs: reflect.TypeFor[localConfiguration](), + ConversionFunc: func(c any) (any, error) { return c, nil }, }, diff --git a/internal/client/auth/api_version.go b/internal/client/auth/api_version.go index 7d8f1d957..21200223b 100644 --- a/internal/client/auth/api_version.go +++ b/internal/client/auth/api_version.go @@ -29,7 +29,7 @@ func APIVersions(resp *http.Response, versionHeader string) []APIVersion { versions := []APIVersion{} if versionHeader != "" { for _, supportedVersions := range resp.Header[http.CanonicalHeaderKey(versionHeader)] { - for _, version := range strings.Fields(supportedVersions) { + for version := range strings.FieldsSeq(supportedVersions) { versions = append(versions, ParseAPIVersion(version)) } } diff --git a/internal/client/auth/challenge/authchallenge.go b/internal/client/auth/challenge/authchallenge.go index 4d26e5688..6d479c38f 100644 --- a/internal/client/auth/challenge/authchallenge.go +++ b/internal/client/auth/challenge/authchallenge.go @@ -35,7 +35,7 @@ func init() { // token = 1* // qdtext = > - for c := 0; c < 256; c++ { + for c := range 256 { var t octetType isCtl := c <= 31 || c == 127 isChar := 0 <= c && c <= 127 diff --git a/internal/client/auth/challenge/authchallenge_test.go b/internal/client/auth/challenge/authchallenge_test.go index 1117ab88c..e391e8c7e 100644 --- a/internal/client/auth/challenge/authchallenge_test.go +++ b/internal/client/auth/challenge/authchallenge_test.go @@ -102,7 +102,7 @@ func testAuthChallengeConcurrent(t *testing.T, host string) { s.Add(2) go func() { defer s.Done() - for i := 0; i < 200; i++ { + for range 200 { err = scm.AddResponse(resp) if err != nil { t.Error(err) @@ -113,7 +113,7 @@ func testAuthChallengeConcurrent(t *testing.T, host string) { defer s.Done() lowered := *url lowered.Host = strings.ToLower(lowered.Host) - for k := 0; k < 200; k++ { + for range 200 { _, err := scm.GetChallenges(lowered) if err != nil { t.Error(err) diff --git a/internal/client/auth/session.go b/internal/client/auth/session.go index 104290ab4..4f33a649e 100644 --- a/internal/client/auth/session.go +++ b/internal/client/auth/session.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/url" + "slices" "strings" "sync" "time" @@ -178,10 +179,10 @@ func (rs RegistryScope) String() string { // Logger defines the injectable logging interface, used on TokenHandlers. type Logger interface { - Debugf(format string, args ...interface{}) + Debugf(format string, args ...any) } -func logDebugf(logger Logger, format string, args ...interface{}) { +func logDebugf(logger Logger, format string, args ...any) { if logger == nil { return } @@ -305,12 +306,7 @@ func (th *tokenHandler) getToken(ctx context.Context, params map[string]string, } func hasScope(scopes []string, scope string) bool { - for _, s := range scopes { - if s == scope { - return true - } - } - return false + return slices.Contains(scopes, scope) } type postTokenResponse struct { diff --git a/internal/client/auth/session_test.go b/internal/client/auth/session_test.go index 3f49cfbb6..b5922bb28 100644 --- a/internal/client/auth/session_test.go +++ b/internal/client/auth/session_test.go @@ -221,11 +221,11 @@ func TestEndpointAuthorizeRefreshToken(t *testing.T) { Request: testutil.Request{ Method: http.MethodPost, Route: "/token", - Body: []byte(fmt.Sprintf("client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope1), service)), + Body: fmt.Appendf(nil, "client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope1), service), }, Response: testutil.Response{ StatusCode: http.StatusOK, - Body: []byte(fmt.Sprintf(`{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken1)), + Body: fmt.Appendf(nil, `{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken1), }, }, { @@ -233,18 +233,18 @@ func TestEndpointAuthorizeRefreshToken(t *testing.T) { Request: testutil.Request{ Method: http.MethodPost, Route: "/token", - Body: []byte(fmt.Sprintf("client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope2), service)), + Body: fmt.Appendf(nil, "client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope2), service), }, Response: testutil.Response{ StatusCode: http.StatusOK, - Body: []byte(fmt.Sprintf(`{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken2)), + Body: fmt.Appendf(nil, `{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken2), }, }, { Request: testutil.Request{ Method: http.MethodPost, Route: "/token", - Body: []byte(fmt.Sprintf("client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken2, url.QueryEscape(scope2), service)), + Body: fmt.Appendf(nil, "client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken2, url.QueryEscape(scope2), service), }, Response: testutil.Response{ StatusCode: http.StatusOK, @@ -375,11 +375,11 @@ func TestEndpointAuthorizeV2RefreshToken(t *testing.T) { Request: testutil.Request{ Method: http.MethodPost, Route: "/token", - Body: []byte(fmt.Sprintf("client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope1), service)), + Body: fmt.Appendf(nil, "client_id=registry-client&grant_type=refresh_token&refresh_token=%s&scope=%s&service=%s", refreshToken1, url.QueryEscape(scope1), service), }, Response: testutil.Response{ StatusCode: http.StatusOK, - Body: []byte(fmt.Sprintf(`{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken1)), + Body: fmt.Appendf(nil, `{"access_token":"statictoken","refresh_token":"%s"}`, refreshToken1), }, }, }) @@ -644,7 +644,7 @@ func TestEndpointAuthorizeTokenBasicWithExpiresIn(t *testing.T) { // First call should result in a token exchange // Subsequent calls should recycle the token from the first request, until the expiration has lapsed. timeIncrement := 1000 * time.Second - for i := 0; i < 4; i++ { + for i := range 4 { req, _ := http.NewRequest(http.MethodGet, e+"/v2/hello", nil) resp, err := client.Do(req) if err != nil { @@ -798,7 +798,7 @@ func TestEndpointAuthorizeTokenBasicWithExpiresInAndIssuedAt(t *testing.T) { // Subsequent calls should recycle the token from the first request, until the expiration has lapsed. // We shaved one increment off of the equivalent logic in TestEndpointAuthorizeTokenBasicWithExpiresIn // so this loop should have one fewer iteration. - for i := 0; i < 3; i++ { + for i := range 3 { req, _ := http.NewRequest(http.MethodGet, e+"/v2/hello", nil) resp, err := client.Do(req) if err != nil { diff --git a/internal/client/repository.go b/internal/client/repository.go index 27dc869f9..10937f63d 100644 --- a/internal/client/repository.go +++ b/internal/client/repository.go @@ -10,6 +10,7 @@ import ( "net/http" "net/url" "path" + "slices" "strconv" "strings" "time" @@ -45,14 +46,7 @@ func checkHTTPRedirect(req *http.Request, via []*http.Request) error { // Don't add to redirected request if redirected // request already has a header with the same // name and value. - hasValue := false - for _, existingVal := range req.Header[headerName] { - if existingVal == val { - hasValue = true - break - } - } - if !hasValue { + if !slices.Contains(req.Header[headerName], val) { req.Header.Add(headerName, val) } } @@ -739,16 +733,16 @@ func (bs *blobs) Put(ctx context.Context, mediaType string, p []byte) (v1.Descri }) } -type optionFunc func(interface{}) error +type optionFunc func(any) error -func (f optionFunc) Apply(v interface{}) error { +func (f optionFunc) Apply(v any) error { return f(v) } // WithMountFrom returns a BlobCreateOption which designates that the blob should be // mounted from the given canonical reference. func WithMountFrom(ref reference.Canonical) distribution.BlobCreateOption { - return optionFunc(func(v interface{}) error { + return optionFunc(func(v any) error { opts, ok := v.(*distribution.CreateOptions) if !ok { return fmt.Errorf("unexpected options type: %T", v) diff --git a/internal/client/repository_test.go b/internal/client/repository_test.go index 107cdcefa..50206e21b 100644 --- a/internal/client/repository_test.go +++ b/internal/client/repository_test.go @@ -919,7 +919,7 @@ func TestBlobMount(t *testing.T) { func newRandomOCIManifest(t *testing.T, blobCount int) (*ocischema.Manifest, digest.Digest, []byte) { layers := make([]v1.Descriptor, blobCount) - for i := 0; i < blobCount; i++ { + for i := range blobCount { dgst, blob := newRandomBlob((i % 5) * 16) layers[i] = v1.Descriptor{ MediaType: v1.MediaTypeImageLayer, @@ -1418,7 +1418,7 @@ func TestManifestTags(t *testing.T) { } `)) var m testutil.RequestResponseMap - for i := 0; i < 3; i++ { + for range 3 { m = append(m, testutil.RequestResponseMapping{ Request: testutil.Request{ Method: http.MethodGet, @@ -1581,8 +1581,8 @@ func TestManifestTagsPaginated(t *testing.T) { repo, _ := reference.WithName("test.example.com/repo/tags/list") tagsList := []string{"tag1", "tag2", "funtag"} var m testutil.RequestResponseMap - for i := 0; i < 3; i++ { - body, err := json.Marshal(map[string]interface{}{ + for i := range 3 { + body, err := json.Marshal(map[string]any{ "name": "test.example.com/repo/tags/list", "tags": []string{tagsList[i]}, }) @@ -1801,7 +1801,7 @@ func TestSanitizeLocation(t *testing.T) { expected: "https://mwhahaha.com/v2/foo/baasdf?_state=asdfasfdasdfasdf", }, } { - fatalf := func(format string, args ...interface{}) { + fatalf := func(format string, args ...any) { t.Fatalf(testcase.description+": "+format, args...) } diff --git a/internal/dcontext/context.go b/internal/dcontext/context.go index 40bd816f0..090d16820 100644 --- a/internal/dcontext/context.go +++ b/internal/dcontext/context.go @@ -16,7 +16,7 @@ type instanceContext struct { once sync.Once // once protect generation of the id } -func (ic *instanceContext) Value(key interface{}) interface{} { +func (ic *instanceContext) Value(key any) any { if key == "instance.id" { ic.once.Do(func() { // We want to lazy initialize the UUID such that we don't @@ -46,13 +46,13 @@ func Background() context.Context { // key, falling back to a parent if not present. type stringMapContext struct { context.Context - m map[string]interface{} + m map[string]any } // WithValues returns a context that proxies lookups through a map. Only // supports string keys. -func WithValues(ctx context.Context, m map[string]interface{}) context.Context { - mo := make(map[string]interface{}, len(m)) // make our own copy. +func WithValues(ctx context.Context, m map[string]any) context.Context { + mo := make(map[string]any, len(m)) // make our own copy. maps.Copy(mo, m) return stringMapContext{ @@ -61,7 +61,7 @@ func WithValues(ctx context.Context, m map[string]interface{}) context.Context { } } -func (smc stringMapContext) Value(key interface{}) interface{} { +func (smc stringMapContext) Value(key any) any { if ks, ok := key.(string); ok { if v, ok := smc.m[ks]; ok { return v diff --git a/internal/dcontext/http.go b/internal/dcontext/http.go index 34956b3f9..cd3e81fec 100644 --- a/internal/dcontext/http.go +++ b/internal/dcontext/http.go @@ -132,7 +132,7 @@ type httpRequestContext struct { // Value returns a keyed element of the request for use in the context. To get // the request itself, query "request". For other components, access them as // "request.". For example, r.RequestURI -func (ctx *httpRequestContext) Value(key interface{}) interface{} { +func (ctx *httpRequestContext) Value(key any) any { if keyStr, ok := key.(string); ok { switch keyStr { case "http.request": @@ -173,7 +173,7 @@ type muxVarsContext struct { vars map[string]string } -func (ctx *muxVarsContext) Value(key interface{}) interface{} { +func (ctx *muxVarsContext) Value(key any) any { if keyStr, ok := key.(string); ok { if keyStr == "vars" { return ctx.vars @@ -230,7 +230,7 @@ func (irw *instrumentedResponseWriter) Flush() { } } -func (irw *instrumentedResponseWriter) Value(key interface{}) interface{} { +func (irw *instrumentedResponseWriter) Value(key any) any { if keyStr, ok := key.(string); ok { switch keyStr { case "http.response": diff --git a/internal/dcontext/http_test.go b/internal/dcontext/http_test.go index 200d2ec61..afd301455 100644 --- a/internal/dcontext/http_test.go +++ b/internal/dcontext/http_test.go @@ -21,7 +21,7 @@ func TestWithRequest(t *testing.T) { ctx := WithRequest(Background(), &req) for _, tc := range []struct { key string - expected interface{} + expected any }{ { key: "http.request", @@ -194,7 +194,7 @@ func TestWithVars(t *testing.T) { ctx := WithVars(Background(), &req) for _, tc := range []struct { key string - expected interface{} + expected any }{ { key: "vars", diff --git a/internal/dcontext/logger.go b/internal/dcontext/logger.go index 058fc8310..d85928d19 100644 --- a/internal/dcontext/logger.go +++ b/internal/dcontext/logger.go @@ -17,34 +17,34 @@ var ( // Logger provides a leveled-logging interface. type Logger interface { // standard logger methods - Print(args ...interface{}) - Printf(format string, args ...interface{}) - Println(args ...interface{}) + Print(args ...any) + Printf(format string, args ...any) + Println(args ...any) - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) - Fatalln(args ...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) + Fatalln(args ...any) - Panic(args ...interface{}) - Panicf(format string, args ...interface{}) - Panicln(args ...interface{}) + Panic(args ...any) + Panicf(format string, args ...any) + Panicln(args ...any) // Leveled methods, from logrus - Debug(args ...interface{}) - Debugf(format string, args ...interface{}) - Debugln(args ...interface{}) + Debug(args ...any) + Debugf(format string, args ...any) + Debugln(args ...any) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) - Errorln(args ...interface{}) + Error(args ...any) + Errorf(format string, args ...any) + Errorln(args ...any) - Info(args ...interface{}) - Infof(format string, args ...interface{}) - Infoln(args ...interface{}) + Info(args ...any) + Infof(format string, args ...any) + Infoln(args ...any) - Warn(args ...interface{}) - Warnf(format string, args ...interface{}) - Warnln(args ...interface{}) + Warn(args ...any) + Warnf(format string, args ...any) + Warnln(args ...any) WithError(err error) *logrus.Entry } @@ -59,14 +59,14 @@ func WithLogger(ctx context.Context, logger Logger) context.Context { // GetLoggerWithField returns a logger instance with the specified field key // and value without affecting the context. Extra specified keys will be // resolved from the context. -func GetLoggerWithField(ctx context.Context, key, value interface{}, keys ...interface{}) Logger { +func GetLoggerWithField(ctx context.Context, key, value any, keys ...any) Logger { return getLogrusLogger(ctx, keys...).WithField(fmt.Sprint(key), value) } // GetLoggerWithFields returns a logger instance with the specified fields // without affecting the context. Extra specified keys will be resolved from // the context. -func GetLoggerWithFields(ctx context.Context, fields map[interface{}]interface{}, keys ...interface{}) Logger { +func GetLoggerWithFields(ctx context.Context, fields map[any]any, keys ...any) Logger { // must convert from interface{} -> interface{} to string -> interface{} for logrus. lfields := make(logrus.Fields, len(fields)) for key, value := range fields { @@ -82,7 +82,7 @@ func GetLoggerWithFields(ctx context.Context, fields map[interface{}]interface{} // argument passed to GetLogger will be passed to fmt.Sprint when expanded as // a logging key field. If context keys are integer constants, for example, // its recommended that a String method is implemented. -func GetLogger(ctx context.Context, keys ...interface{}) Logger { +func GetLogger(ctx context.Context, keys ...any) Logger { return getLogrusLogger(ctx, keys...) } @@ -102,7 +102,7 @@ func SetDefaultLogger(logger Logger) { // are provided, they will be resolved on the context and included in the // logger. Only use this function if specific logrus functionality is // required. -func getLogrusLogger(ctx context.Context, keys ...interface{}) *logrus.Entry { +func getLogrusLogger(ctx context.Context, keys ...any) *logrus.Entry { var logger *logrus.Entry // Get a logger, if it is present. diff --git a/internal/dcontext/trace.go b/internal/dcontext/trace.go index 1ba764531..de90c2744 100644 --- a/internal/dcontext/trace.go +++ b/internal/dcontext/trace.go @@ -37,7 +37,7 @@ import ( // // Notice that the function name is automatically resolved, along with the // package and a trace id is emitted that can be linked with parent ids. -func WithTrace(ctx context.Context) (context.Context, func(format string, a ...interface{})) { +func WithTrace(ctx context.Context) (context.Context, func(format string, a ...any)) { if ctx == nil { ctx = Background() } @@ -54,7 +54,7 @@ func WithTrace(ctx context.Context) (context.Context, func(format string, a ...i line: line, } - return ctx, func(format string, a ...interface{}) { + return ctx, func(format string, a ...any) { GetLogger(ctx, "trace.duration", "trace.id", @@ -79,7 +79,7 @@ type traced struct { line int } -func (ts *traced) Value(key interface{}) interface{} { +func (ts *traced) Value(key any) any { switch key { case "trace.start": return ts.start diff --git a/internal/dcontext/trace_test.go b/internal/dcontext/trace_test.go index 590ad36fc..bf7c796b4 100644 --- a/internal/dcontext/trace_test.go +++ b/internal/dcontext/trace_test.go @@ -96,6 +96,6 @@ func TestWithTrace(t *testing.T) { type valueTestCase struct { key string - expected interface{} + expected any notnilorempty bool // just check not empty/not nil } diff --git a/internal/dcontext/util.go b/internal/dcontext/util.go index 5b32ba16f..ef8557cb6 100644 --- a/internal/dcontext/util.go +++ b/internal/dcontext/util.go @@ -8,7 +8,7 @@ import ( // Since looks up key, which should be a time.Time, and returns the duration // since that time. If the key is not found, the value returned will be zero. // This is helpful when inferring metrics related to context execution times. -func Since(ctx context.Context, key interface{}) time.Duration { +func Since(ctx context.Context, key any) time.Duration { if startedAt, ok := ctx.Value(key).(time.Time); ok { return time.Since(startedAt) } @@ -17,7 +17,7 @@ func Since(ctx context.Context, key interface{}) time.Duration { // GetStringValue returns a string value from the context. The empty string // will be returned if not found. -func GetStringValue(ctx context.Context, key interface{}) (value string) { +func GetStringValue(ctx context.Context, key any) (value string) { if valuev, ok := ctx.Value(key).(string); ok { value = valuev } diff --git a/manifest/manifestlist/manifestlist.go b/manifest/manifestlist/manifestlist.go index 4752331ab..ecf966480 100644 --- a/manifest/manifestlist/manifestlist.go +++ b/manifest/manifestlist/manifestlist.go @@ -196,8 +196,8 @@ func (m DeserializedManifestList) Payload() (string, []byte, error) { // contains fields that belong to a manifest func validateManifestList(b []byte) error { var doc struct { - Config interface{} `json:"config,omitempty"` - Layers interface{} `json:"layers,omitempty"` + Config any `json:"config,omitempty"` + Layers any `json:"layers,omitempty"` } if err := json.Unmarshal(b, &doc); err != nil { return err diff --git a/manifest/ocischema/index.go b/manifest/ocischema/index.go index add766f3e..df2da46c3 100644 --- a/manifest/ocischema/index.go +++ b/manifest/ocischema/index.go @@ -151,8 +151,8 @@ func (m DeserializedImageIndex) Payload() (string, []byte, error) { // contains fields that belong to a manifest func validateIndex(b []byte) error { var doc struct { - Config interface{} `json:"config,omitempty"` - Layers interface{} `json:"layers,omitempty"` + Config any `json:"config,omitempty"` + Layers any `json:"layers,omitempty"` } if err := json.Unmarshal(b, &doc); err != nil { return err diff --git a/manifest/ocischema/manifest.go b/manifest/ocischema/manifest.go index 2009e2f5a..05c901f18 100644 --- a/manifest/ocischema/manifest.go +++ b/manifest/ocischema/manifest.go @@ -141,7 +141,7 @@ func (m *DeserializedManifest) Payload() (string, []byte, error) { // contains fields that belong to a index func validateManifest(b []byte) error { var doc struct { - Manifests interface{} `json:"manifests,omitempty"` + Manifests any `json:"manifests,omitempty"` } if err := json.Unmarshal(b, &doc); err != nil { return err diff --git a/notifications/event.go b/notifications/event.go index 98dd9faf0..fff87966e 100644 --- a/notifications/event.go +++ b/notifications/event.go @@ -45,7 +45,7 @@ type Event struct { ID string `json:"id,omitempty"` // Timestamp is the time at which the event occurred. - Timestamp time.Time `json:"timestamp,omitempty"` + Timestamp time.Time `json:"timestamp"` // Action indicates what action encompasses the provided event. Action string `json:"action,omitempty"` @@ -75,19 +75,19 @@ type Event struct { // References provides the references descriptors. References []v1.Descriptor `json:"references,omitempty"` - } `json:"target,omitempty"` + } `json:"target"` // Request covers the request that generated the event. - Request RequestRecord `json:"request,omitempty"` + Request RequestRecord `json:"request"` // Actor specifies the agent that initiated the event. For most // situations, this could be from the authorization context of the request. - Actor ActorRecord `json:"actor,omitempty"` + Actor ActorRecord `json:"actor"` // Source identifies the registry node that generated the event. Put // differently, while the actor "initiates" the event, the source // "generates" it. - Source SourceRecord `json:"source,omitempty"` + Source SourceRecord `json:"source"` } // ActorRecord specifies the agent that initiated the event. For most diff --git a/notifications/listener_test.go b/notifications/listener_test.go index aa053f806..590b97566 100644 --- a/notifications/listener_test.go +++ b/notifications/listener_test.go @@ -153,7 +153,7 @@ func checkTestRepository(t *testing.T, repository distribution.Repository, remov }, } - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatalf("error creating test layer: %v", err) diff --git a/notifications/metrics.go b/notifications/metrics.go index f85282441..0495eb7ef 100644 --- a/notifications/metrics.go +++ b/notifications/metrics.go @@ -39,15 +39,15 @@ func init() { var notifications expvar.Map notifications.Init() - notifications.Set("endpoints", expvar.Func(func() interface{} { + notifications.Set("endpoints", expvar.Func(func() any { endpoints.mu.Lock() defer endpoints.mu.Unlock() - var names []interface{} + var names []any if len(endpoints.registered) == 0 { return names } - names = make([]interface{}, 0, len(endpoints.registered)) + names = make([]any, 0, len(endpoints.registered)) for _, v := range endpoints.registered { var epjson struct { Name string `json:"name"` diff --git a/notifications/metrics_test.go b/notifications/metrics_test.go index 03a08e2c8..e023f709c 100644 --- a/notifications/metrics_test.go +++ b/notifications/metrics_test.go @@ -9,7 +9,7 @@ import ( func TestMetricsExpvar(t *testing.T) { endpointsVar := expvar.Get("registry").(*expvar.Map).Get("notifications").(*expvar.Map).Get("endpoints") - var v interface{} + var v any if err := json.Unmarshal([]byte(endpointsVar.String()), &v); err != nil { t.Fatalf("unexpected error unmarshaling endpoints: %v", err) } @@ -22,7 +22,7 @@ func TestMetricsExpvar(t *testing.T) { if err := json.Unmarshal([]byte(endpointsVar.String()), &v); err != nil { t.Fatalf("unexpected error unmarshaling endpoints: %v", err) } - if slice, ok := v.([]interface{}); !ok || len(slice) != 1 { + if slice, ok := v.([]any); !ok || len(slice) != 1 { t.Logf("expected one-element []interface{}, got %#v", v) } } diff --git a/registry/api/errcode/errors.go b/registry/api/errcode/errors.go index 9cecc23d3..31ed53848 100644 --- a/registry/api/errcode/errors.go +++ b/registry/api/errcode/errors.go @@ -80,7 +80,7 @@ func (ec ErrorCode) WithMessage(message string) Error { // WithDetail creates a new Error struct based on the passed-in info and // set the Detail property appropriately -func (ec ErrorCode) WithDetail(detail interface{}) Error { +func (ec ErrorCode) WithDetail(detail any) Error { return Error{ Code: ec, Message: ec.Message(), @@ -88,7 +88,7 @@ func (ec ErrorCode) WithDetail(detail interface{}) Error { } // WithArgs creates a new Error struct and sets the Args slice -func (ec ErrorCode) WithArgs(args ...interface{}) Error { +func (ec ErrorCode) WithArgs(args ...any) Error { return Error{ Code: ec, Message: ec.Message(), @@ -97,9 +97,9 @@ func (ec ErrorCode) WithArgs(args ...interface{}) Error { // Error provides a wrapper around ErrorCode with extra Details provided. type Error struct { - Code ErrorCode `json:"code"` - Message string `json:"message"` - Detail interface{} `json:"detail,omitempty"` + Code ErrorCode `json:"code"` + Message string `json:"message"` + Detail any `json:"detail,omitempty"` // TODO(duglin): See if we need an "args" property so we can do the // variable substitution right before showing the message to the user @@ -119,7 +119,7 @@ func (e Error) Error() string { // WithDetail will return a new Error, based on the current one, but with // some Detail info added -func (e Error) WithDetail(detail interface{}) Error { +func (e Error) WithDetail(detail any) Error { return Error{ Code: e.Code, Message: e.Message, @@ -129,7 +129,7 @@ func (e Error) WithDetail(detail interface{}) Error { // WithArgs uses the passed-in list of interface{} as the substitution // variables in the Error's Message string, but returns a new Error -func (e Error) WithArgs(args ...interface{}) Error { +func (e Error) WithArgs(args ...any) Error { return Error{ Code: e.Code, Message: fmt.Sprintf(e.Code.Message(), args...), @@ -184,11 +184,12 @@ func (errs Errors) Error() string { case 1: return errs[0].Error() default: - msg := "errors:\n" + var msg strings.Builder + msg.WriteString("errors:\n") for _, err := range errs { - msg += err.Error() + "\n" + msg.WriteString(err.Error() + "\n") } - return msg + return msg.String() } } diff --git a/registry/api/errcode/errors_test.go b/registry/api/errcode/errors_test.go index 6da99cb31..83b9fd46b 100644 --- a/registry/api/errcode/errors_test.go +++ b/registry/api/errcode/errors_test.go @@ -66,7 +66,7 @@ func TestErrorCodes(t *testing.T) { } // First, unmarshal to interface and ensure we have a string. - var ecUnspecified interface{} + var ecUnspecified any if err := json.Unmarshal(p, &ecUnspecified); err != nil { t.Fatalf("error unmarshaling error code %v: %v", ec, err) } @@ -98,7 +98,7 @@ func TestErrorsManagement(t *testing.T) { errs = append(errs, ErrorCodeTest1) errs = append(errs, ErrorCodeTest2.WithDetail( - map[string]interface{}{"digest": "sometestblobsumdoesntmatter"})) + map[string]any{"digest": "sometestblobsumdoesntmatter"})) errs = append(errs, ErrorCodeTest3.WithArgs("BOOGIE")) errs = append(errs, ErrorCodeTest3.WithArgs("BOOGIE").WithDetail("data")) diff --git a/registry/auth/auth.go b/registry/auth/auth.go index 687002c3b..954496676 100644 --- a/registry/auth/auth.go +++ b/registry/auth/auth.go @@ -47,7 +47,7 @@ var ( // InitFunc is the type of an AccessController factory function and is used // to register the constructor for different AccessController backends. -type InitFunc func(options map[string]interface{}) (AccessController, error) +type InitFunc func(options map[string]any) (AccessController, error) var accessControllers map[string]InitFunc @@ -128,7 +128,7 @@ func Register(name string, initFunc InitFunc) error { // GetAccessController constructs an AccessController // with the given options using the named backend. -func GetAccessController(name string, options map[string]interface{}) (AccessController, error) { +func GetAccessController(name string, options map[string]any) (AccessController, error) { if initFunc, exists := accessControllers[name]; exists { return initFunc(options) } diff --git a/registry/auth/htpasswd/access.go b/registry/auth/htpasswd/access.go index 58cd8588f..71ff09410 100644 --- a/registry/auth/htpasswd/access.go +++ b/registry/auth/htpasswd/access.go @@ -39,7 +39,7 @@ type accessController struct { var _ auth.AccessController = &accessController{} -func newAccessController(options map[string]interface{}) (auth.AccessController, error) { +func newAccessController(options map[string]any) (auth.AccessController, error) { realm, present := options["realm"] if _, ok := realm.(string); !present || !ok { return nil, fmt.Errorf(`"realm" must be set for htpasswd access controller`) @@ -150,7 +150,7 @@ func createHtpasswdFile(path string) error { if _, err := fmt.Fprintf(f, "docker:%s", string(encryptedPass[:])); err != nil { return err } - dcontext.GetLoggerWithFields(context.Background(), map[interface{}]interface{}{ + dcontext.GetLoggerWithFields(context.Background(), map[any]any{ "user": "docker", "password": pass, }).Warnf("htpasswd is missing, provisioning with default user") diff --git a/registry/auth/htpasswd/access_test.go b/registry/auth/htpasswd/access_test.go index 01f2ac9d7..df830a2cc 100644 --- a/registry/auth/htpasswd/access_test.go +++ b/registry/auth/htpasswd/access_test.go @@ -28,7 +28,7 @@ func TestBasicAccessController(t *testing.T) { t.Fatal("could not write temporary htpasswd file") } - options := map[string]interface{}{ + options := map[string]any{ "realm": testRealm, "path": tempFile.Name(), } @@ -87,7 +87,7 @@ func TestBasicAccessController(t *testing.T) { "DeokMan": {}, } - for i := 0; i < len(testUsers); i++ { + for i := range testUsers { userNumber = i req, err := http.NewRequest(http.MethodGet, server.URL, nil) if err != nil { @@ -123,7 +123,7 @@ func TestCreateHtpasswdFile(t *testing.T) { t.Fatalf("could not create temporary htpasswd file %v", err) } defer tempFile.Close() - options := map[string]interface{}{ + options := map[string]any{ "realm": "/auth/htpasswd", "path": tempFile.Name(), } diff --git a/registry/auth/silly/access.go b/registry/auth/silly/access.go index c732fc5e1..7dffa0338 100644 --- a/registry/auth/silly/access.go +++ b/registry/auth/silly/access.go @@ -33,7 +33,7 @@ type accessController struct { var _ auth.AccessController = &accessController{} -func newAccessController(options map[string]interface{}) (auth.AccessController, error) { +func newAccessController(options map[string]any) (auth.AccessController, error) { realm, present := options["realm"] if _, ok := realm.(string); !present || !ok { return nil, fmt.Errorf(`"realm" must be set for silly access controller`) diff --git a/registry/auth/token/accesscontroller.go b/registry/auth/token/accesscontroller.go index a71846fc4..5a07bb565 100644 --- a/registry/auth/token/accesscontroller.go +++ b/registry/auth/token/accesscontroller.go @@ -181,7 +181,7 @@ type tokenAccessOptions struct { // checkOptions gathers the necessary options // for an accessController from the given map. -func checkOptions(options map[string]interface{}) (tokenAccessOptions, error) { +func checkOptions(options map[string]any) (tokenAccessOptions, error) { var opts tokenAccessOptions keys := []string{"realm", "issuer", "service", "rootcertbundle", "jwks"} @@ -229,7 +229,7 @@ func checkOptions(options map[string]interface{}) (tokenAccessOptions, error) { signingAlgos, ok := options["signingalgorithms"] if ok { - signingAlgorithmsVals, ok := signingAlgos.([]interface{}) + signingAlgorithmsVals, ok := signingAlgos.([]any) if !ok { return tokenAccessOptions{}, errors.New("signingalgorithms must be a list of signing algorithms") } @@ -317,7 +317,7 @@ func getSigningAlgorithms(algos []string) ([]jose.SignatureAlgorithm, error) { } // newAccessController creates an accessController using the given options. -func newAccessController(options map[string]interface{}) (auth.AccessController, error) { +func newAccessController(options map[string]any) (auth.AccessController, error) { config, err := checkOptions(options) if err != nil { return nil, err diff --git a/registry/auth/token/accesscontroller_test.go b/registry/auth/token/accesscontroller_test.go index ba3d0a37a..8e7e7c4b7 100644 --- a/registry/auth/token/accesscontroller_test.go +++ b/registry/auth/token/accesscontroller_test.go @@ -54,7 +54,7 @@ func TestCheckOptions(t *testing.T) { issuer := "test-issuer.example.com" service := "test-service.example.com" - options := map[string]interface{}{ + options := map[string]any{ "realm": realm, "issuer": issuer, "service": service, @@ -74,7 +74,7 @@ func TestCheckOptions(t *testing.T) { t.Fatal("autoredirectpath should be /auth") } - options = map[string]interface{}{ + options = map[string]any{ "realm": realm, "issuer": issuer, "service": service, @@ -127,7 +127,7 @@ func TestRootCertIncludedInTrustedKeys(t *testing.T) { issuer := "test-issuer.example.com" service := "test-service.example.com" - options := map[string]interface{}{ + options := map[string]any{ "realm": realm, "issuer": issuer, "service": service, @@ -157,7 +157,7 @@ func TestJWKSIncludedInTrustedKeys(t *testing.T) { issuer := "test-issuer.example.com" service := "test-service.example.com" - options := map[string]interface{}{ + options := map[string]any{ "realm": realm, "issuer": issuer, "service": service, diff --git a/registry/auth/token/token_test.go b/registry/auth/token/token_test.go index ba9f073cb..5f6b48799 100644 --- a/registry/auth/token/token_test.go +++ b/registry/auth/token/token_test.go @@ -26,7 +26,7 @@ import ( func makeRootKeys(numKeys int) ([]*ecdsa.PrivateKey, error) { rootKeys := make([]*ecdsa.PrivateKey, 0, numKeys) - for i := 0; i < numKeys; i++ { + for range numKeys { pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return nil, err @@ -251,7 +251,7 @@ func TestTokenVerify(t *testing.T) { tokens := make([]*Token, 0, numTokens) trustedKeys := map[string]crypto.PublicKey{} - for i := 0; i < numTokens; i++ { + for i := range numTokens { jwk, err := makeSigningKeyWithChain(rootKeys[i], i) if err != nil { t.Fatal(err) @@ -437,7 +437,7 @@ func TestAccessController(t *testing.T) { issuer := "test-issuer.example.com" service := "test-service.example.com" - options := map[string]interface{}{ + options := map[string]any{ "realm": realm, "issuer": issuer, "service": service, @@ -629,7 +629,7 @@ func TestNewAccessControllerPemBlock(t *testing.T) { issuer := "test-issuer.example.com" service := "test-service.example.com" - options := map[string]interface{}{ + options := map[string]any{ "realm": realm, "issuer": issuer, "service": service, diff --git a/registry/auth/token/types.go b/registry/auth/token/types.go index 2aa5c9bab..b3415152a 100644 --- a/registry/auth/token/types.go +++ b/registry/auth/token/types.go @@ -9,7 +9,7 @@ import ( type AudienceList []string func (s *AudienceList) UnmarshalJSON(data []byte) (err error) { - var value interface{} + var value any if err = json.Unmarshal(data, &value); err != nil { return err @@ -22,7 +22,7 @@ func (s *AudienceList) UnmarshalJSON(data []byte) (err error) { case []string: *s = v - case []interface{}: + case []any: var ss []string for _, vv := range v { diff --git a/registry/auth/token/util.go b/registry/auth/token/util.go index 0cff486c0..3a796c84f 100644 --- a/registry/auth/token/util.go +++ b/registry/auth/token/util.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "fmt" "math/big" + "slices" ) // actionSet is a special type of stringSet. @@ -28,13 +29,7 @@ func (s actionSet) contains(action string) bool { // contains returns true if q is found in ss. func contains(ss []string, q string) bool { - for _, s := range ss { - if s == q { - return true - } - } - - return false + return slices.Contains(ss, q) } // containsAny returns true if any of q is found in ss. diff --git a/registry/handlers/api_test.go b/registry/handlers/api_test.go index bdbf4b111..9cf825115 100644 --- a/registry/handlers/api_test.go +++ b/registry/handlers/api_test.go @@ -15,6 +15,7 @@ import ( "path" "reflect" "regexp" + "slices" "strconv" "strings" "testing" @@ -631,19 +632,14 @@ func checkLink(t *testing.T, urlStr string, numEntries int, last string) url.Val } func contains(elems []string, e string) bool { - for _, elem := range elems { - if elem == e { - return true - } - } - return false + return slices.Contains(elems, e) } func TestURLPrefix(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -726,7 +722,7 @@ func TestRelativeURL(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -1405,7 +1401,7 @@ const ( repositoryWithGenericStorageError = "genericstorageerr" ) -func (factory *storageManifestErrDriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *storageManifestErrDriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { // Initialize the mock driver errGenericStorage := errors.New("generic storage error") return &mockErrorDriver{ @@ -1460,7 +1456,7 @@ func TestGetManifestWithStorageError(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ "storagemanifesterror": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -2231,7 +2227,7 @@ func newTestEnvMirror(t *testing.T, deleteEnabled bool) *testEnv { Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, "delete": configuration.Parameters{"enabled": deleteEnabled}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -2251,7 +2247,7 @@ func newTestEnv(t *testing.T, deleteEnabled bool) *testEnv { Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, "delete": configuration.Parameters{"enabled": deleteEnabled}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -2289,7 +2285,7 @@ func (t *testEnv) Shutdown() { t.server.Close() } -func putManifest(t *testing.T, msg, url, contentType string, v interface{}) *http.Response { +func putManifest(t *testing.T, msg, url, contentType string, v any) *http.Response { var body []byte switch m := v.(type) { @@ -2805,7 +2801,7 @@ func TestProxyManifestGetByTag(t *testing.T) { truthConfig := configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, diff --git a/registry/handlers/app.go b/registry/handlers/app.go index 73c8430c1..02350969a 100644 --- a/registry/handlers/app.go +++ b/registry/handlers/app.go @@ -131,13 +131,13 @@ func NewApp(ctx context.Context, config *configuration.Configuration) *App { purgeConfig := uploadPurgeDefaultConfig() if mc, ok := config.Storage["maintenance"]; ok { if v, ok := mc["uploadpurging"]; ok { - purgeConfig, ok = v.(map[interface{}]interface{}) + purgeConfig, ok = v.(map[any]any) if !ok { panic("uploadpurging config key must contain additional keys") } } if v, ok := mc["readonly"]; ok { - readOnly, ok := v.(map[interface{}]interface{}) + readOnly, ok := v.(map[any]any) if !ok { panic("readonly config key must contain additional keys") } @@ -611,9 +611,9 @@ func (app *App) configureRedis(cfg *configuration.Configuration) { registry = expvar.NewMap("registry") } - registry.(*expvar.Map).Set("redis", expvar.Func(func() interface{} { + registry.(*expvar.Map).Set("redis", expvar.Func(func() any { stats := app.redis.PoolStats() - return map[string]interface{}{ + return map[string]any{ "Config": cfg, "Active": stats.TotalConns - stats.IdleConns, } @@ -1047,8 +1047,8 @@ func applyStorageMiddleware(ctx context.Context, driver storagedriver.StorageDri // uploadPurgeDefaultConfig provides a default configuration for upload // purging to be used in the absence of configuration in the // configuration file -func uploadPurgeDefaultConfig() map[interface{}]interface{} { - config := map[interface{}]interface{}{} +func uploadPurgeDefaultConfig() map[any]any { + config := map[any]any{} config["enabled"] = true config["age"] = "168h" config["interval"] = "24h" @@ -1062,7 +1062,7 @@ func badPurgeUploadConfig(reason string) { // startUploadPurger schedules a goroutine which will periodically // check upload directories for old files and delete them -func startUploadPurger(ctx context.Context, storageDriver storagedriver.StorageDriver, log dcontext.Logger, config map[interface{}]interface{}) { +func startUploadPurger(ctx context.Context, storageDriver storagedriver.StorageDriver, log dcontext.Logger, config map[any]any) { if config["enabled"] == false { return } diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go index 7725df83a..6e045fcbc 100644 --- a/registry/handlers/app_test.go +++ b/registry/handlers/app_test.go @@ -143,7 +143,7 @@ func TestNewApp(t *testing.T) { config := configuration.Configuration{ Storage: configuration.Storage{ "inmemory": nil, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, diff --git a/registry/handlers/context.go b/registry/handlers/context.go index c272095c8..acc84223d 100644 --- a/registry/handlers/context.go +++ b/registry/handlers/context.go @@ -42,7 +42,7 @@ type Context struct { // Value overrides context.Context.Value to ensure that calls are routed to // correct context. -func (ctx *Context) Value(key interface{}) interface{} { +func (ctx *Context) Value(key any) any { return ctx.Context.Value(key) } @@ -117,7 +117,7 @@ type userInfoContext struct { user auth.UserInfo } -func (uic userInfoContext) Value(key interface{}) interface{} { +func (uic userInfoContext) Value(key any) any { switch key { case userKey: return uic.user @@ -143,7 +143,7 @@ type resourceContext struct { type resourceKey struct{} -func (rc resourceContext) Value(key interface{}) interface{} { +func (rc resourceContext) Value(key any) any { if key == (resourceKey{}) { return rc.resources } diff --git a/registry/handlers/health_test.go b/registry/handlers/health_test.go index 079ebda51..52b197549 100644 --- a/registry/handlers/health_test.go +++ b/registry/handlers/health_test.go @@ -26,7 +26,7 @@ func TestFileHealthCheck(t *testing.T) { config := &configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -89,7 +89,7 @@ func TestTCPHealthCheck(t *testing.T) { config := &configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, @@ -151,7 +151,7 @@ func TestHTTPHealthCheck(t *testing.T) { config := &configuration.Configuration{ Storage: configuration.Storage{ "inmemory": configuration.Parameters{}, - "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{ + "maintenance": configuration.Parameters{"uploadpurging": map[any]any{ "enabled": false, }}, }, diff --git a/registry/handlers/helpers.go b/registry/handlers/helpers.go index 3ccba5558..b1bdea34d 100644 --- a/registry/handlers/helpers.go +++ b/registry/handlers/helpers.go @@ -50,7 +50,7 @@ func copyFullPayload(ctx context.Context, responseWriter http.ResponseWriter, r // instead of showing 0 for the HTTP status. responseWriter.WriteHeader(499) - dcontext.GetLoggerWithFields(ctx, map[interface{}]interface{}{ + dcontext.GetLoggerWithFields(ctx, map[any]any{ "error": err, "copied": copied, "contentLength": r.ContentLength, diff --git a/registry/handlers/manifests.go b/registry/handlers/manifests.go index 391aa920b..c37188335 100644 --- a/registry/handlers/manifests.go +++ b/registry/handlers/manifests.go @@ -5,6 +5,7 @@ import ( "fmt" "mime" "net/http" + "slices" "strings" "sync" @@ -95,7 +96,7 @@ func (imh *manifestHandler) GetManifest(w http.ResponseWriter, r *http.Request) // we need to split each header value on "," to get the full list of "Accept" values (per RFC 2616) // https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 - for _, mediaType := range strings.Split(acceptHeader, ",") { + for mediaType := range strings.SplitSeq(acceptHeader, ",") { if mediaType, _, err = mime.ParseMediaType(mediaType); err != nil { continue } @@ -395,11 +396,8 @@ func (imh *manifestHandler) applyResourcePolicy(manifest distribution.Manifest) // Check to see if class is allowed in registry var allowedClass bool - for _, c := range allowedClasses { - if class == c { - allowedClass = true - break - } + if slices.Contains(allowedClasses, class) { + allowedClass = true } if !allowedClass { return errcode.ErrorCodeDenied.WithMessage(fmt.Sprintf("registry does not allow %s manifest", class)) diff --git a/registry/middleware/registry/middleware.go b/registry/middleware/registry/middleware.go index 16552a319..538210645 100644 --- a/registry/middleware/registry/middleware.go +++ b/registry/middleware/registry/middleware.go @@ -11,7 +11,7 @@ import ( // InitFunc is the type of a RegistryMiddleware factory function and is // used to register the constructor for different RegistryMiddleware backends. -type InitFunc func(ctx context.Context, registry distribution.Namespace, driver storagedriver.StorageDriver, options map[string]interface{}) (distribution.Namespace, error) +type InitFunc func(ctx context.Context, registry distribution.Namespace, driver storagedriver.StorageDriver, options map[string]any) (distribution.Namespace, error) var ( middlewares map[string]InitFunc @@ -34,7 +34,7 @@ func Register(name string, initFunc InitFunc) error { } // Get constructs a RegistryMiddleware with the given options using the named backend. -func Get(ctx context.Context, name string, options map[string]interface{}, registry distribution.Namespace, driver storagedriver.StorageDriver) (distribution.Namespace, error) { +func Get(ctx context.Context, name string, options map[string]any, registry distribution.Namespace, driver storagedriver.StorageDriver) (distribution.Namespace, error) { if middlewares != nil { if initFunc, exists := middlewares[name]; exists { return initFunc(ctx, registry, driver, options) diff --git a/registry/middleware/repository/middleware.go b/registry/middleware/repository/middleware.go index 8c1cc8ef7..ca136d9f6 100644 --- a/registry/middleware/repository/middleware.go +++ b/registry/middleware/repository/middleware.go @@ -9,7 +9,7 @@ import ( // InitFunc is the type of a RepositoryMiddleware factory function and is // used to register the constructor for different RepositoryMiddleware backends. -type InitFunc func(ctx context.Context, repository distribution.Repository, options map[string]interface{}) (distribution.Repository, error) +type InitFunc func(ctx context.Context, repository distribution.Repository, options map[string]any) (distribution.Repository, error) var middlewares map[string]InitFunc @@ -29,7 +29,7 @@ func Register(name string, initFunc InitFunc) error { } // Get constructs a RepositoryMiddleware with the given options using the named backend. -func Get(ctx context.Context, name string, options map[string]interface{}, repository distribution.Repository) (distribution.Repository, error) { +func Get(ctx context.Context, name string, options map[string]any, repository distribution.Repository) (distribution.Repository, error) { if middlewares != nil { if initFunc, exists := middlewares[name]; exists { return initFunc(ctx, repository, options) diff --git a/registry/proxy/proxyauth_exec_test.go b/registry/proxy/proxyauth_exec_test.go index 50fa942b9..df69b3627 100644 --- a/registry/proxy/proxyauth_exec_test.go +++ b/registry/proxy/proxyauth_exec_test.go @@ -18,7 +18,7 @@ type testHelper struct { } func (h *testHelper) Output() ([]byte, error) { - return []byte(fmt.Sprintf(`{"Username":%q,"Secret":%q}`, h.username, h.secret)), h.err + return fmt.Appendf(nil, `{"Username":%q,"Secret":%q}`, h.username, h.secret), h.err } func (h *testHelper) Input(in io.Reader) { diff --git a/registry/proxy/proxyblobstore_test.go b/registry/proxy/proxyblobstore_test.go index 1485cefa0..0418d90e9 100644 --- a/registry/proxy/proxyblobstore_test.go +++ b/registry/proxy/proxyblobstore_test.go @@ -134,7 +134,7 @@ func makeTestEnv(t *testing.T, name string) *testEnv { truthDir := t.TempDir() cacheDir := t.TempDir() - localDriver, err := filesystem.FromParameters(map[string]interface{}{ + localDriver, err := filesystem.FromParameters(map[string]any{ "rootdirectory": truthDir, }) if err != nil { @@ -151,7 +151,7 @@ func makeTestEnv(t *testing.T, name string) *testEnv { t.Fatalf("unexpected error getting repo: %v", err) } - cacheDriver, err := filesystem.FromParameters(map[string]interface{}{ + cacheDriver, err := filesystem.FromParameters(map[string]any{ "rootdirectory": cacheDir, }) if err != nil { @@ -196,7 +196,7 @@ func makeTestEnv(t *testing.T, name string) *testEnv { func makeBlob(size int) []byte { blob := make([]byte, size) - for i := 0; i < size; i++ { + for i := range size { blob[i] = byte('A' + randSource.Int()%48) } return blob @@ -205,7 +205,7 @@ func makeBlob(size int) []byte { func populate(t *testing.T, te *testEnv, blobCount, size, numUnique int) { var inRemote []v1.Descriptor - for i := 0; i < numUnique; i++ { + for range numUnique { bytes := makeBlob(size) for j := 0; j < blobCount/numUnique; j++ { desc, err := te.store.remoteStore.Put(te.ctx, "", bytes) @@ -430,7 +430,7 @@ func testProxyStoreServe(t *testing.T, te *testEnv, numClients int) { descHitMap[remoteBlob.Digest] = true } - for i := 0; i < numClients; i++ { + for range numClients { // Serveblob - pulls through blobs wg.Add(1) go func() { diff --git a/registry/proxy/proxymanifeststore_test.go b/registry/proxy/proxymanifeststore_test.go index fdf563173..063d805c7 100644 --- a/registry/proxy/proxymanifeststore_test.go +++ b/registry/proxy/proxymanifeststore_test.go @@ -165,7 +165,7 @@ func populateRepo(ctx context.Context, t *testing.T, repository distribution.Rep }, } - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatal("unexpected error generating test layer file") diff --git a/registry/proxy/proxymetrics.go b/registry/proxy/proxymetrics.go index 0b492fe12..660618f0e 100644 --- a/registry/proxy/proxymetrics.go +++ b/registry/proxy/proxymetrics.go @@ -53,11 +53,11 @@ func init() { registry.(*expvar.Map).Set("proxy", pm) } - pm.(*expvar.Map).Set("blobs", expvar.Func(func() interface{} { + pm.(*expvar.Map).Set("blobs", expvar.Func(func() any { return proxyMetrics.blobMetrics })) - pm.(*expvar.Map).Set("manifests", expvar.Func(func() interface{} { + pm.(*expvar.Map).Set("manifests", expvar.Func(func() any { return proxyMetrics.manifestMetrics })) diff --git a/registry/registry.go b/registry/registry.go index 29fc1c401..6801e4c57 100644 --- a/registry/registry.go +++ b/registry/registry.go @@ -416,7 +416,7 @@ func configureLogging(ctx context.Context, config *configuration.Configuration) logrus.Debugf("using %q logging formatter", formatter) if len(config.Log.Fields) > 0 { // build up the static fields, if present. - var fields []interface{} + var fields []any for k := range config.Log.Fields { fields = append(fields, k) } diff --git a/registry/registry_test.go b/registry/registry_test.go index f37cd0e89..e03f19dd4 100644 --- a/registry/registry_test.go +++ b/registry/registry_test.go @@ -71,7 +71,7 @@ func setupRegistry(tlsCfg *registryTLSConfig, addr string) (*Registry, error) { config.HTTP.TLS.Certificate = tlsCfg.certificatePath config.HTTP.TLS.Key = tlsCfg.privateKeyPath } - config.Storage = map[string]configuration.Parameters{"inmemory": map[string]interface{}{}} + config.Storage = map[string]configuration.Parameters{"inmemory": map[string]any{}} return NewRegistry(context.Background(), config) } @@ -177,7 +177,7 @@ func TestGetCipherSuite(t *testing.T) { } func buildRegistryTLSConfig(name, keyType string, cipherSuites []string) (*registryTLSConfig, error) { - var priv interface{} + var priv any var pub crypto.PublicKey var err error switch keyType { diff --git a/registry/storage/blobwriter.go b/registry/storage/blobwriter.go index e3c7fe615..afa0ac804 100644 --- a/registry/storage/blobwriter.go +++ b/registry/storage/blobwriter.go @@ -267,7 +267,7 @@ func (bw *blobWriter) validateBlob(ctx context.Context, desc v1.Descriptor) (v1. if !verified { dcontext.GetLoggerWithFields(ctx, - map[interface{}]interface{}{ + map[any]any{ "canonical": canonical, "provided": desc.Digest, }, "canonical", "provided"). diff --git a/registry/storage/blobwriter_resumable.go b/registry/storage/blobwriter_resumable.go index 5c55d5403..6c7836385 100644 --- a/registry/storage/blobwriter_resumable.go +++ b/registry/storage/blobwriter_resumable.go @@ -1,5 +1,4 @@ //go:build !noresumabledigest -// +build !noresumabledigest package storage diff --git a/registry/storage/catalog.go b/registry/storage/catalog.go index cb200e95b..bfd659c17 100644 --- a/registry/storage/catalog.go +++ b/registry/storage/catalog.go @@ -107,10 +107,7 @@ func compareReplaceInline(s1, s2 string, old, new byte) int { // the exact same slice header. It will make the code unsafe but can // provide some extra performance. - l := len(s1) - if len(s2) < l { - l = len(s2) - } + l := min(len(s2), len(s1)) for i := 0; i < l; i++ { c1, c2 := s1[i], s2[i] diff --git a/registry/storage/driver/azure/azure.go b/registry/storage/driver/azure/azure.go index df1a9432b..ba73dd9ea 100644 --- a/registry/storage/driver/azure/azure.go +++ b/registry/storage/driver/azure/azure.go @@ -42,7 +42,7 @@ const ( type azureDriverFactory struct{} -func (factory *azureDriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *azureDriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { params, err := NewParameters(parameters) if err != nil { return nil, err @@ -161,10 +161,7 @@ func (d *driver) PutContent(ctx context.Context, path string, contents []byte) e // when writing large piece of data in one sot: // RESPONSE 413: 413 The uploaded entity blob is too large. for offset := 0; offset < len(contents); offset += maxChunkSize { - end := offset + maxChunkSize - if end > len(contents) { - end = len(contents) - } + end := min(offset+maxChunkSize, len(contents)) chunk := contents[offset:end] _, err := appendBlobRef.AppendBlock(ctx, streaming.NopCloser(bytes.NewReader(chunk)), nil) diff --git a/registry/storage/driver/azure/azure_test.go b/registry/storage/driver/azure/azure_test.go index 73a9d07c1..6598c9e26 100644 --- a/registry/storage/driver/azure/azure_test.go +++ b/registry/storage/driver/azure/azure_test.go @@ -68,7 +68,7 @@ func init() { } azureDriverConstructor = func() (storagedriver.StorageDriver, error) { - parameters := map[string]interface{}{ + parameters := map[string]any{ "container": container, "accountname": accountName, "accountkey": accountKey, @@ -175,7 +175,7 @@ func TestCommitAfterMove(t *testing.T) { } func TestParamParsing(t *testing.T) { - expectErrors := []map[string]interface{}{ + expectErrors := []map[string]any{ {}, {"accountname": "acc1"}, } @@ -184,10 +184,10 @@ func TestParamParsing(t *testing.T) { t.Fatalf("Expected an error for parameter set: %v", parameters) } } - input := []map[string]interface{}{ + input := []map[string]any{ {"accountname": "acc1", "accountkey": "k1", "container": "c1", "max_retries": 1, "retry_delay": "10ms"}, - {"accountname": "acc1", "container": "c1", "credentials": map[string]interface{}{"type": "default"}}, - {"accountname": "acc1", "container": "c1", "credentials": map[string]interface{}{"type": "client_secret", "clientid": "c1", "tenantid": "t1", "secret": "s1"}}, + {"accountname": "acc1", "container": "c1", "credentials": map[string]any{"type": "default"}}, + {"accountname": "acc1", "container": "c1", "credentials": map[string]any{"type": "client_secret", "clientid": "c1", "tenantid": "t1", "secret": "s1"}}, } expecteds := []DriverParameters{ { diff --git a/registry/storage/driver/azure/parser.go b/registry/storage/driver/azure/parser.go index 5ecf19060..17d3703dd 100644 --- a/registry/storage/driver/azure/parser.go +++ b/registry/storage/driver/azure/parser.go @@ -42,7 +42,7 @@ type DriverParameters struct { SkipVerify bool `mapstructure:"skipverify"` } -func NewParameters(parameters map[string]interface{}) (*DriverParameters, error) { +func NewParameters(parameters map[string]any) (*DriverParameters, error) { params := DriverParameters{ Realm: defaultRealm, } diff --git a/registry/storage/driver/base/regulator.go b/registry/storage/driver/base/regulator.go index 2cf7a3ece..184df07d3 100644 --- a/registry/storage/driver/base/regulator.go +++ b/registry/storage/driver/base/regulator.go @@ -24,7 +24,7 @@ type regulator struct { // concurrent calls given a minimum limit and default. // // If the parameter supplied is of an invalid type this returns an error. -func GetLimitFromParameter(param interface{}, min, def uint64) (uint64, error) { +func GetLimitFromParameter(param any, min, def uint64) (uint64, error) { limit := def switch v := param.(type) { diff --git a/registry/storage/driver/base/regulator_test.go b/registry/storage/driver/base/regulator_test.go index e30c6a75c..becb861d6 100644 --- a/registry/storage/driver/base/regulator_test.go +++ b/registry/storage/driver/base/regulator_test.go @@ -12,14 +12,14 @@ func TestRegulatorEnterExit(t *testing.T) { r := NewRegulator(nil, limit).(*regulator) - for try := 0; try < 50; try++ { + for range 50 { run := make(chan struct{}) var firstGroupReady sync.WaitGroup var firstGroupDone sync.WaitGroup firstGroupReady.Add(limit) firstGroupDone.Add(limit) - for i := 0; i < limit; i++ { + for range limit { go func() { r.enter() firstGroupReady.Done() @@ -33,7 +33,7 @@ func TestRegulatorEnterExit(t *testing.T) { // now we exhausted all the limit, let's run a little bit more var secondGroupReady sync.WaitGroup var secondGroupDone sync.WaitGroup - for i := 0; i < 50; i++ { + for range 50 { secondGroupReady.Add(1) secondGroupDone.Add(1) go func() { @@ -69,7 +69,7 @@ func TestRegulatorEnterExit(t *testing.T) { func TestGetLimitFromParameter(t *testing.T) { tests := []struct { - Input interface{} + Input any Expected uint64 Min uint64 Default uint64 diff --git a/registry/storage/driver/factory/factory.go b/registry/storage/driver/factory/factory.go index f52684b76..fca9a95be 100644 --- a/registry/storage/driver/factory/factory.go +++ b/registry/storage/driver/factory/factory.go @@ -24,7 +24,7 @@ type StorageDriverFactory interface { // Create returns a new storagedriver.StorageDriver with the given parameters // Parameters will vary by driver and may be ignored // Each parameter key must only consist of lowercase letters and numbers - Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) + Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) } // Register makes a storage driver available by the provided name. @@ -47,7 +47,7 @@ func Register(name string, factory StorageDriverFactory) { // parameters. To use a driver, the StorageDriverFactory must first be // registered with the given name. If no drivers are found, an // InvalidStorageDriverError is returned -func Create(ctx context.Context, name string, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func Create(ctx context.Context, name string, parameters map[string]any) (storagedriver.StorageDriver, error) { driverFactory, ok := driverFactories[name] if !ok { return nil, InvalidStorageDriverError{name} diff --git a/registry/storage/driver/filesystem/driver.go b/registry/storage/driver/filesystem/driver.go index f3dd447fe..3650b61de 100644 --- a/registry/storage/driver/filesystem/driver.go +++ b/registry/storage/driver/filesystem/driver.go @@ -43,7 +43,7 @@ func init() { // filesystemDriverFactory implements the factory.StorageDriverFactory interface type filesystemDriverFactory struct{} -func (factory *filesystemDriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *filesystemDriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { return FromParameters(parameters) } @@ -65,7 +65,7 @@ type Driver struct { // Optional Parameters: // - rootdirectory // - maxthreads -func FromParameters(parameters map[string]interface{}) (*Driver, error) { +func FromParameters(parameters map[string]any) (*Driver, error) { params, err := fromParametersImpl(parameters) if err != nil || params == nil { return nil, err @@ -73,7 +73,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) { return New(*params), nil } -func fromParametersImpl(parameters map[string]interface{}) (*DriverParameters, error) { +func fromParametersImpl(parameters map[string]any) (*DriverParameters, error) { var ( err error maxThreads = defaultMaxThreads diff --git a/registry/storage/driver/filesystem/driver_test.go b/registry/storage/driver/filesystem/driver_test.go index 71e2273cc..312522b46 100644 --- a/registry/storage/driver/filesystem/driver_test.go +++ b/registry/storage/driver/filesystem/driver_test.go @@ -12,7 +12,7 @@ func newDriverConstructor(tb testing.TB) testsuites.DriverConstructor { root := tb.TempDir() return func() (storagedriver.StorageDriver, error) { - return FromParameters(map[string]interface{}{ + return FromParameters(map[string]any{ "rootdirectory": root, }) } @@ -28,13 +28,13 @@ func BenchmarkFilesystemDriverSuite(b *testing.B) { func TestFromParametersImpl(t *testing.T) { tests := []struct { - params map[string]interface{} // technically the yaml can contain anything + params map[string]any // technically the yaml can contain anything expected DriverParameters pass bool }{ // check we use default threads and root dirs { - params: map[string]interface{}{}, + params: map[string]any{}, expected: DriverParameters{ RootDirectory: defaultRootDirectory, MaxThreads: defaultMaxThreads, @@ -43,14 +43,14 @@ func TestFromParametersImpl(t *testing.T) { }, // Testing initiation with a string maxThreads which can't be parsed { - params: map[string]interface{}{ + params: map[string]any{ "maxthreads": "fail", }, expected: DriverParameters{}, pass: false, }, { - params: map[string]interface{}{ + params: map[string]any{ "maxthreads": "100", }, expected: DriverParameters{ @@ -60,7 +60,7 @@ func TestFromParametersImpl(t *testing.T) { pass: true, }, { - params: map[string]interface{}{ + params: map[string]any{ "maxthreads": 100, }, expected: DriverParameters{ @@ -71,7 +71,7 @@ func TestFromParametersImpl(t *testing.T) { }, // check that we use minimum thread counts { - params: map[string]interface{}{ + params: map[string]any{ "maxthreads": 1, }, expected: DriverParameters{ diff --git a/registry/storage/driver/gcs/gcs.go b/registry/storage/driver/gcs/gcs.go index 05b7aa32d..b29eec4a1 100644 --- a/registry/storage/driver/gcs/gcs.go +++ b/registry/storage/driver/gcs/gcs.go @@ -86,7 +86,7 @@ func init() { type gcsDriverFactory struct{} // Create StorageDriver from parameters -func (factory *gcsDriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *gcsDriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { return FromParameters(ctx, parameters) } @@ -116,7 +116,7 @@ type baseEmbed struct { // FromParameters constructs a new Driver with a given parameters map // Required parameters: // - bucket -func FromParameters(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func FromParameters(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { bucket, ok := parameters["bucket"] if !ok || fmt.Sprint(bucket) == "" { return nil, fmt.Errorf("no bucket parameter provided") @@ -138,7 +138,7 @@ func FromParameters(ctx context.Context, parameters map[string]interface{}) (sto } chunkSize = vv case int, uint, int32, uint32, uint64, int64: - chunkSize = int(reflect.ValueOf(v).Convert(reflect.TypeOf(chunkSize)).Int()) + chunkSize = int(reflect.ValueOf(v).Convert(reflect.TypeFor[int]()).Int()) default: return nil, fmt.Errorf("invalid valud for chunksize: %#v", chunkSizeParam) } @@ -169,12 +169,12 @@ func FromParameters(ctx context.Context, parameters map[string]interface{}) (sto ts = jwtConf.TokenSource(ctx) options = append(options, option.WithCredentialsFile(fmt.Sprint(keyfile))) } else if credentials, ok := parameters["credentials"]; ok { - credentialMap, ok := credentials.(map[interface{}]interface{}) + credentialMap, ok := credentials.(map[any]any) if !ok { return nil, fmt.Errorf("the credentials were not specified in the correct format") } - stringMap := map[string]interface{}{} + stringMap := map[string]any{} for k, v := range credentialMap { key, ok := k.(string) if !ok { @@ -600,7 +600,7 @@ type request func() error func retry(req request) error { backoff := time.Second var err error - for i := 0; i < maxTries; i++ { + for i := range maxTries { err = req() if err == nil { return nil diff --git a/registry/storage/driver/inmemory/driver.go b/registry/storage/driver/inmemory/driver.go index 0256603c1..eeff71d2f 100644 --- a/registry/storage/driver/inmemory/driver.go +++ b/registry/storage/driver/inmemory/driver.go @@ -22,7 +22,7 @@ func init() { // inMemoryDriverFacotry implements the factory.StorageDriverFactory interface. type inMemoryDriverFactory struct{} -func (factory *inMemoryDriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *inMemoryDriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { return New(), nil } diff --git a/registry/storage/driver/inmemory/mfs.go b/registry/storage/driver/inmemory/mfs.go index f3837c5f5..f52bddbf5 100644 --- a/registry/storage/driver/inmemory/mfs.go +++ b/registry/storage/driver/inmemory/mfs.go @@ -164,8 +164,8 @@ func (d *dir) mkdirs(p string) (*dir, error) { return dd, nil } - components := strings.Split(relative, "/") - for _, component := range components { + components := strings.SplitSeq(relative, "/") + for component := range components { d, err := dd.mkdir(component) if err != nil { // This should actually never happen, since there are no children. @@ -302,10 +302,7 @@ func (f *file) WriteAt(p []byte, offset int64) (n int, err error) { if int64(cap(f.data)) < newLen { // Grow slice exponentially to ensure amortized linear time complexity // of reallocation - newCap := int64(float64(cap(f.data)) * reallocExponent) - if newCap < newLen { - newCap = newLen - } + newCap := max(int64(float64(cap(f.data))*reallocExponent), newLen) data := make([]byte, len(f.data), newCap) copy(data, f.data) f.data = data diff --git a/registry/storage/driver/middleware/cloudfront/middleware.go b/registry/storage/driver/middleware/cloudfront/middleware.go index 130827a40..0289fb618 100644 --- a/registry/storage/driver/middleware/cloudfront/middleware.go +++ b/registry/storage/driver/middleware/cloudfront/middleware.go @@ -57,7 +57,7 @@ var _ storagedriver.StorageDriver = &cloudFrontStorageMiddleware{} // default value. "aws", only aws IP goes to S3 directly. "awsregion", only // regions listed in awsregion options goes to S3 directly // - awsregion: a comma separated string of AWS regions. -func newCloudFrontStorageMiddleware(ctx context.Context, storageDriver storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { +func newCloudFrontStorageMiddleware(ctx context.Context, storageDriver storagedriver.StorageDriver, options map[string]any) (storagedriver.StorageDriver, error) { // parse baseurl base, ok := options["baseurl"] if !ok { @@ -174,7 +174,7 @@ func newCloudFrontStorageMiddleware(ctx context.Context, storageDriver storagedr var awsRegion []string if i, ok := options["awsregion"]; ok { if regions, ok := i.(string); ok { - for _, awsRegions := range strings.Split(regions, ",") { + for awsRegions := range strings.SplitSeq(regions, ",") { awsRegion = append(awsRegion, strings.ToLower(strings.TrimSpace(awsRegions))) } awsIPs, err = newAWSIPs(ctx, ipRangesURL, updateFrequency, awsRegion) diff --git a/registry/storage/driver/middleware/cloudfront/middleware_test.go b/registry/storage/driver/middleware/cloudfront/middleware_test.go index 2fa8243d8..1a7c046a6 100644 --- a/registry/storage/driver/middleware/cloudfront/middleware_test.go +++ b/registry/storage/driver/middleware/cloudfront/middleware_test.go @@ -9,13 +9,13 @@ import ( ) func TestNoConfig(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) _, err := newCloudFrontStorageMiddleware(context.Background(), nil, options) require.ErrorContains(t, err, "no baseurl provided") } func TestCloudFrontStorageMiddlewareGenerateKey(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) options["baseurl"] = "example.com" privk := `-----BEGIN RSA PRIVATE KEY----- diff --git a/registry/storage/driver/middleware/cloudfront/s3filter.go b/registry/storage/driver/middleware/cloudfront/s3filter.go index 190bc6d9f..af7769985 100644 --- a/registry/storage/driver/middleware/cloudfront/s3filter.go +++ b/registry/storage/driver/middleware/cloudfront/s3filter.go @@ -116,7 +116,7 @@ func (s *awsIPs) tryUpdate(ctx context.Context) error { _, network, err := net.ParseCIDR(prefix) if err != nil { - dcontext.GetLoggerWithFields(dcontext.Background(), map[interface{}]interface{}{ + dcontext.GetLoggerWithFields(dcontext.Background(), map[any]any{ "cidr": prefix, }).Error("unparseable cidr") return @@ -172,7 +172,7 @@ func (s *awsIPs) getCandidateNetworks(ip net.IP) []net.IPNet { } else if ip.To16() != nil { return s.ipv6 } else { - dcontext.GetLoggerWithFields(dcontext.Background(), map[interface{}]interface{}{ + dcontext.GetLoggerWithFields(dcontext.Background(), map[any]any{ "ip": ip, }).Error("unknown ip address format") // assume mismatch, pass through cloudfront @@ -208,7 +208,7 @@ func parseIPFromRequest(request *http.Request) (net.IP, error) { func eligibleForS3(request *http.Request, awsIPs *awsIPs) bool { if awsIPs != nil && awsIPs.initialized { if addr, err := parseIPFromRequest(request); err == nil { - loggerField := map[interface{}]interface{}{ + loggerField := map[any]any{ "user-client": request.UserAgent(), "ip": requestutil.RemoteIP(request), } diff --git a/registry/storage/driver/middleware/cloudfront/s3filter_test.go b/registry/storage/driver/middleware/cloudfront/s3filter_test.go index 7ea920cdc..781ddec12 100644 --- a/registry/storage/driver/middleware/cloudfront/s3filter_test.go +++ b/registry/storage/driver/middleware/cloudfront/s3filter_test.go @@ -15,7 +15,7 @@ import ( ) // Rather than pull in all of testify -func assertEqual(t *testing.T, x, y interface{}) { +func assertEqual(t *testing.T, x, y any) { if !reflect.DeepEqual(x, y) { t.Errorf("%s: Not equal! Expected='%v', Actual='%v'\n", t.Name(), x, y) t.FailNow() @@ -351,14 +351,14 @@ func TestEligibleForS3WithAWSIPNotInitialized(t *testing.T) { // of benchmarking contains() performance. func populateRandomNetworks(b *testing.B, ips *awsIPs, ipv4Count, ipv6Count int) { generateNetworks := func(dest *[]net.IPNet, bytes int, count int) { - for i := 0; i < count; i++ { + for range count { ip := make([]byte, bytes) _, err := rand.Read(ip) if err != nil { b.Fatalf("failed to generate network for test : %s", err.Error()) } mask := make([]byte, bytes) - for i := 0; i < bytes; i++ { + for i := range bytes { mask[i] = 0xff } *dest = append(*dest, net.IPNet{ diff --git a/registry/storage/driver/middleware/redirect/middleware.go b/registry/storage/driver/middleware/redirect/middleware.go index 7dc28f76f..c8bc06b39 100644 --- a/registry/storage/driver/middleware/redirect/middleware.go +++ b/registry/storage/driver/middleware/redirect/middleware.go @@ -27,7 +27,7 @@ type redirectStorageMiddleware struct { var _ storagedriver.StorageDriver = &redirectStorageMiddleware{} -func newRedirectStorageMiddleware(ctx context.Context, sd storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { +func newRedirectStorageMiddleware(ctx context.Context, sd storagedriver.StorageDriver, options map[string]any) (storagedriver.StorageDriver, error) { o, ok := options["baseurl"] if !ok { return nil, fmt.Errorf("no baseurl provided") diff --git a/registry/storage/driver/middleware/redirect/middleware_test.go b/registry/storage/driver/middleware/redirect/middleware_test.go index 4fbf75934..1273234f4 100644 --- a/registry/storage/driver/middleware/redirect/middleware_test.go +++ b/registry/storage/driver/middleware/redirect/middleware_test.go @@ -8,20 +8,20 @@ import ( ) func TestNoConfig(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) _, err := newRedirectStorageMiddleware(context.Background(), nil, options) require.ErrorContains(t, err, "no baseurl provided") } func TestMissingScheme(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) options["baseurl"] = "example.com" _, err := newRedirectStorageMiddleware(context.Background(), nil, options) require.ErrorContains(t, err, "no scheme specified for redirect baseurl") } func TestHttpsPort(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) options["baseurl"] = "https://example.com:5443" middleware, err := newRedirectStorageMiddleware(context.Background(), nil, options) require.NoError(t, err) @@ -37,7 +37,7 @@ func TestHttpsPort(t *testing.T) { } func TestHTTP(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) options["baseurl"] = "http://example.com" middleware, err := newRedirectStorageMiddleware(context.Background(), nil, options) require.NoError(t, err) @@ -54,7 +54,7 @@ func TestHTTP(t *testing.T) { func TestPath(t *testing.T) { // basePath: end with no slash - options := make(map[string]interface{}) + options := make(map[string]any) options["baseurl"] = "https://example.com/path" middleware, err := newRedirectStorageMiddleware(context.Background(), nil, options) require.NoError(t, err) diff --git a/registry/storage/driver/middleware/rewrite/middleware.go b/registry/storage/driver/middleware/rewrite/middleware.go index 61bcd15b6..7d7c042eb 100644 --- a/registry/storage/driver/middleware/rewrite/middleware.go +++ b/registry/storage/driver/middleware/rewrite/middleware.go @@ -27,7 +27,7 @@ type rewriteStorageMiddleware struct { var _ storagedriver.StorageDriver = &rewriteStorageMiddleware{} -func getStringOption(key string, options map[string]interface{}) (string, error) { +func getStringOption(key string, options map[string]any) (string, error) { o, ok := options[key] if !ok { return "", nil @@ -39,7 +39,7 @@ func getStringOption(key string, options map[string]interface{}) (string, error) return s, nil } -func newRewriteStorageMiddleware(ctx context.Context, sd storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) { +func newRewriteStorageMiddleware(ctx context.Context, sd storagedriver.StorageDriver, options map[string]any) (storagedriver.StorageDriver, error) { var err error r := &rewriteStorageMiddleware{StorageDriver: sd} diff --git a/registry/storage/driver/middleware/rewrite/middleware_test.go b/registry/storage/driver/middleware/rewrite/middleware_test.go index 651866cbc..9343d85b3 100644 --- a/registry/storage/driver/middleware/rewrite/middleware_test.go +++ b/registry/storage/driver/middleware/rewrite/middleware_test.go @@ -18,7 +18,7 @@ func (*mockSD) RedirectURL(_ *http.Request, urlPath string) (string, error) { } func TestNoConfig(t *testing.T) { - options := make(map[string]interface{}) + options := make(map[string]any) middleware, err := newRewriteStorageMiddleware(context.Background(), &mockSD{}, options) require.NoError(t, err) @@ -31,7 +31,7 @@ func TestNoConfig(t *testing.T) { } func TestWrongType(t *testing.T) { - options := map[string]interface{}{ + options := map[string]any{ "scheme": 1, } _, err := newRewriteStorageMiddleware(context.TODO(), nil, options) @@ -39,7 +39,7 @@ func TestWrongType(t *testing.T) { } func TestRewriteHostsScheme(t *testing.T) { - options := map[string]interface{}{ + options := map[string]any{ "scheme": "https", "host": "example.com", } @@ -58,7 +58,7 @@ func TestRewriteHostsScheme(t *testing.T) { } func TestTrimPrefix(t *testing.T) { - options := map[string]interface{}{ + options := map[string]any{ "trimpathprefix": "/some/path", } diff --git a/registry/storage/driver/middleware/storagemiddleware.go b/registry/storage/driver/middleware/storagemiddleware.go index d2c37741e..0369144c9 100644 --- a/registry/storage/driver/middleware/storagemiddleware.go +++ b/registry/storage/driver/middleware/storagemiddleware.go @@ -9,7 +9,7 @@ import ( // InitFunc is the type of a StorageMiddleware factory function and is // used to register the constructor for different StorageMiddleware backends. -type InitFunc func(ctx context.Context, storageDriver storagedriver.StorageDriver, options map[string]interface{}) (storagedriver.StorageDriver, error) +type InitFunc func(ctx context.Context, storageDriver storagedriver.StorageDriver, options map[string]any) (storagedriver.StorageDriver, error) var storageMiddlewares map[string]InitFunc @@ -29,7 +29,7 @@ func Register(name string, initFunc InitFunc) error { } // Get constructs a StorageMiddleware with the given options using the named backend. -func Get(ctx context.Context, name string, options map[string]interface{}, storageDriver storagedriver.StorageDriver) (storagedriver.StorageDriver, error) { +func Get(ctx context.Context, name string, options map[string]any, storageDriver storagedriver.StorageDriver) (storagedriver.StorageDriver, error) { if storageMiddlewares != nil { if initFunc, exists := storageMiddlewares[name]; exists { return initFunc(ctx, storageDriver, options) diff --git a/registry/storage/driver/s3-aws/s3.go b/registry/storage/driver/s3-aws/s3.go index 42584b84d..b8f5d4582 100644 --- a/registry/storage/driver/s3-aws/s3.go +++ b/registry/storage/driver/s3-aws/s3.go @@ -146,7 +146,7 @@ func init() { // s3DriverFactory implements the factory.StorageDriverFactory interface type s3DriverFactory struct{} -func (factory *s3DriverFactory) Create(ctx context.Context, parameters map[string]interface{}) (storagedriver.StorageDriver, error) { +func (factory *s3DriverFactory) Create(ctx context.Context, parameters map[string]any) (storagedriver.StorageDriver, error) { return FromParameters(ctx, parameters) } @@ -184,7 +184,7 @@ type Driver struct { // - region // - bucket // - encrypt -func FromParameters(ctx context.Context, parameters map[string]interface{}) (*Driver, error) { +func FromParameters(ctx context.Context, parameters map[string]any) (*Driver, error) { // Providing no values for these is valid in case the user is authenticating // with an IAM on an ec2 instance (in which case the instance credentials will // be summoned when GetAuth is called) diff --git a/registry/storage/driver/s3-aws/s3_test.go b/registry/storage/driver/s3-aws/s3_test.go index 0a975ed3d..3e41dd3f0 100644 --- a/registry/storage/driver/s3-aws/s3_test.go +++ b/registry/storage/driver/s3-aws/s3_test.go @@ -10,6 +10,7 @@ import ( "os" "path" "reflect" + "slices" "sort" "strconv" "strings" @@ -349,7 +350,7 @@ func TestClientTransport(t *testing.T) { // NOTE(milosgajdos): we cannot simply reuse s3DriverConstructor // because s3DriverConstructor is initialized in init() using the process // env vars: we can not override S3_SKIP_VERIFY env var with t.Setenv - params := map[string]interface{}{ + params := map[string]any{ "region": os.Getenv("AWS_REGION"), "bucket": os.Getenv("S3_BUCKET"), "skipverify": tc.skipverify, @@ -610,12 +611,7 @@ func TestDelete(t *testing.T) { // and all files not marked for deletion still remain expected := tc.expected isExpected := func(path string) bool { - for _, epath := range expected { - if epath == path { - return true - } - } - return false + return slices.Contains(expected, path) } for _, path := range objs { stat, err := drvr.Stat(dcontext.Background(), path) @@ -976,7 +972,7 @@ func TestOverThousandBlobs(t *testing.T) { } ctx := dcontext.Background() - for i := 0; i < 1005; i++ { + for i := range 1005 { filename := "/thousandfiletest/file" + strconv.Itoa(i) contents := []byte("contents") err = standardDriver.PutContent(ctx, filename, contents) @@ -1056,7 +1052,7 @@ func TestListObjectsV2(t *testing.T) { n := 6 prefix := "/test-list-objects-v2" var filePaths []string - for i := 0; i < n; i++ { + for i := range n { filePaths = append(filePaths, fmt.Sprintf("%s/%d", prefix, i)) } for _, p := range filePaths { diff --git a/registry/storage/driver/storagedriver.go b/registry/storage/driver/storagedriver.go index c12f79de3..180a5fd1b 100644 --- a/registry/storage/driver/storagedriver.go +++ b/registry/storage/driver/storagedriver.go @@ -216,11 +216,12 @@ func (e Errors) Error() string { case 1: return fmt.Sprintf("%s: %s", e.DriverName, e.Errs[0].Error()) default: - msg := "errors:\n" + var msg strings.Builder + msg.WriteString("errors:\n") for _, err := range e.Errs { - msg += err.Error() + "\n" + msg.WriteString(err.Error() + "\n") } - return fmt.Sprintf("%s: %s", e.DriverName, msg) + return fmt.Sprintf("%s: %s", e.DriverName, msg.String()) } } diff --git a/registry/storage/driver/testsuites/testsuites.go b/registry/storage/driver/testsuites/testsuites.go index c61ecc6cd..4a0a1b265 100644 --- a/registry/storage/driver/testsuites/testsuites.go +++ b/registry/storage/driver/testsuites/testsuites.go @@ -585,7 +585,7 @@ func (suite *DriverSuite) TestList() { parentDirectory := rootDirectory + "/" + randomFilename(int64(8+rand.Intn(8))) childFiles := make([]string, 50) - for i := 0; i < len(childFiles); i++ { + for i := range childFiles { childFile := parentDirectory + "/" + randomFilename(int64(8+rand.Intn(8))) childFiles[i] = childFile err := suite.StorageDriver.PutContent(suite.ctx, childFile, randomContents(32)) @@ -1009,7 +1009,7 @@ func (suite *DriverSuite) TestConcurrentStreamReads() { } wg.Add(10) - for i := 0; i < 10; i++ { + for range 10 { go readContents() } wg.Wait() @@ -1222,7 +1222,7 @@ func (s *DriverBenchmarkSuite) benchmarkListFiles(b *testing.B, numFiles int64) s.StorageDriver.Delete(s.ctx, firstPart(parentDir)) }() - for i := int64(0); i < numFiles; i++ { + for range numFiles { err := s.StorageDriver.PutContent(s.ctx, path.Join(parentDir, randomPath(32)), nil) s.Suite.Require().NoError(err) } @@ -1251,7 +1251,7 @@ func (s *DriverBenchmarkSuite) benchmarkDeleteFiles(b *testing.B, numFiles int64 defer s.deletePath(firstPart(parentDir)) b.StopTimer() - for j := int64(0); j < numFiles; j++ { + for range numFiles { err := s.StorageDriver.PutContent(s.ctx, path.Join(parentDir, randomPath(32)), nil) s.Suite.Require().NoError(err) } @@ -1388,10 +1388,7 @@ func (rr *randReader) Read(p []byte) (n int, err error) { rr.m.Lock() defer rr.m.Unlock() - toread := int64(len(p)) - if toread > rr.r { - toread = rr.r - } + toread := min(int64(len(p)), rr.r) n = copy(p, randomContents(toread)) rr.r -= int64(n) diff --git a/registry/storage/garbagecollect.go b/registry/storage/garbagecollect.go index 8b4ae73c7..a95d7f40c 100644 --- a/registry/storage/garbagecollect.go +++ b/registry/storage/garbagecollect.go @@ -12,7 +12,7 @@ import ( v1 "github.com/opencontainers/image-spec/specs-go/v1" ) -func emit(format string, a ...interface{}) { +func emit(format string, a ...any) { fmt.Printf(format+"\n", a...) } diff --git a/registry/storage/linkedblobstore.go b/registry/storage/linkedblobstore.go index e5f5b32e4..212e82bce 100644 --- a/registry/storage/linkedblobstore.go +++ b/registry/storage/linkedblobstore.go @@ -102,16 +102,16 @@ func (lbs *linkedBlobStore) Put(ctx context.Context, mediaType string, p []byte) return desc, lbs.linkBlob(ctx, desc) } -type optionFunc func(interface{}) error +type optionFunc func(any) error -func (f optionFunc) Apply(v interface{}) error { +func (f optionFunc) Apply(v any) error { return f(v) } // WithMountFrom returns a BlobCreateOption which designates that the blob should be // mounted from the given canonical reference. func WithMountFrom(ref reference.Canonical) distribution.BlobCreateOption { - return optionFunc(func(v interface{}) error { + return optionFunc(func(v any) error { opts, ok := v.(*distribution.CreateOptions) if !ok { return fmt.Errorf("unexpected options type: %T", v) diff --git a/registry/storage/linkedblobstore_test.go b/registry/storage/linkedblobstore_test.go index 0c61e0848..6179f75e5 100644 --- a/registry/storage/linkedblobstore_test.go +++ b/registry/storage/linkedblobstore_test.go @@ -22,7 +22,7 @@ func TestLinkedBlobStoreEnumerator(t *testing.T) { ctx := context.Background() var expected []string - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatal("unexpected error generating test layer file") @@ -76,7 +76,7 @@ func TestLinkedBlobStoreCreateWithMountFrom(t *testing.T) { // Build up some test layers and add them to the manifest, saving the // readseekers for upload later. testLayers := map[digest.Digest]io.ReadSeeker{} - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatal("unexpected error generating test layer file") @@ -249,7 +249,7 @@ type statCrossMountCreateOption struct { var _ distribution.BlobCreateOption = statCrossMountCreateOption{} -func (f statCrossMountCreateOption) Apply(v interface{}) error { +func (f statCrossMountCreateOption) Apply(v any) error { opts, ok := v.(*distribution.CreateOptions) if !ok { return fmt.Errorf("Unexpected create options: %#v", v) diff --git a/registry/storage/manifeststore_test.go b/registry/storage/manifeststore_test.go index 1beb78c88..5e90e3b62 100644 --- a/registry/storage/manifeststore_test.go +++ b/registry/storage/manifeststore_test.go @@ -108,7 +108,7 @@ func testManifestStorage(t *testing.T, options ...RegistryOption) { // Build up some test layers and add them to the manifest, saving the // readseekers for upload later. testLayers := map[digest.Digest]io.ReadSeeker{} - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatal("unexpected error generating test layer file") @@ -602,7 +602,7 @@ func createRandomImage(t *testing.T, testname string, imageMediaType string, blo ctx := context.Background() // Add some layers - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatalf("%s: unexpected error generating test layer file", testname) @@ -776,7 +776,7 @@ func TestManifestStorageCache(t *testing.T) { // Build up some test layers and add them to the manifest, saving the // readseekers for upload later. testLayers := map[digest.Digest]io.ReadSeeker{} - for i := 0; i < 2; i++ { + for range 2 { rs, dgst, err := testutil.CreateRandomTarFile() if err != nil { t.Fatal("unexpected error generating test layer file") diff --git a/registry/storage/purgeuploads_test.go b/registry/storage/purgeuploads_test.go index 96960aef1..2c648d0a2 100644 --- a/registry/storage/purgeuploads_test.go +++ b/registry/storage/purgeuploads_test.go @@ -15,7 +15,7 @@ import ( func testUploadFS(t *testing.T, numUploads int, repoName string, startedAt time.Time) (driver.StorageDriver, context.Context) { d := inmemory.New() ctx := context.Background() - for i := 0; i < numUploads; i++ { + for range numUploads { addUploads(ctx, t, d, uuid.NewString(), repoName, startedAt) } return d, ctx @@ -91,7 +91,7 @@ func TestPurgeSome(t *testing.T) { newUploadCount := 4 - for i := 0; i < newUploadCount; i++ { + for range newUploadCount { addUploads(ctx, t, fs, uuid.NewString(), "test-repo", time.Now().Add(1*time.Hour)) } diff --git a/registry/storage/tagstore_test.go b/registry/storage/tagstore_test.go index c4c89163b..e3502cb01 100644 --- a/registry/storage/tagstore_test.go +++ b/registry/storage/tagstore_test.go @@ -238,7 +238,7 @@ func TestTagIndexes(t *testing.T) { t1Dgsts := make(map[digest.Digest]struct{}) t2Dgsts := make(map[digest.Digest]struct{}) - for i := 0; i < 5; i++ { + for i := range 5 { layer, err := env.bs.Put(ctx, "application/octet-stream", []byte{byte(i + 1)}) if err != nil { t.Fatal(err) diff --git a/testutil/tarfile.go b/testutil/tarfile.go index 84634cdbb..a24d51084 100644 --- a/testutil/tarfile.go +++ b/testutil/tarfile.go @@ -34,7 +34,7 @@ func CreateRandomTarFile() (rs io.ReadSeeker, dgst digest.Digest, err error) { ChangeTime: time.Now(), } - for fileNumber := 0; fileNumber < nFiles; fileNumber++ { + for fileNumber := range nFiles { fileSize := mrand.Int63n(1<<20) + 1<<20 header.Name = fmt.Sprint(fileNumber) @@ -84,7 +84,7 @@ func CreateRandomTarFile() (rs io.ReadSeeker, dgst digest.Digest, err error) { // about the order of said digests (since they're all random anyway). func CreateRandomLayers(n int) (map[digest.Digest]io.ReadSeeker, error) { digestMap := map[digest.Digest]io.ReadSeeker{} - for i := 0; i < n; i++ { + for range n { rs, ds, err := CreateRandomTarFile() if err != nil { return nil, fmt.Errorf("unexpected error generating test layer file: %v", err)