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

Commit bd97f7c

Browse files
committed
first test compiles, will need testing and additional tests
1 parent 4e6ac73 commit bd97f7c

File tree

5 files changed

+87
-49
lines changed

5 files changed

+87
-49
lines changed

cmd/diff.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,11 @@ func diffFile(image1, image2 *pkgutil.Image) error {
158158
if err != nil {
159159
return err
160160
}
161-
util.TemplateOutput(diff, "FilenameDiff")
161+
writer, err := getWriter(outputFile)
162+
if err != nil {
163+
return err
164+
}
165+
util.TemplateOutput(writer, diff, "FilenameDiff")
162166
return nil
163167
}
164168

cmd/root.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package cmd
1919
import (
2020
goflag "flag"
2121
"fmt"
22+
"io"
2223
"os"
2324
"path/filepath"
2425
"sort"
@@ -40,6 +41,7 @@ var save bool
4041
var types diffTypes
4142
var noCache bool
4243

44+
var outputFile string
4345
var cacheDir string
4446
var LogLevel string
4547
var format string
@@ -70,27 +72,35 @@ Tarballs can also be specified by simply providing the path to the .tar, .tar.gz
7072
}
7173

7274
func outputResults(resultMap map[string]util.Result) {
75+
7376
// Outputs diff/analysis results in alphabetical order by analyzer name
7477
sortedTypes := []string{}
7578
for analyzerType := range resultMap {
7679
sortedTypes = append(sortedTypes, analyzerType)
7780
}
7881
sort.Strings(sortedTypes)
7982

83+
// Get the writer
84+
writer, err := getWriter(outputFile)
85+
if err != nil {
86+
logrus.Error(err)
87+
}
88+
8089
results := make([]interface{}, len(resultMap))
8190
for i, analyzerType := range sortedTypes {
8291
result := resultMap[analyzerType]
8392
if json {
8493
results[i] = result.OutputStruct()
8594
} else {
86-
err := result.OutputText(analyzerType, format)
95+
err := result.OutputText(writer, analyzerType, format)
8796
if err != nil {
8897
logrus.Error(err)
8998
}
9099
}
91100
}
92101
if json {
93-
err := util.JSONify(results)
102+
103+
err := util.JSONify(writer, results)
94104
if err != nil {
95105
logrus.Error(err)
96106
}
@@ -162,6 +172,29 @@ func getCacheDir(imageName string) (string, error) {
162172
return filepath.Join(rootDir, filepath.Clean(imageName)), nil
163173
}
164174

175+
func getWriter(outputFile string) (io.Writer, error) {
176+
var err error
177+
var outWriter io.Writer
178+
179+
// If the user specifies an output file, ensure exists
180+
if outputFile != "" {
181+
182+
// The file can't exist, we would overwrite it
183+
if _, err := os.Stat(outputFile); !os.IsNotExist(err) {
184+
return os.Stdout, errors.Wrap(err, "file exists, will not overwrite")
185+
}
186+
187+
// Otherwise, output file is an io.writer
188+
outWriter, err = os.Create(outputFile)
189+
190+
}
191+
// If still doesn't exist, return stdout as the io.Writer
192+
if outputFile == "" {
193+
outWriter = os.Stdout
194+
}
195+
return outWriter, err
196+
}
197+
165198
func init() {
166199
RootCmd.PersistentFlags().StringVarP(&LogLevel, "verbosity", "v", "warning", "This flag controls the verbosity of container-diff.")
167200
RootCmd.PersistentFlags().StringVarP(&format, "format", "", "", "Format to output diff in.")
@@ -201,5 +234,5 @@ func addSharedFlags(cmd *cobra.Command) {
201234
cmd.Flags().BoolVarP(&util.SortSize, "order", "o", false, "Set this flag to sort any file/package results by descending size. Otherwise, they will be sorted by name.")
202235
cmd.Flags().BoolVarP(&noCache, "no-cache", "n", false, "Set this to force retrieval of image filesystem on each run.")
203236
cmd.Flags().StringVarP(&cacheDir, "cache-dir", "c", "", "cache directory base to create .container-diff (default is $HOME).")
204-
237+
cmd.Flags().StringVarP(&outputFile, "output", "w", "", "output file to write to (default writes to STDOUT).")
205238
}

util/analyze_output_utils.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ package util
1919
import (
2020
"errors"
2121
"fmt"
22+
"io"
2223

2324
"github.com/GoogleContainerTools/container-diff/pkg/util"
2425
"github.com/sirupsen/logrus"
2526
)
2627

2728
type Result interface {
2829
OutputStruct() interface{}
29-
OutputText(resultType string, format string) error
30+
OutputText(writer io.Writer, resultType string, format string) error
3031
}
3132

3233
type AnalyzeResult struct {
@@ -41,14 +42,14 @@ func (r ListAnalyzeResult) OutputStruct() interface{} {
4142
return r
4243
}
4344

44-
func (r ListAnalyzeResult) OutputText(resultType string, format string) error {
45+
func (r ListAnalyzeResult) OutputText(writer io.Writer, resultType string, format string) error {
4546
analysis, valid := r.Analysis.([]string)
4647
if !valid {
4748
logrus.Error("Unexpected structure of Analysis. Should be of type []string")
4849
return fmt.Errorf("Could not output %s analysis result", r.AnalyzeType)
4950
}
5051
r.Analysis = analysis
51-
return TemplateOutputFromFormat(r, "ListAnalyze", format)
52+
return TemplateOutputFromFormat(writer, r, "ListAnalyze", format)
5253

5354
}
5455

@@ -73,7 +74,7 @@ func (r MultiVersionPackageAnalyzeResult) OutputStruct() interface{} {
7374
return output
7475
}
7576

76-
func (r MultiVersionPackageAnalyzeResult) OutputText(resultType string, format string) error {
77+
func (r MultiVersionPackageAnalyzeResult) OutputText(writer io.Writer, resultType string, format string) error {
7778
analysis, valid := r.Analysis.(map[string]map[string]PackageInfo)
7879
if !valid {
7980
logrus.Error("Unexpected structure of Analysis. Should be of type map[string]map[string]PackageInfo")
@@ -91,7 +92,7 @@ func (r MultiVersionPackageAnalyzeResult) OutputText(resultType string, format s
9192
AnalyzeType: r.AnalyzeType,
9293
Analysis: strAnalysis,
9394
}
94-
return TemplateOutputFromFormat(strResult, "MultiVersionPackageAnalyze", format)
95+
return TemplateOutputFromFormat(writer, strResult, "MultiVersionPackageAnalyze", format)
9596
}
9697

9798
type SingleVersionPackageAnalyzeResult AnalyzeResult
@@ -115,7 +116,7 @@ func (r SingleVersionPackageAnalyzeResult) OutputStruct() interface{} {
115116
return output
116117
}
117118

118-
func (r SingleVersionPackageAnalyzeResult) OutputText(diffType string, format string) error {
119+
func (r SingleVersionPackageAnalyzeResult) OutputText(writer io.Writer, diffType string, format string) error {
119120
analysis, valid := r.Analysis.(map[string]PackageInfo)
120121
if !valid {
121122
logrus.Error("Unexpected structure of Analysis. Should be of type map[string]PackageInfo")
@@ -133,7 +134,7 @@ func (r SingleVersionPackageAnalyzeResult) OutputText(diffType string, format st
133134
AnalyzeType: r.AnalyzeType,
134135
Analysis: strAnalysis,
135136
}
136-
return TemplateOutputFromFormat(strResult, "SingleVersionPackageAnalyze", format)
137+
return TemplateOutputFromFormat(writer, strResult, "SingleVersionPackageAnalyze", format)
137138
}
138139

139140
type SingleVersionPackageLayerAnalyzeResult AnalyzeResult
@@ -173,7 +174,7 @@ func (r SingleVersionPackageLayerAnalyzeResult) OutputStruct() interface{} {
173174
return output
174175
}
175176

176-
func (r SingleVersionPackageLayerAnalyzeResult) OutputText(diffType string, format string) error {
177+
func (r SingleVersionPackageLayerAnalyzeResult) OutputText(writer io.Writer, diffType string, format string) error {
177178
analysis, valid := r.Analysis.(PackageLayerDiff)
178179
if !valid {
179180
logrus.Error("Unexpected structure of Analysis. Should be of type PackageLayerDiff")
@@ -205,7 +206,7 @@ func (r SingleVersionPackageLayerAnalyzeResult) OutputText(diffType string, form
205206
AnalyzeType: r.AnalyzeType,
206207
Analysis: analysisOutput,
207208
}
208-
return TemplateOutputFromFormat(strResult, "SingleVersionPackageLayerAnalyze", format)
209+
return TemplateOutputFromFormat(writer, strResult, "SingleVersionPackageLayerAnalyze", format)
209210
}
210211

211212
type PackageOutput struct {
@@ -263,7 +264,7 @@ func (r FileAnalyzeResult) OutputStruct() interface{} {
263264
return r
264265
}
265266

266-
func (r FileAnalyzeResult) OutputText(analyzeType string, format string) error {
267+
func (r FileAnalyzeResult) OutputText(writer io.Writer, analyzeType string, format string) error {
267268
analysis, valid := r.Analysis.([]util.DirectoryEntry)
268269
if !valid {
269270
logrus.Error("Unexpected structure of Analysis. Should be of type []DirectoryEntry")
@@ -286,7 +287,7 @@ func (r FileAnalyzeResult) OutputText(analyzeType string, format string) error {
286287
AnalyzeType: r.AnalyzeType,
287288
Analysis: strAnalysis,
288289
}
289-
return TemplateOutputFromFormat(strResult, "FileAnalyze", format)
290+
return TemplateOutputFromFormat(writer, strResult, "FileAnalyze", format)
290291
}
291292

292293
type FileLayerAnalyzeResult AnalyzeResult
@@ -310,7 +311,7 @@ func (r FileLayerAnalyzeResult) OutputStruct() interface{} {
310311
return r
311312
}
312313

313-
func (r FileLayerAnalyzeResult) OutputText(analyzeType string, format string) error {
314+
func (r FileLayerAnalyzeResult) OutputText(writer io.Writer, analyzeType string, format string) error {
314315
analysis, valid := r.Analysis.([][]util.DirectoryEntry)
315316
if !valid {
316317
logrus.Error("Unexpected structure of Analysis. Should be of type []DirectoryEntry")
@@ -338,7 +339,7 @@ func (r FileLayerAnalyzeResult) OutputText(analyzeType string, format string) er
338339
AnalyzeType: r.AnalyzeType,
339340
Analysis: strDirectoryEntries,
340341
}
341-
return TemplateOutputFromFormat(strResult, "FileLayerAnalyze", format)
342+
return TemplateOutputFromFormat(writer, strResult, "FileLayerAnalyze", format)
342343
}
343344

344345
type SizeAnalyzeResult AnalyzeResult
@@ -353,7 +354,7 @@ func (r SizeAnalyzeResult) OutputStruct() interface{} {
353354
return r
354355
}
355356

356-
func (r SizeAnalyzeResult) OutputText(analyzeType string, format string) error {
357+
func (r SizeAnalyzeResult) OutputText(writer io.Writer, analyzeType string, format string) error {
357358
analysis, valid := r.Analysis.([]SizeEntry)
358359
if !valid {
359360
logrus.Error("Unexpected structure of Analysis. Should be of type []SizeEntry")
@@ -371,7 +372,7 @@ func (r SizeAnalyzeResult) OutputText(analyzeType string, format string) error {
371372
AnalyzeType: r.AnalyzeType,
372373
Analysis: strAnalysis,
373374
}
374-
return TemplateOutputFromFormat(strResult, "SizeAnalyze", format)
375+
return TemplateOutputFromFormat(writer, strResult, "SizeAnalyze", format)
375376
}
376377

377378
type SizeLayerAnalyzeResult AnalyzeResult
@@ -386,7 +387,7 @@ func (r SizeLayerAnalyzeResult) OutputStruct() interface{} {
386387
return r
387388
}
388389

389-
func (r SizeLayerAnalyzeResult) OutputText(analyzeType string, format string) error {
390+
func (r SizeLayerAnalyzeResult) OutputText(writer io.Writer, analyzeType string, format string) error {
390391
analysis, valid := r.Analysis.([]SizeEntry)
391392
if !valid {
392393
logrus.Error("Unexpected structure of Analysis. Should be of type []SizeEntry")
@@ -404,5 +405,5 @@ func (r SizeLayerAnalyzeResult) OutputText(analyzeType string, format string) er
404405
AnalyzeType: r.AnalyzeType,
405406
Analysis: strAnalysis,
406407
}
407-
return TemplateOutputFromFormat(strResult, "SizeLayerAnalyze", format)
408+
return TemplateOutputFromFormat(writer, strResult, "SizeLayerAnalyze", format)
408409
}

0 commit comments

Comments
 (0)