Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Commit c8a7267

Browse files
committed
Changed CLI to use --types flag, a comma separated list of desired analyzers
1 parent 8be7997 commit c8a7267

File tree

9 files changed

+78
-115
lines changed

9 files changed

+78
-115
lines changed

README.md

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,29 @@ To use `container-diff analyze` to perform analysis on a single image, you need
4343

4444
```
4545
container-diff analyze <img> [Run all analyzers]
46-
container-diff analyze <img> -d [History]
47-
container-diff analyze <img> -f [File System]
48-
container-diff analyze <img> -p [Pip]
49-
container-diff analyze <img> -a [Apt]
50-
container-diff analyze <img> -n [Node]
46+
container-diff analyze <img> --types=history [History]
47+
container-diff analyze <img> --types=file [File System]
48+
container-diff analyze <img> --types=pip [Pip]
49+
container-diff analyze <img> --types=apt [Apt]
50+
container-diff analyze <img> --types=node [Node]
51+
container-diff analyze <img> --types=apt,node [Apt and Node]
52+
# --types=<analyzer1>,<analyzer2>,<analyzer3>,...
5153
```
5254

5355
To use container-diff to perform a diff analysis on two images, you need two Docker images (in the form of an ID, tarball, or URL from a repo). Once you have those images, you can run any of the following differs:
5456
```
5557
container-diff diff <img1> <img2> [Run all differs]
56-
container-diff diff <img1> <img2> -d [History]
57-
container-diff diff <img1> <img2> -f [File System]
58-
container-diff diff <img1> <img2> -p [Pip]
59-
container-diff diff <img1> <img2> -a [Apt]
60-
container-diff diff <img1> <img2> -n [Node]
58+
container-diff diff <img1> <img2> --types=history [History]
59+
container-diff diff <img1> <img2> --types=file [File System]
60+
container-diff diff <img1> <img2> --types=pip [Pip]
61+
container-diff diff <img1> <img2> --types=apt [Apt]
62+
container-diff diff <img1> <img2> --types=node [Node]
6163
```
6264

6365
You can similarly run many analyzers at once:
6466

6567
```
66-
container-diff diff <img1> <img2> -d -a -n [History, Apt, and Node]
68+
container-diff diff <img1> <img2> --types=history,apt,node [History, Apt, and Node]
6769
```
6870

6971
All of the analyzer flags with their long versions can be seen below:
@@ -228,7 +230,7 @@ To run container-diff on image IDs, docker must be installed.
228230
## Example Run
229231

