Browse code

Move the search command to the registry package.

And move it back to the top-level command.

Signed-off-by: Daniel Nephin <dnephin@docker.com>

Daniel Nephin authored on 2016/08/29 22:59:41
Showing 4 changed files
... ...
@@ -33,6 +33,7 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
33 33
 		system.NewEventsCommand(dockerCli),
34 34
 		registry.NewLoginCommand(dockerCli),
35 35
 		registry.NewLogoutCommand(dockerCli),
36
+		registry.NewSearchCommand(dockerCli),
36 37
 		system.NewVersionCommand(dockerCli),
37 38
 		volume.NewVolumeCommand(dockerCli),
38 39
 		system.NewInfoCommand(dockerCli),
... ...
@@ -66,7 +67,6 @@ func AddCommands(cmd *cobra.Command, dockerCli *command.DockerCli) {
66 66
 		hide(image.NewPushCommand(dockerCli)),
67 67
 		hide(image.NewRemoveCommand(dockerCli)),
68 68
 		hide(image.NewSaveCommand(dockerCli)),
69
-		hide(image.NewSearchCommand(dockerCli)),
70 69
 		hide(image.NewTagCommand(dockerCli)),
71 70
 		hide(system.NewInspectCommand(dockerCli)),
72 71
 	)
... ...
@@ -27,7 +27,6 @@ func NewImageCommand(dockerCli *command.DockerCli) *cobra.Command {
27 27
 		NewPullCommand(dockerCli),
28 28
 		NewPushCommand(dockerCli),
29 29
 		NewSaveCommand(dockerCli),
30
-		NewSearchCommand(dockerCli),
31 30
 		NewTagCommand(dockerCli),
32 31
 		newListCommand(dockerCli),
33 32
 		newRemoveCommand(dockerCli),
34 33
deleted file mode 100644
... ...
@@ -1,126 +0,0 @@
1
-package image
2
-
3
-import (
4
-	"fmt"
5
-	"sort"
6
-	"strings"
7
-	"text/tabwriter"
8
-
9
-	"golang.org/x/net/context"
10
-
11
-	"github.com/docker/docker/api/types"
12
-	registrytypes "github.com/docker/docker/api/types/registry"
13
-	"github.com/docker/docker/cli"
14
-	"github.com/docker/docker/cli/command"
15
-	"github.com/docker/docker/opts"
16
-	"github.com/docker/docker/pkg/stringutils"
17
-	"github.com/docker/docker/registry"
18
-	"github.com/spf13/cobra"
19
-)
20
-
21
-type searchOptions struct {
22
-	term    string
23
-	noTrunc bool
24
-	limit   int
25
-	filter  opts.FilterOpt
26
-
27
-	// Deprecated
28
-	stars     uint
29
-	automated bool
30
-}
31
-
32
-// NewSearchCommand creates a new `docker search` command
33
-func NewSearchCommand(dockerCli *command.DockerCli) *cobra.Command {
34
-	opts := searchOptions{filter: opts.NewFilterOpt()}
35
-
36
-	cmd := &cobra.Command{
37
-		Use:   "search [OPTIONS] TERM",
38
-		Short: "Search the Docker Hub for images",
39
-		Args:  cli.ExactArgs(1),
40
-		RunE: func(cmd *cobra.Command, args []string) error {
41
-			opts.term = args[0]
42
-			return runSearch(dockerCli, opts)
43
-		},
44
-	}
45
-
46
-	flags := cmd.Flags()
47
-
48
-	flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
49
-	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
50
-	flags.IntVar(&opts.limit, "limit", registry.DefaultSearchLimit, "Max number of search results")
51
-
52
-	flags.BoolVar(&opts.automated, "automated", false, "Only show automated builds")
53
-	flags.UintVarP(&opts.stars, "stars", "s", 0, "Only displays with at least x stars")
54
-
55
-	flags.MarkDeprecated("automated", "use --filter=automated=true instead")
56
-	flags.MarkDeprecated("stars", "use --filter=stars=3 instead")
57
-
58
-	return cmd
59
-}
60
-
61
-func runSearch(dockerCli *command.DockerCli, opts searchOptions) error {
62
-	indexInfo, err := registry.ParseSearchIndexInfo(opts.term)
63
-	if err != nil {
64
-		return err
65
-	}
66
-
67
-	ctx := context.Background()
68
-
69
-	authConfig := command.ResolveAuthConfig(ctx, dockerCli, indexInfo)
70
-	requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, indexInfo, "search")
71
-
72
-	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
73
-	if err != nil {
74
-		return err
75
-	}
76
-
77
-	options := types.ImageSearchOptions{
78
-		RegistryAuth:  encodedAuth,
79
-		PrivilegeFunc: requestPrivilege,
80
-		Filters:       opts.filter.Value(),
81
-		Limit:         opts.limit,
82
-	}
83
-
84
-	clnt := dockerCli.Client()
85
-
86
-	unorderedResults, err := clnt.ImageSearch(ctx, opts.term, options)
87
-	if err != nil {
88
-		return err
89
-	}
90
-
91
-	results := searchResultsByStars(unorderedResults)
92
-	sort.Sort(results)
93
-
94
-	w := tabwriter.NewWriter(dockerCli.Out(), 10, 1, 3, ' ', 0)
95
-	fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
96
-	for _, res := range results {
97
-		// --automated and -s, --stars are deprecated since Docker 1.12
98
-		if (opts.automated && !res.IsAutomated) || (int(opts.stars) > res.StarCount) {
99
-			continue
100
-		}
101
-		desc := strings.Replace(res.Description, "\n", " ", -1)
102
-		desc = strings.Replace(desc, "\r", " ", -1)
103
-		if !opts.noTrunc {
104
-			desc = stringutils.Ellipsis(desc, 45)
105
-		}
106
-		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
107
-		if res.IsOfficial {
108
-			fmt.Fprint(w, "[OK]")
109
-
110
-		}
111
-		fmt.Fprint(w, "\t")
112
-		if res.IsAutomated {
113
-			fmt.Fprint(w, "[OK]")
114
-		}
115
-		fmt.Fprint(w, "\n")
116
-	}
117
-	w.Flush()
118
-	return nil
119
-}
120
-
121
-// SearchResultsByStars sorts search results in descending order by number of stars.
122
-type searchResultsByStars []registrytypes.SearchResult
123
-
124
-func (r searchResultsByStars) Len() int           { return len(r) }
125
-func (r searchResultsByStars) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
126
-func (r searchResultsByStars) Less(i, j int) bool { return r[j].StarCount < r[i].StarCount }
127 1
new file mode 100644
... ...
@@ -0,0 +1,126 @@
0
+package registry
1
+
2
+import (
3
+	"fmt"
4
+	"sort"
5
+	"strings"
6
+	"text/tabwriter"
7
+
8
+	"golang.org/x/net/context"
9
+
10
+	"github.com/docker/docker/api/types"
11
+	registrytypes "github.com/docker/docker/api/types/registry"
12
+	"github.com/docker/docker/cli"
13
+	"github.com/docker/docker/cli/command"
14
+	"github.com/docker/docker/opts"
15
+	"github.com/docker/docker/pkg/stringutils"
16
+	"github.com/docker/docker/registry"
17
+	"github.com/spf13/cobra"
18
+)
19
+
20
+type searchOptions struct {
21
+	term    string
22
+	noTrunc bool
23
+	limit   int
24
+	filter  opts.FilterOpt
25
+
26
+	// Deprecated
27
+	stars     uint
28
+	automated bool
29
+}
30
+
31
+// NewSearchCommand creates a new `docker search` command
32
+func NewSearchCommand(dockerCli *command.DockerCli) *cobra.Command {
33
+	opts := searchOptions{filter: opts.NewFilterOpt()}
34
+
35
+	cmd := &cobra.Command{
36
+		Use:   "search [OPTIONS] TERM",
37
+		Short: "Search the Docker Hub for images",
38
+		Args:  cli.ExactArgs(1),
39
+		RunE: func(cmd *cobra.Command, args []string) error {
40
+			opts.term = args[0]
41
+			return runSearch(dockerCli, opts)
42
+		},
43
+	}
44
+
45
+	flags := cmd.Flags()
46
+
47
+	flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
48
+	flags.VarP(&opts.filter, "filter", "f", "Filter output based on conditions provided")
49
+	flags.IntVar(&opts.limit, "limit", registry.DefaultSearchLimit, "Max number of search results")
50
+
51
+	flags.BoolVar(&opts.automated, "automated", false, "Only show automated builds")
52
+	flags.UintVarP(&opts.stars, "stars", "s", 0, "Only displays with at least x stars")
53
+
54
+	flags.MarkDeprecated("automated", "use --filter=automated=true instead")
55
+	flags.MarkDeprecated("stars", "use --filter=stars=3 instead")
56
+
57
+	return cmd
58
+}
59
+
60
+func runSearch(dockerCli *command.DockerCli, opts searchOptions) error {
61
+	indexInfo, err := registry.ParseSearchIndexInfo(opts.term)
62
+	if err != nil {
63
+		return err
64
+	}
65
+
66
+	ctx := context.Background()
67
+
68
+	authConfig := command.ResolveAuthConfig(ctx, dockerCli, indexInfo)
69
+	requestPrivilege := command.RegistryAuthenticationPrivilegedFunc(dockerCli, indexInfo, "search")
70
+
71
+	encodedAuth, err := command.EncodeAuthToBase64(authConfig)
72
+	if err != nil {
73
+		return err
74
+	}
75
+
76
+	options := types.ImageSearchOptions{
77
+		RegistryAuth:  encodedAuth,
78
+		PrivilegeFunc: requestPrivilege,
79
+		Filters:       opts.filter.Value(),
80
+		Limit:         opts.limit,
81
+	}
82
+
83
+	clnt := dockerCli.Client()
84
+
85
+	unorderedResults, err := clnt.ImageSearch(ctx, opts.term, options)
86
+	if err != nil {
87
+		return err
88
+	}
89
+
90
+	results := searchResultsByStars(unorderedResults)
91
+	sort.Sort(results)
92
+
93
+	w := tabwriter.NewWriter(dockerCli.Out(), 10, 1, 3, ' ', 0)
94
+	fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
95
+	for _, res := range results {
96
+		// --automated and -s, --stars are deprecated since Docker 1.12
97
+		if (opts.automated && !res.IsAutomated) || (int(opts.stars) > res.StarCount) {
98
+			continue
99
+		}
100
+		desc := strings.Replace(res.Description, "\n", " ", -1)
101
+		desc = strings.Replace(desc, "\r", " ", -1)
102
+		if !opts.noTrunc {
103
+			desc = stringutils.Ellipsis(desc, 45)
104
+		}
105
+		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
106
+		if res.IsOfficial {
107
+			fmt.Fprint(w, "[OK]")
108
+
109
+		}
110
+		fmt.Fprint(w, "\t")
111
+		if res.IsAutomated {
112
+			fmt.Fprint(w, "[OK]")
113
+		}
114
+		fmt.Fprint(w, "\n")
115
+	}
116
+	w.Flush()
117
+	return nil
118
+}
119
+
120
+// SearchResultsByStars sorts search results in descending order by number of stars.
121
+type searchResultsByStars []registrytypes.SearchResult
122
+
123
+func (r searchResultsByStars) Len() int           { return len(r) }
124
+func (r searchResultsByStars) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
125
+func (r searchResultsByStars) Less(i, j int) bool { return r[j].StarCount < r[i].StarCount }