mirror of https://github.com/docker/cli.git
Merge pull request #1196 from adshmh/use-sort-slice-for-sorting-cli-compose
refactored commands to use sort.Slice
This commit is contained in:
commit
b91953f507
|
@ -133,18 +133,3 @@ func (c *signerInfoContext) Keys() string {
|
||||||
func (c *signerInfoContext) Signer() string {
|
func (c *signerInfoContext) Signer() string {
|
||||||
return c.s.Name
|
return c.s.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignerInfoList helps sort []SignerInfo by signer names
|
|
||||||
type SignerInfoList []SignerInfo
|
|
||||||
|
|
||||||
func (signerInfoComp SignerInfoList) Len() int {
|
|
||||||
return len(signerInfoComp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (signerInfoComp SignerInfoList) Less(i, j int) bool {
|
|
||||||
return signerInfoComp[i].Name < signerInfoComp[j].Name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (signerInfoComp SignerInfoList) Swap(i, j int) {
|
|
||||||
signerInfoComp[i], signerInfoComp[j] = signerInfoComp[j], signerInfoComp[i]
|
|
||||||
}
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ eve foobarbazquxquux, key31, key32
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testcase := range cases {
|
for _, testcase := range cases {
|
||||||
signerInfo := SignerInfoList{
|
signerInfo := []SignerInfo{
|
||||||
{Name: "alice", Keys: []string{"key11", "key12"}},
|
{Name: "alice", Keys: []string{"key11", "key12"}},
|
||||||
{Name: "bob", Keys: []string{"key21"}},
|
{Name: "bob", Keys: []string{"key21"}},
|
||||||
{Name: "eve", Keys: []string{"key31", "key32", "foobarbazquxquux"}},
|
{Name: "eve", Keys: []string{"key31", "key32", "foobarbazquxquux"}},
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
"github.com/docker/cli/opts"
|
"github.com/docker/cli/opts"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
registrytypes "github.com/docker/docker/api/types/registry"
|
|
||||||
"github.com/docker/docker/registry"
|
"github.com/docker/docker/registry"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -81,13 +80,14 @@ func runSearch(dockerCli command.Cli, options searchOptions) error {
|
||||||
|
|
||||||
clnt := dockerCli.Client()
|
clnt := dockerCli.Client()
|
||||||
|
|
||||||
unorderedResults, err := clnt.ImageSearch(ctx, options.term, searchOptions)
|
results, err := clnt.ImageSearch(ctx, options.term, searchOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
results := searchResultsByStars(unorderedResults)
|
sort.Slice(results, func(i, j int) bool {
|
||||||
sort.Sort(results)
|
return results[j].StarCount < results[i].StarCount
|
||||||
|
})
|
||||||
searchCtx := formatter.Context{
|
searchCtx := formatter.Context{
|
||||||
Output: dockerCli.Out(),
|
Output: dockerCli.Out(),
|
||||||
Format: formatter.NewSearchFormat(options.format),
|
Format: formatter.NewSearchFormat(options.format),
|
||||||
|
@ -95,10 +95,3 @@ func runSearch(dockerCli command.Cli, options searchOptions) error {
|
||||||
}
|
}
|
||||||
return formatter.SearchWrite(searchCtx, results, options.automated, int(options.stars))
|
return formatter.SearchWrite(searchCtx, results, options.automated, int(options.stars))
|
||||||
}
|
}
|
||||||
|
|
||||||
// searchResultsByStars sorts search results in descending order by number of stars.
|
|
||||||
type searchResultsByStars []registrytypes.SearchResult
|
|
||||||
|
|
||||||
func (r searchResultsByStars) Len() int { return len(r) }
|
|
||||||
func (r searchResultsByStars) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
|
||||||
func (r searchResultsByStars) Less(i, j int) bool { return r[j].StarCount < r[i].StarCount }
|
|
||||||
|
|
|
@ -28,24 +28,10 @@ type trustTagRow struct {
|
||||||
Signers []string
|
Signers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type trustTagRowList []trustTagRow
|
|
||||||
|
|
||||||
func (tagComparator trustTagRowList) Len() int {
|
|
||||||
return len(tagComparator)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tagComparator trustTagRowList) Less(i, j int) bool {
|
|
||||||
return tagComparator[i].SignedTag < tagComparator[j].SignedTag
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tagComparator trustTagRowList) Swap(i, j int) {
|
|
||||||
tagComparator[i], tagComparator[j] = tagComparator[j], tagComparator[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// trustRepo represents consumable information about a trusted repository
|
// trustRepo represents consumable information about a trusted repository
|
||||||
type trustRepo struct {
|
type trustRepo struct {
|
||||||
Name string
|
Name string
|
||||||
SignedTags trustTagRowList
|
SignedTags []trustTagRow
|
||||||
Signers []trustSigner
|
Signers []trustSigner
|
||||||
AdminstrativeKeys []trustSigner
|
AdminstrativeKeys []trustSigner
|
||||||
}
|
}
|
||||||
|
@ -64,20 +50,20 @@ type trustKey struct {
|
||||||
|
|
||||||
// lookupTrustInfo returns processed signature and role information about a notary repository.
|
// lookupTrustInfo returns processed signature and role information about a notary repository.
|
||||||
// This information is to be pretty printed or serialized into a machine-readable format.
|
// This information is to be pretty printed or serialized into a machine-readable format.
|
||||||
func lookupTrustInfo(cli command.Cli, remote string) (trustTagRowList, []client.RoleWithSignatures, []data.Role, error) {
|
func lookupTrustInfo(cli command.Cli, remote string) ([]trustTagRow, []client.RoleWithSignatures, []data.Role, error) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote)
|
imgRefAndAuth, err := trust.GetImageReferencesAndAuth(ctx, nil, image.AuthResolver(cli), remote)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, err
|
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, err
|
||||||
}
|
}
|
||||||
tag := imgRefAndAuth.Tag()
|
tag := imgRefAndAuth.Tag()
|
||||||
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
|
notaryRepo, err := cli.NotaryClient(imgRefAndAuth, trust.ActionsPullOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
|
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, trust.NotaryError(imgRefAndAuth.Reference().Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = clearChangeList(notaryRepo); err != nil {
|
if err = clearChangeList(notaryRepo); err != nil {
|
||||||
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, err
|
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, err
|
||||||
}
|
}
|
||||||
defer clearChangeList(notaryRepo)
|
defer clearChangeList(notaryRepo)
|
||||||
|
|
||||||
|
@ -87,7 +73,7 @@ func lookupTrustInfo(cli command.Cli, remote string) (trustTagRowList, []client.
|
||||||
logrus.Debug(trust.NotaryError(remote, err))
|
logrus.Debug(trust.NotaryError(remote, err))
|
||||||
// print an empty table if we don't have signed targets, but have an initialized notary repo
|
// print an empty table if we don't have signed targets, but have an initialized notary repo
|
||||||
if _, ok := err.(client.ErrNoSuchTarget); !ok {
|
if _, ok := err.(client.ErrNoSuchTarget); !ok {
|
||||||
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signatures or cannot access %s", remote)
|
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signatures or cannot access %s", remote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
signatureRows := matchReleasedSignatures(allSignedTargets)
|
signatureRows := matchReleasedSignatures(allSignedTargets)
|
||||||
|
@ -95,7 +81,7 @@ func lookupTrustInfo(cli command.Cli, remote string) (trustTagRowList, []client.
|
||||||
// get the administrative roles
|
// get the administrative roles
|
||||||
adminRolesWithSigs, err := notaryRepo.ListRoles()
|
adminRolesWithSigs, err := notaryRepo.ListRoles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return trustTagRowList{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signers for %s", remote)
|
return []trustTagRow{}, []client.RoleWithSignatures{}, []data.Role{}, fmt.Errorf("No signers for %s", remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get delegation roles with the canonical key IDs
|
// get delegation roles with the canonical key IDs
|
||||||
|
@ -138,8 +124,8 @@ func getDelegationRoleToKeyMap(rawDelegationRoles []data.Role) map[string][]stri
|
||||||
|
|
||||||
// aggregate all signers for a "released" hash+tagname pair. To be "released," the tag must have been
|
// aggregate all signers for a "released" hash+tagname pair. To be "released," the tag must have been
|
||||||
// signed into the "targets" or "targets/releases" role. Output is sorted by tag name
|
// signed into the "targets" or "targets/releases" role. Output is sorted by tag name
|
||||||
func matchReleasedSignatures(allTargets []client.TargetSignedStruct) trustTagRowList {
|
func matchReleasedSignatures(allTargets []client.TargetSignedStruct) []trustTagRow {
|
||||||
signatureRows := trustTagRowList{}
|
signatureRows := []trustTagRow{}
|
||||||
// do a first pass to get filter on tags signed into "targets" or "targets/releases"
|
// do a first pass to get filter on tags signed into "targets" or "targets/releases"
|
||||||
releasedTargetRows := map[trustTagKey][]string{}
|
releasedTargetRows := map[trustTagKey][]string{}
|
||||||
for _, tgt := range allTargets {
|
for _, tgt := range allTargets {
|
||||||
|
@ -162,6 +148,8 @@ func matchReleasedSignatures(allTargets []client.TargetSignedStruct) trustTagRow
|
||||||
for targetKey, signers := range releasedTargetRows {
|
for targetKey, signers := range releasedTargetRows {
|
||||||
signatureRows = append(signatureRows, trustTagRow{targetKey, signers})
|
signatureRows = append(signatureRows, trustTagRow{targetKey, signers})
|
||||||
}
|
}
|
||||||
sort.Sort(signatureRows)
|
sort.Slice(signatureRows, func(i, j int) bool {
|
||||||
|
return signatureRows[i].SignedTag < signatureRows[j].SignedTag
|
||||||
|
})
|
||||||
return signatureRows
|
return signatureRows
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ func printSortedAdminKeys(out io.Writer, adminRoles []client.RoleWithSignatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pretty print with ordered rows
|
// pretty print with ordered rows
|
||||||
func printSignatures(out io.Writer, signatureRows trustTagRowList) error {
|
func printSignatures(out io.Writer, signatureRows []trustTagRow) error {
|
||||||
trustTagCtx := formatter.Context{
|
trustTagCtx := formatter.Context{
|
||||||
Output: out,
|
Output: out,
|
||||||
Format: formatter.NewTrustTagFormat(),
|
Format: formatter.NewTrustTagFormat(),
|
||||||
|
@ -78,13 +78,15 @@ func printSignerInfo(out io.Writer, roleToKeyIDs map[string][]string) error {
|
||||||
Format: formatter.NewSignerInfoFormat(),
|
Format: formatter.NewSignerInfoFormat(),
|
||||||
Trunc: true,
|
Trunc: true,
|
||||||
}
|
}
|
||||||
formattedSignerInfo := formatter.SignerInfoList{}
|
formattedSignerInfo := []formatter.SignerInfo{}
|
||||||
for name, keyIDs := range roleToKeyIDs {
|
for name, keyIDs := range roleToKeyIDs {
|
||||||
formattedSignerInfo = append(formattedSignerInfo, formatter.SignerInfo{
|
formattedSignerInfo = append(formattedSignerInfo, formatter.SignerInfo{
|
||||||
Name: name,
|
Name: name,
|
||||||
Keys: keyIDs,
|
Keys: keyIDs,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sort.Sort(formattedSignerInfo)
|
sort.Slice(formattedSignerInfo, func(i, j int) bool {
|
||||||
|
return formattedSignerInfo[i].Name < formattedSignerInfo[j].Name
|
||||||
|
})
|
||||||
return formatter.SignerInfoWrite(signerInfoCtx, formattedSignerInfo)
|
return formatter.SignerInfoWrite(signerInfoCtx, formattedSignerInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,12 +202,6 @@ func sortStrings(strs []string) []string {
|
||||||
return strs
|
return strs
|
||||||
}
|
}
|
||||||
|
|
||||||
type byNetworkTarget []swarm.NetworkAttachmentConfig
|
|
||||||
|
|
||||||
func (a byNetworkTarget) Len() int { return len(a) }
|
|
||||||
func (a byNetworkTarget) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
||||||
func (a byNetworkTarget) Less(i, j int) bool { return a[i].Target < a[j].Target }
|
|
||||||
|
|
||||||
func convertServiceNetworks(
|
func convertServiceNetworks(
|
||||||
networks map[string]*composetypes.ServiceNetworkConfig,
|
networks map[string]*composetypes.ServiceNetworkConfig,
|
||||||
networkConfigs networkMap,
|
networkConfigs networkMap,
|
||||||
|
@ -246,7 +240,9 @@ func convertServiceNetworks(
|
||||||
nets = append(nets, netAttachConfig)
|
nets = append(nets, netAttachConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(byNetworkTarget(nets))
|
sort.Slice(nets, func(i, j int) bool {
|
||||||
|
return nets[i].Target < nets[j].Target
|
||||||
|
})
|
||||||
return nets, nil
|
return nets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,12 +532,6 @@ func convertResources(source composetypes.Resources) (*swarm.ResourceRequirement
|
||||||
return resources, nil
|
return resources, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type byPublishedPort []swarm.PortConfig
|
|
||||||
|
|
||||||
func (a byPublishedPort) Len() int { return len(a) }
|
|
||||||
func (a byPublishedPort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
||||||
func (a byPublishedPort) Less(i, j int) bool { return a[i].PublishedPort < a[j].PublishedPort }
|
|
||||||
|
|
||||||
func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortConfig) (*swarm.EndpointSpec, error) {
|
func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortConfig) (*swarm.EndpointSpec, error) {
|
||||||
portConfigs := []swarm.PortConfig{}
|
portConfigs := []swarm.PortConfig{}
|
||||||
for _, port := range source {
|
for _, port := range source {
|
||||||
|
@ -554,7 +544,10 @@ func convertEndpointSpec(endpointMode string, source []composetypes.ServicePortC
|
||||||
portConfigs = append(portConfigs, portConfig)
|
portConfigs = append(portConfigs, portConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(byPublishedPort(portConfigs))
|
sort.Slice(portConfigs, func(i, j int) bool {
|
||||||
|
return portConfigs[i].PublishedPort < portConfigs[j].PublishedPort
|
||||||
|
})
|
||||||
|
|
||||||
return &swarm.EndpointSpec{
|
return &swarm.EndpointSpec{
|
||||||
Mode: swarm.ResolutionMode(strings.ToLower(endpointMode)),
|
Mode: swarm.ResolutionMode(strings.ToLower(endpointMode)),
|
||||||
Ports: portConfigs,
|
Ports: portConfigs,
|
||||||
|
|
|
@ -247,11 +247,8 @@ func TestConvertServiceNetworks(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
sortedConfigs := byTargetSort(configs)
|
|
||||||
sort.Sort(&sortedConfigs)
|
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Check(t, is.DeepEqual(expected, []swarm.NetworkAttachmentConfig(sortedConfigs)))
|
assert.Check(t, is.DeepEqual(expected, configs))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConvertServiceNetworksCustomDefault(t *testing.T) {
|
func TestConvertServiceNetworksCustomDefault(t *testing.T) {
|
||||||
|
@ -277,20 +274,6 @@ func TestConvertServiceNetworksCustomDefault(t *testing.T) {
|
||||||
assert.Check(t, is.DeepEqual(expected, []swarm.NetworkAttachmentConfig(configs)))
|
assert.Check(t, is.DeepEqual(expected, []swarm.NetworkAttachmentConfig(configs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
type byTargetSort []swarm.NetworkAttachmentConfig
|
|
||||||
|
|
||||||
func (s byTargetSort) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s byTargetSort) Less(i, j int) bool {
|
|
||||||
return strings.Compare(s[i].Target, s[j].Target) < 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s byTargetSort) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConvertDNSConfigEmpty(t *testing.T) {
|
func TestConvertDNSConfigEmpty(t *testing.T) {
|
||||||
dnsConfig, err := convertDNSConfig(nil, nil)
|
dnsConfig, err := convertDNSConfig(nil, nil)
|
||||||
|
|
||||||
|
|
|
@ -985,16 +985,12 @@ services:
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceSort(services []types.ServiceConfig) []types.ServiceConfig {
|
func serviceSort(services []types.ServiceConfig) []types.ServiceConfig {
|
||||||
sort.Sort(servicesByName(services))
|
sort.Slice(services, func(i, j int) bool {
|
||||||
|
return services[i].Name < services[j].Name
|
||||||
|
})
|
||||||
return services
|
return services
|
||||||
}
|
}
|
||||||
|
|
||||||
type servicesByName []types.ServiceConfig
|
|
||||||
|
|
||||||
func (sbn servicesByName) Len() int { return len(sbn) }
|
|
||||||
func (sbn servicesByName) Swap(i, j int) { sbn[i], sbn[j] = sbn[j], sbn[i] }
|
|
||||||
func (sbn servicesByName) Less(i, j int) bool { return sbn[i].Name < sbn[j].Name }
|
|
||||||
|
|
||||||
func TestLoadAttachableNetwork(t *testing.T) {
|
func TestLoadAttachableNetwork(t *testing.T) {
|
||||||
config, err := loadYAML(`
|
config, err := loadYAML(`
|
||||||
version: "3.2"
|
version: "3.2"
|
||||||
|
|
Loading…
Reference in New Issue