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

Commit f024fad

Browse files
Merge pull request #68 from aaron-prindle/type-list
Changed CLI to use --types flag, a comma separated list of desired an…
2 parents 8d76928 + c8a7267 commit f024fad

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
@@ -20,6 +20,7 @@ import (
2020
"errors"
2121
"fmt"
2222
"os"
23+
"strings"
2324

2425
"github.com/GoogleCloudPlatform/container-diff/differs"
2526
"github.com/GoogleCloudPlatform/container-diff/utils"
@@ -32,37 +33,29 @@ var analyzeCmd = &cobra.Command{
3233
Short: "Analyzes an image: [image]",
3334
Long: `Analyzes an image using the specifed analyzers as indicated via flags (see documentation for available ones).`,
3435
Run: func(cmd *cobra.Command, args []string) {
35-
if validArgs, err := validateArgs(args, checkAnalyzeArgNum, checkArgType); !validArgs {
36+
if err := validateArgs(args, checkAnalyzeArgNum, checkArgType); err != nil {
3637
glog.Error(err.Error())
3738
os.Exit(1)
3839
}
39-
analyzeArgs := []string{}
40-
allAnalyzers := getAllAnalyzers()
41-
for _, name := range allAnalyzers {
42-
if *analyzeFlagMap[name] == true {
43-
analyzeArgs = append(analyzeArgs, name)
44-
}
45-
}
46-
47-
// If no analyzers are specified, perform them all as the default
48-
if len(analyzeArgs) == 0 {
49-
analyzeArgs = allAnalyzers
40+
if err := checkIfValidAnalyzer(types); err != nil {
41+
glog.Error(err)
42+
os.Exit(1)
5043
}
51-
52-
if err := analyzeImage(args[0], analyzeArgs); err != nil {
44+
if err := analyzeImage(args[0], strings.Split(types, ",")); err != nil {
5345
glog.Error(err)
5446
os.Exit(1)
5547
}
5648
},
5749
}
5850

59-
func checkAnalyzeArgNum(args []string) (bool, error) {
51+
func checkAnalyzeArgNum(args []string) error {
6052
var errMessage string
6153
if len(args) != 1 {
6254
errMessage = "'analyze' requires one image as an argument: container analyze [image]"
63-
return false, errors.New(errMessage)
55+
glog.Errorf(errMessage)
56+
return errors.New(errMessage)
6457
}
65-
return true, nil
58+
return nil
6659
}
6760

6861
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
@@ -28,8 +28,8 @@ var analyzeArgNumTests = []testpair{
2828

2929
func TestAnalyzeArgNum(t *testing.T) {
3030
for _, test := range analyzeArgNumTests {
31-
valid, err := checkAnalyzeArgNum(test.input)
32-
if valid != test.expected_output {
31+
err := checkAnalyzeArgNum(test.input)
32+
if (err == nil) != test.expected_output {
3333
if test.expected_output {
3434
t.Errorf("Got unexpected error: %s", err)
3535
} else {

cmd/diff.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"errors"
2121
"fmt"
2222
"os"
23+
"strings"
2324
"sync"
2425

2526
"github.com/GoogleCloudPlatform/container-diff/differs"
@@ -33,37 +34,28 @@ var diffCmd = &cobra.Command{
3334
Short: "Compare two images: [image1] [image2]",
3435
Long: `Compares two images using the specifed analyzers as indicated via flags (see documentation for available ones).`,
3536
Run: func(cmd *cobra.Command, args []string) {
36-
if validArgs, err := validateArgs(args, checkDiffArgNum, checkArgType); !validArgs {
37+
if err := validateArgs(args, checkDiffArgNum, checkArgType); err != nil {
3738
glog.Error(err.Error())
3839
os.Exit(1)
3940
}
40-
analyzeArgs := []string{}
41-
allAnalyzers := getAllAnalyzers()
42-
for _, name := range allAnalyzers {
43-
if *analyzeFlagMap[name] == true {
44-
analyzeArgs = append(analyzeArgs, name)
45-
}
46-
}
47-
48-
// If no analyzers are specified, perform them all as the default
49-
if len(analyzeArgs) == 0 {
50-
analyzeArgs = allAnalyzers
41+
if err := checkIfValidAnalyzer(types); err != nil {
42+
glog.Error(err)
43+
os.Exit(1)
5144
}
52-
53-
if err := diffImages(args[0], args[1], analyzeArgs); err != nil {
45+
if err := diffImages(args[0], args[1], strings.Split(types, ",")); err != nil {
5446
glog.Error(err)
5547
os.Exit(1)
5648
}
5749
},
5850
}
5951

60-
func checkDiffArgNum(args []string) (bool, error) {
52+
func checkDiffArgNum(args []string) error {
6153
var errMessage string
6254
if len(args) != 2 {
6355
errMessage = "'diff' requires two images as arguments: container diff [image1] [image2]"
64-
return false, errors.New(errMessage)
56+
return errors.New(errMessage)
6557
}
66-
return true, nil
58+
return nil
6759
}
6860

6961
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
@@ -29,8 +29,8 @@ var diffArgNumTests = []testpair{
2929

3030
func TestDiffArgNum(t *testing.T) {
3131
for _, test := range diffArgNumTests {
32-
valid, err := checkDiffArgNum(test.input)
33-
if valid != test.expected_output {
32+
err := checkDiffArgNum(test.input)
33+
if (err == nil) != test.expected_output {
3434
if test.expected_output {
3535
t.Errorf("Got unexpected error: %s", err)
3636
} else {

cmd/root.go

Lines changed: 25 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,27 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20-
"bytes"
2120
"context"
22-
"errors"
2321
goflag "flag"
2422
"fmt"
2523
"os"
2624
"sort"
25+
"strings"
2726

27+
"github.com/GoogleCloudPlatform/container-diff/differs"
2828
"github.com/GoogleCloudPlatform/container-diff/utils"
2929
"github.com/docker/docker/client"
3030
"github.com/golang/glog"
31+
"github.com/pkg/errors"
3132
"github.com/spf13/cobra"
3233
"github.com/spf13/pflag"
3334
)
3435

3536
var json bool
36-
var eng bool
3737
var save bool
38-
var apt bool
39-
var node bool
40-
var file bool
41-
var history bool
42-
var pip bool
43-
44-
var analyzeFlagMap = map[string]*bool{
45-
"apt": &apt,
46-
"node": &node,
47-
"file": &file,
48-
"history": &history,
49-
"pip": &pip,
50-
}
38+
var types string
5139

52-
type validatefxn func(args []string) (bool, error)
40+
type validatefxn func(args []string) error
5341

5442
var RootCmd = &cobra.Command{
5543
Use: "container-diff",
@@ -105,24 +93,13 @@ func cleanupImage(image utils.Image) {
10593
}
10694
}
10795

108-
func getAllAnalyzers() []string {
109-
allAnalyzers := []string{}
110-
for name := range analyzeFlagMap {
111-
allAnalyzers = append(allAnalyzers, name)
112-
}
113-
return allAnalyzers
114-
}
115-
116-
func validateArgs(args []string, validatefxns ...validatefxn) (bool, error) {
96+
func validateArgs(args []string, validatefxns ...validatefxn) error {
11797
for _, validatefxn := range validatefxns {
118-
valid, err := validatefxn(args)
119-
if err != nil {
120-
return false, err
121-
} else if !valid {
122-
return false, nil
98+
if err := validatefxn(args); err != nil {
99+
return err
123100
}
124101
}
125-
return true, nil
102+
return nil
126103
}
127104

128105
func checkImage(arg string) bool {
@@ -132,20 +109,27 @@ func checkImage(arg string) bool {
132109
return true
133110
}
134111

135-
func checkArgType(args []string) (bool, error) {
136-
var buffer bytes.Buffer
137-
valid := true
112+
func checkArgType(args []string) error {
138113
for _, arg := range args {
139114
if !checkImage(arg) {
140-
valid = false
141115
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", args[0])
142-
buffer.WriteString(errMessage)
116+
glog.Errorf(errMessage)
117+
return errors.New(errMessage)
143118
}
144119
}
145-
if !valid {
146-
return false, errors.New(buffer.String())
120+
return nil
121+
}
122+
123+
func checkIfValidAnalyzer(flagtypes string) error {
124+
analyzers := strings.Split(flagtypes, ",")
125+
for _, name := range analyzers {
126+
if _, exists := differs.Analyzers[name]; !exists {
127+
errMessage := fmt.Sprintf("Argument %s is not an image ID, URL, or tar\n", name)
128+
glog.Errorf(errMessage)
129+
return errors.New(errMessage)
130+
}
147131
}
148-
return true, nil
132+
return nil
149133
}
150134

151135
func remove(path string, dir bool) string {
@@ -172,11 +156,7 @@ func init() {
172156

173157
func addSharedFlags(cmd *cobra.Command) {
174158
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).")
175-
cmd.Flags().BoolVarP(&pip, "pip", "p", false, "Set this flag to use the pip differ.")
176-
cmd.Flags().BoolVarP(&node, "node", "n", false, "Set this flag to use the node differ.")
177-
cmd.Flags().BoolVarP(&apt, "apt", "a", false, "Set this flag to use the apt differ.")
178-
cmd.Flags().BoolVarP(&file, "file", "f", false, "Set this flag to use the file differ.")
179-
cmd.Flags().BoolVarP(&history, "history", "d", false, "Set this flag to use the dockerfile history differ.")
159+
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.")
180160
cmd.Flags().BoolVarP(&save, "save", "s", false, "Set this flag to save rather than remove the final image filesystems on exit.")
181161
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.")
182162
}

cmd/root_test.go

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

3636
func TestArgType(t *testing.T) {
3737
for _, test := range argTypeTests {
38-
valid, err := checkArgType(test.input)
39-
if valid != test.expected_output {
38+
err := checkArgType(test.input)
39+
if (err == nil) != test.expected_output {
4040
if test.expected_output {
4141
t.Errorf("Got unexpected error: %s", err)
4242
} else {

differs/differs.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ type Analyzer interface {
4141
Name() string
4242
}
4343

44-
var analyzers = map[string]Analyzer{
44+
var Analyzers = map[string]Analyzer{
4545
"history": HistoryAnalyzer{},
4646
"file": FileAnalyzer{},
4747
"apt": AptAnalyzer{},
@@ -99,7 +99,7 @@ func (req SingleRequest) GetAnalysis() (map[string]utils.Result, error) {
9999

100100
func GetAnalyzers(analyzeNames []string) (analyzeFuncs []Analyzer, err error) {
101101
for _, name := range analyzeNames {
102-
if a, exists := analyzers[name]; exists {
102+
if a, exists := Analyzers[name]; exists {
103103
analyzeFuncs = append(analyzeFuncs, a)
104104
} else {
105105
glog.Errorf("Unknown analyzer/differ specified", name)

0 commit comments

Comments
 (0)