diff --git a/cmd/docker-trust/internal/trust/trust_push.go b/cmd/docker-trust/internal/trust/trust_push.go index 64f255964c..c65085f2c8 100644 --- a/cmd/docker-trust/internal/trust/trust_push.go +++ b/cmd/docker-trust/internal/trust/trust_push.go @@ -7,7 +7,7 @@ import ( "errors" "fmt" "io" - "sort" + "slices" "github.com/distribution/reference" "github.com/docker/cli/cli/streams" @@ -113,8 +113,7 @@ func PushTrustedReference(ctx context.Context, ioStreams Streams, repoInfo *Repo var rootKeyID string // always select the first root key if len(keys) > 0 { - sort.Strings(keys) - rootKeyID = keys[0] + rootKeyID = slices.Min(keys) } else { rootPublicKey, err := repo.GetCryptoService().Create(data.CanonicalRootRole, "", data.ECDSAKey) if err != nil { diff --git a/cmd/docker-trust/trust/common.go b/cmd/docker-trust/trust/common.go index f05e577273..f839bd26bd 100644 --- a/cmd/docker-trust/trust/common.go +++ b/cmd/docker-trust/trust/common.go @@ -4,6 +4,7 @@ import ( "context" "encoding/hex" "fmt" + "slices" "sort" "strings" @@ -110,9 +111,6 @@ func lookupTrustInfo(ctx context.Context, cli command.Cli, remote string) ([]tru } func formatAdminRole(roleWithSigs client.RoleWithSignatures) string { - adminKeyList := roleWithSigs.KeyIDs - sort.Strings(adminKeyList) - var role string switch roleWithSigs.Name { case data.CanonicalTargetsRole: @@ -122,6 +120,7 @@ func formatAdminRole(roleWithSigs client.RoleWithSignatures) string { default: return "" } + adminKeyList := slices.Sorted(slices.Values(roleWithSigs.KeyIDs)) return fmt.Sprintf("%s:\t%s\n", role, strings.Join(adminKeyList, ", ")) } diff --git a/cmd/docker-trust/trust/formatter.go b/cmd/docker-trust/trust/formatter.go index 13e5712a27..2bde36115f 100644 --- a/cmd/docker-trust/trust/formatter.go +++ b/cmd/docker-trust/trust/formatter.go @@ -1,7 +1,7 @@ package trust import ( - "sort" + "slices" "strings" "github.com/docker/cli/cli/command/formatter" @@ -73,8 +73,7 @@ func (c *trustTagContext) Digest() string { // Signers returns the sorted list of entities who signed this tag func (c *trustTagContext) Signers() string { - sort.Strings(c.s.Signers) - return strings.Join(c.s.Signers, ", ") + return strings.Join(slices.Sorted(slices.Values(c.s.Signers)), ", ") } // signerInfoWrite writes the context. @@ -108,15 +107,13 @@ type signerInfoContext struct { // Keys returns the sorted list of keys associated with the signer func (c *signerInfoContext) Keys() string { - sort.Strings(c.s.Keys) - truncatedKeys := []string{} + keys := slices.Sorted(slices.Values(c.s.Keys)) if c.trunc { - for _, keyID := range c.s.Keys { - truncatedKeys = append(truncatedKeys, formatter.TruncateID(keyID)) + for i, keyID := range keys { + keys[i] = formatter.TruncateID(keyID) } - return strings.Join(truncatedKeys, ", ") } - return strings.Join(c.s.Keys, ", ") + return strings.Join(keys, ", ") } // Signer returns the name of the signer diff --git a/cmd/docker-trust/trust/inspect.go b/cmd/docker-trust/trust/inspect.go index fabb1d7a13..74240b61ad 100644 --- a/cmd/docker-trust/trust/inspect.go +++ b/cmd/docker-trust/trust/inspect.go @@ -4,10 +4,11 @@ package trust import ( + "cmp" "context" "encoding/json" "fmt" - "sort" + "slices" "github.com/docker/cli/cli" "github.com/docker/cli/cli/command" @@ -80,36 +81,38 @@ func getRepoTrustInfo(ctx context.Context, dockerCLI command.Cli, remote string) } } - signerList, adminList := []trustSigner{}, []trustSigner{} - - signerRoleToKeyIDs := getDelegationRoleToKeyMap(delegationRoles) - - for signerName, signerKeys := range signerRoleToKeyIDs { - signerKeyList := []trustKey{} + var signerList []trustSigner + for signerName, signerKeys := range getDelegationRoleToKeyMap(delegationRoles) { + signerKeyList := make([]trustKey, 0, len(signerKeys)) for _, keyID := range signerKeys { signerKeyList = append(signerKeyList, trustKey{ID: keyID}) } signerList = append(signerList, trustSigner{signerName, signerKeyList}) } - sort.Slice(signerList, func(i, j int) bool { return signerList[i].Name > signerList[j].Name }) + // Sort by name in descending order. + slices.SortFunc(signerList, func(a, b trustSigner) int { return cmp.Compare(b.Name, a.Name) }) + var adminList []trustSigner for _, adminRole := range adminRolesWithSigs { + var name string switch adminRole.Name { case data.CanonicalRootRole: - rootKeys := []trustKey{} - for _, keyID := range adminRole.KeyIDs { - rootKeys = append(rootKeys, trustKey{ID: keyID}) - } - adminList = append(adminList, trustSigner{"Root", rootKeys}) + name = "Root" case data.CanonicalTargetsRole: - targetKeys := []trustKey{} - for _, keyID := range adminRole.KeyIDs { - targetKeys = append(targetKeys, trustKey{ID: keyID}) - } - adminList = append(adminList, trustSigner{"Repository", targetKeys}) + name = "Repository" + default: + continue } + + keys := make([]trustKey, 0, len(adminRole.KeyIDs)) + for _, keyID := range adminRole.KeyIDs { + keys = append(keys, trustKey{ID: keyID}) + } + adminList = append(adminList, trustSigner{name, keys}) } - sort.Slice(adminList, func(i, j int) bool { return adminList[i].Name > adminList[j].Name }) + + // Sort by name in descending order. + slices.SortFunc(adminList, func(a, b trustSigner) int { return cmp.Compare(b.Name, a.Name) }) return json.Marshal(trustRepo{ Name: remote, diff --git a/cmd/docker-trust/trust/inspect_pretty.go b/cmd/docker-trust/trust/inspect_pretty.go index 3eac2cfbe8..68e717be71 100644 --- a/cmd/docker-trust/trust/inspect_pretty.go +++ b/cmd/docker-trust/trust/inspect_pretty.go @@ -1,9 +1,11 @@ package trust import ( + "cmp" "context" "fmt" "io" + "slices" "sort" "github.com/docker/cli/cli/command" @@ -44,7 +46,10 @@ func prettyPrintTrustInfo(ctx context.Context, dockerCLI command.Cli, remote str } func printSortedAdminKeys(out io.Writer, adminRoles []client.RoleWithSignatures) { - sort.Slice(adminRoles, func(i, j int) bool { return adminRoles[i].Name > adminRoles[j].Name }) + // Sort by name in descending order. + slices.SortFunc(adminRoles, func(a, b client.RoleWithSignatures) int { + return cmp.Compare(b.Name, a.Name) + }) for _, adminRole := range adminRoles { if formattedAdminRole := formatAdminRole(adminRole); formattedAdminRole != "" { _, _ = fmt.Fprintf(out, " %s", formattedAdminRole) diff --git a/cmd/docker-trust/trust/sign.go b/cmd/docker-trust/trust/sign.go index 6b4b933f72..f965ffb86a 100644 --- a/cmd/docker-trust/trust/sign.go +++ b/cmd/docker-trust/trust/sign.go @@ -6,7 +6,7 @@ import ( "fmt" "io" "path" - "sort" + "slices" "strings" "github.com/distribution/reference" @@ -189,8 +189,8 @@ func getExistingSignatureInfoForReleasedTag(notaryRepo notaryclient.Repository, } func prettyPrintExistingSignatureInfo(out io.Writer, existingSigInfo trustTagRow) { - sort.Strings(existingSigInfo.Signers) - joinedSigners := strings.Join(existingSigInfo.Signers, ", ") + signers := slices.Sorted(slices.Values(existingSigInfo.Signers)) + joinedSigners := strings.Join(signers, ", ") _, _ = fmt.Fprintf(out, "Existing signatures for tag %s digest %s from:\n%s\n", existingSigInfo.SignedTag, existingSigInfo.Digest, joinedSigners) } @@ -228,8 +228,7 @@ func getOrGenerateNotaryKey(notaryRepo notaryclient.Repository, role data.RoleNa var key data.PublicKey // always select the first key by ID if len(keys) > 0 { - sort.Strings(keys) - keyID := keys[0] + keyID := slices.Min(keys) privKey, _, err := notaryRepo.GetCryptoService().GetPrivateKey(keyID) if err != nil { return nil, err