230232
```
231-
$ container-diff gcr.io/google-appengine/python:2017-07-21-123058 gcr.io/google-appengine/python:2017-06-29-190410 -a -n -p
233+
$ container-diff diff gcr.io/google-appengine/python:2017-07-21-123058 gcr.io/google-appengine/python:2017-06-29-190410 --types=apt,node,pip
232234
233235
-----AptDiffer-----
234236
@@ -372,7 +374,3 @@ This is where you define how your analyzer should output for a human readable fo
372374

373375
5. Add your analyzer to the `analyses` map in [differs.go](https://github.com/GoogleCloudPlatform/container-diff/blob/master/differs/differs.go#L22) with the corresponding Analyzer struct as the value.
374376

375-
376-
377-
378-

cmd/analyze.go

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"strings"
78

89
"github.com/GoogleCloudPlatform/container-diff/differs"
910
"github.com/GoogleCloudPlatform/container-diff/utils"
@@ -16,37 +17,29 @@ var analyzeCmd = &cobra.Command{
1617
Short: "Analyzes an image: [image]",
1718
Long: `Analyzes an image using the specifed analyzers as indicated via flags (see documentation for available ones).`,
1819
Run: func(cmd *cobra.Command, args []string) {
19-
if validArgs, err := validateArgs(args, checkAnalyzeArgNum, checkArgType); !validArgs {
20+
if err := validateArgs(args, checkAnalyzeArgNum, checkArgType); err != nil {
2021
glog.Error(err.Error())
2122
os.Exit(1)
2223
}
23-
analyzeArgs := []string{}
24-
allAnalyzers := getAllAnalyzers()
25-
for _, name := range allAnalyzers {
26-
if *analyzeFlagMap[name] == true {
27-
analyzeArgs = append(analyzeArgs, name)
28-
}
29-
}
30-
31-
// If no analyzers are specified, perform them all as the default
32-
if len(analyzeArgs) == 0 {
33-
analyzeArgs = allAnalyzers
24+
if err := checkIfValidAnalyzer(types); err != nil {
25+
glog.Error(err)
26+
os.Exit(1)
3427
}
35-
36-
if err := analyzeImage(args[0], analyzeArgs); err != nil {
28+
if err := analyzeImage(args[0], strings.Split(types, ",")); err != nil {
3729
glog.Error(err)
3830
os.Exit(1)
3931
}
4032
},
4133
}
4234

43-
func checkAnalyzeArgNum(args []string) (bool, error) {
35+
func checkAnalyzeArgNum(args []string) error {
4436
var errMessage string
4537
if len(args) != 1 {
4638
errMessage = "'analyze' requires one image as an argument: container analyze [image]"
47-
return false, errors.New(errMessage)
39+
glog.Errorf(errMessage)
40+
return errors.New(errMessage)
4841
}
49-
return true, nil
42+
return nil
5043
}
5144

5245
func analyzeImage(imageArg string, analyzerArgs []string) error {

cmd/analyze_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ var analyzeArgNumTests = []testpair{
1212

1313
func TestAnalyzeArgNum(t *testing.T) {
1414
for _, test := range analyzeArgNumTests {
15-
valid, err := checkAnalyzeArgNum(test.input)
16-
if valid != test.expected_output {
15+
err := checkAnalyzeArgNum(test.input)
16+
if (err == nil) != test.expected_output {
1717
if test.expected_output {
1818
t.Errorf("Got unexpected error: %s", err)
1919
} else {

cmd/diff.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"strings"
78
"sync"
89

910
"github.com/GoogleCloudPlatform/container-diff/differs"
@@ -17,37 +18,28 @@ var diffCmd = &cobra.Command{
1718
Short: "Compare two images: [image1] [image2]",
1819
Long: `Compares two images using the specifed analyzers as indicated via flags (see documentation for available ones).`,
1920
Run: func(cmd *cobra.Command, args []string) {
20-
if validArgs, err := validateArgs(args, checkDiffArgNum, checkArgType); !validArgs {
21+
if err := validateArgs(args, checkDiffArgNum, checkArgType); err != nil {
2122
glog.Error(err.Error())
2223
os.Exit(1)
2324
}
24-
analyzeArgs := []string{}
25-
allAnalyzers := getAllAnalyzers()
26-
for _, name := range allAnalyzers {
27-
if *analyzeFlagMap[name] == true {
28-
analyzeArgs = append(analyzeArgs, name)
29-
}
30-
}
31-
32-
// If no analyzers are specified, perform them all as the default
33-
if len(analyzeArgs) == 0 {
34-
analyzeArgs = allAnalyzers
25+
if err := checkIfValidAnalyzer(types); err != nil {
26+
glog.Error(err)
27+
os.Exit(1)
3528
}
36-
37-
if err := diffImages(args[0], args[1], analyzeArgs); err != nil {
29+
if err := diffImages(args[0], args[1], strings.Split(types, ",")); err != nil {
3830
glog.Error(err)
3931
os.Exit(1)
4032
}
4133
},
4234
}
4335

44-
func checkDiffArgNum(args []string) (bool, error) {
36+
func checkDiffArgNum(args []string) error {
4537
var errMessage string
4638
if len(args) != 2 {
4739
errMessage = "'diff' requires two images as arguments: container diff [image1] [image2]"
48-
return false, errors.New(errMessage)
40+
return errors.New(errMessage)
4941
}
50-
return true, nil
42+
return nil
5143
}
5244

5345
func diffImages(image1Arg, image2Arg string, diffArgs []string) error {

cmd/diff_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ var diffArgNumTests = []testpair{
1313

1414
func TestDiffArgNum(t *testing.T) {
1515
for _, test := range diffArgNumTests {
16-
valid, err := checkDiffArgNum(test.input)
17-
if valid != test.expected_output {
16+
err := checkDiffArgNum(test.input)
17+
if (err == nil) != test.expected_output {
1818
if test.expected_output {
1919
t.Errorf("Got unexpected error: %s", err)
2020
} else {

cmd/root.go

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,28 @@
11
package cmd
22

33
import (
4-
"bytes"
54
"context"
6-
"errors"
75
goflag "flag"
86
"fmt"
97
"os"
108
"reflect"
119
"sort"
10+
"strings"
1211

12+
"github.com/GoogleCloudPlatform/container-diff/differs"
1313
"github.com/GoogleCloudPlatform/container-diff/utils"
1414
"github.com/docker/docker/client"
1515
"github.com/golang/glog"
16+
"github.com/pkg/errors"
1617
"github.com/spf13/cobra"
1718
"github.com/spf13/pflag"
1819
)
1920

2021
var json bool
21-
var eng bool
2222
var save bool
23-
var apt bool
24-
var node bool
25-
var file bool
26-
var history bool
27-
var pip bool
28-
29-
var analyzeFlagMap = map[string]*bool{
30-
"apt": &apt,
31-
"node": &node,
32-
"file": &file,
33-
"history": &history,
34-
"pip": &pip,
35-
}
23+
var types string
3624

37-
type validatefxn func(args []string) (bool, error)
25+
type validatefxn func(args []string) error
3826

3927
var RootCmd = &cobra.Command{
4028
Use: "container-diff",
@@ -90,24 +78,13 @@ func cleanupImage(image utils.Image) {
9078
}
9179
}
9280

93-
func getAllAnalyzers() []string {
94-
allAnalyzers := []string{}
95-
for name := range analyzeFlagMap {
96-
allAnalyzers = append(allAnalyzers, name)
97-
}
98-
return allAnalyzers
99-
}
100-
101-
func validateArgs(args []string, validatefxns ...validatefxn) (bool, error) {
81+
func validateArgs(args []string, validatefxns ...validatefxn) error {
10282
for _, validatefxn := range validatefxns {
103-
valid, err := validatefxn(args)
104-
if err != nil {
105-
return false, err
106-
} else if !valid {
107-
return false, nil
83+
if err := validatefxn(args); err != nil {
84+
return err
10885
}
10986
}
110-
return true, nil
87+
return nil
11188
}
11289

11390
func checkImage(arg string) bool {
@@ -117,20 +94,27 @@ func checkImage(arg string) bool {
11794
return true
11895
}
11996

120-
func checkArgType(args []string) (bool, error) {
121-
var buffer bytes.Buffer
122-
valid := true
97+
func checkArgType(args []string) error {
12398
for _, arg := range args {
12499
if !checkImage(arg) {
125-
valid = false
126100
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", args[0])
127-
buffer.WriteString(errMessage)
101+
glog.Errorf(errMessage)
102+
return errors.New(errMessage)
128103
}
129104
}
130-
if !valid {
131-
return false, errors.New(buffer.String())
105+
return nil
106+
}
107+
108+
func checkIfValidAnalyzer(flagtypes string) error {
109+
analyzers := strings.Split(flagtypes, ",")
110+
for _, name := range analyzers {
111+
if _, exists := differs.Analyzers[name]; !exists {
112+
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", name)
113+
glog.Errorf(errMessage)
114+
return errors.New(errMessage)
115+
}
132116
}
133-
return true, nil
117+
return nil
134118
}
135119

136120
func remove(path string, dir bool) string {
@@ -157,11 +141,7 @@ func init() {
157141

158142
func addSharedFlags(cmd *cobra.Command) {
159143
cmd.Flags().BoolVarP(&json, "json", "j", false, "JSON Output defines if the diff should be returned in a human readable format (false) or a JSON (true).")
160-
cmd.Flags().BoolVarP(&pip, "pip", "p", false, "Set this flag to use the pip differ.")
161-
cmd.Flags().BoolVarP(&node, "node", "n", false, "Set this flag to use the node differ.")
162-
cmd.Flags().BoolVarP(&apt, "apt", "a", false, "Set this flag to use the apt differ.")
163-
cmd.Flags().BoolVarP(&file, "file", "f", false, "Set this flag to use the file differ.")
164-
cmd.Flags().BoolVarP(&history, "history", "d", false, "Set this flag to use the dockerfile history differ.")
144+
cmd.Flags().StringVarP(&types, "types", "t", "", "This flag sets the list of analyzer types to use. It expects a comma separated list of supported analyzers.")
165145
cmd.Flags().BoolVarP(&save, "save", "s", false, "Set this flag to save rather than remove the final image filesystems on exit.")
166146
cmd.Flags().BoolVarP(&utils.SortSize, "order", "o", false, "Set this flag to sort any file/package results by descending size. Otherwise, they will be sorted by name.")
167147
}

cmd/root_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ var argTypeTests = []testpair{
1919

2020
func TestArgType(t *testing.T) {
2121
for _, test := range argTypeTests {
22-
valid, err := checkArgType(test.input)
23-
if valid != test.expected_output {
22+
err := checkArgType(test.input)
23+
if (err == nil) != test.expected_output {
2424
if test.expected_output {
2525
t.Errorf("Got unexpected error: %s", err)
2626
} else {

differs/differs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type Analyzer interface {
2525
Analyze(image utils.Image) (utils.Result, error)
2626
}
2727

28-
var analyzers = map[string]Analyzer{
28+
var Analyzers = map[string]Analyzer{
2929
"history": HistoryAnalyzer{},
3030
"file": FileAnalyzer{},
3131
"apt": AptAnalyzer{},
@@ -84,7 +84,7 @@ func (req SingleRequest) GetAnalysis() (map[string]utils.Result, error) {
8484

8585
func GetAnalyzers(analyzeNames []string) (analyzeFuncs []Analyzer, err error) {
8686
for _, name := range analyzeNames {
87-
if a, exists := analyzers[name]; exists {
87+
if a, exists := Analyzers[name]; exists {
8888
analyzeFuncs = append(analyzeFuncs, a)
8989
} else {
9090
glog.Errorf("Unknown analyzer/differ specified", name)

0 commit comments

Comments
 (0)