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

Commit cf169f6

Browse files
authored
Merge pull request #121 from priyawadhwa/diff-within-files
Diff within files
2 parents a2c4d96 + f376e3a commit cf169f6

File tree

5 files changed

+127
-5
lines changed

5 files changed

+127
-5
lines changed

cmd/diff.go

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,18 @@ package cmd
1919
import (
2020
"errors"
2121
"fmt"
22-
"os"
23-
"strings"
24-
"sync"
25-
2622
"github.com/GoogleCloudPlatform/container-diff/differs"
2723
pkgutil "github.com/GoogleCloudPlatform/container-diff/pkg/util"
24+
"github.com/GoogleCloudPlatform/container-diff/util"
2825
"github.com/sirupsen/logrus"
2926
"github.com/spf13/cobra"
27+
"os"
28+
"strings"
29+
"sync"
3030
)
3131

32+
var filename string
33+
3234
var diffCmd = &cobra.Command{
3335
Use: "diff",
3436
Short: "Compare two images: [image1] [image2]",
@@ -40,6 +42,9 @@ var diffCmd = &cobra.Command{
4042
if err := checkIfValidAnalyzer(types); err != nil {
4143
return err
4244
}
45+
if err := checkFilenameFlag(types); err != nil {
46+
return err
47+
}
4348
return nil
4449
},
4550
Run: func(cmd *cobra.Command, args []string) {
@@ -57,6 +62,15 @@ func checkDiffArgNum(args []string) error {
5762
return nil
5863
}
5964

65+
func checkFilenameFlag(types string) error {
66+
if filename != "" {
67+
if !strings.Contains(types, "file") {
68+
return errors.New("Please include --types=file with the --filename flag")
69+
}
70+
}
71+
return nil
72+
}
73+
6074
func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
6175
diffTypes, err := differs.GetAnalyzers(diffArgs)
6276
if err != nil {
@@ -109,14 +123,32 @@ func diffImages(image1Arg, image2Arg string, diffArgs []string) error {
109123
}
110124
outputResults(diffs)
111125

126+
if filename != "" {
127+
fmt.Fprintln(os.Stderr, "Computing filename diffs")
128+
err := diffFile(imageMap[image1Arg], imageMap[image2Arg])
129+
if err != nil {
130+
return err
131+
}
132+
}
133+
112134
if save {
113135
logrus.Infof("Images were saved at %s and %s", imageMap[image1Arg].FSPath,
114136
imageMap[image2Arg].FSPath)
115137
}
116138
return nil
117139
}
118140

141+
func diffFile(image1, image2 *pkgutil.Image) error {
142+
diff, err := util.DiffFile(image1, image2, filename)
143+
if err != nil {
144+
return err
145+
}
146+
util.TemplateOutput(diff, "FilenameDiff")
147+
return nil
148+
}
149+
119150
func init() {
151+
diffCmd.Flags().StringVarP(&filename, "filename", "f", "", "Set this flag to the path of a file in both containers to view the diff of the file. Must be used with --types=file flag.")
120152
RootCmd.AddCommand(diffCmd)
121153
addSharedFlags(diffCmd)
122154
}

pkg/util/fs_utils.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,25 @@ func GetSize(path string) int64 {
5353
return stat.Size()
5454
}
5555

56+
//GetFileContents returns the contents of a file at the specified path
57+
func GetFileContents(path string) (*string, error) {
58+
if _, err := os.Stat(path); os.IsNotExist(err) {
59+
return nil, err
60+
}
61+
62+
contents, err := ioutil.ReadFile(path)
63+
if err != nil {
64+
return nil, err
65+
}
66+
67+
strContents := string(contents)
68+
//If file is empty, return nil
69+
if strContents == "" {
70+
return nil, nil
71+
}
72+
return &strContents, nil
73+
}
74+
5675
func getDirectorySize(path string) (int64, error) {
5776
var size int64
5877
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {

util/diff_utils.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ type DirDiff struct {
3434
Mods []EntryDiff
3535
}
3636

37+
type FileNameDiff struct {
38+
Filename string
39+
Description string
40+
Diff string
41+
}
42+
3743
type EntryDiff struct {
3844
Name string
3945
Size1 int64
@@ -118,6 +124,64 @@ func DiffDirectory(d1, d2 pkgutil.Directory) (DirDiff, bool) {
118124
return DirDiff{addedEntries, deletedEntries, modifiedEntries}, same
119125
}
120126

127+
func DiffFile(image1, image2 *pkgutil.Image, filename string) (*FileNameDiff, error) {
128+
//Join paths
129+
image1FilePath := filepath.Join(image1.FSPath, filename)
130+
image2FilePath := filepath.Join(image2.FSPath, filename)
131+
132+
//Get contents of files
133+
image1FileContents, err := pkgutil.GetFileContents(image1FilePath)
134+
if err != nil {
135+
return nil, err
136+
}
137+
138+
image2FileContents, err := pkgutil.GetFileContents(image2FilePath)
139+
if err != nil {
140+
return nil, err
141+
}
142+
143+
description := ""
144+
//Check if file contents are empty or if they are the same
145+
if image1FileContents == nil && image2FileContents == nil {
146+
description := "Both files are empty"
147+
return &FileNameDiff{filename, description, ""}, nil
148+
}
149+
150+
if image1FileContents == nil {
151+
description := fmt.Sprintf("%s contains an empty file, the contents of %s are:", image1.Source, image2.Source)
152+
return &FileNameDiff{filename, description, *image2FileContents}, nil
153+
}
154+
155+
if image2FileContents == nil {
156+
description := fmt.Sprintf("%s contains an empty file, the contents of %s are:", image2.Source, image1.Source)
157+
return &FileNameDiff{filename, description, *image1FileContents}, nil
158+
}
159+
160+
if *image1FileContents == *image2FileContents {
161+
description := "Both files are the same, the contents are:"
162+
return &FileNameDiff{filename, description, *image1FileContents}, nil
163+
}
164+
165+
//Carry on with diffing, make string array for difflib requirements
166+
image1Contents := []string{string(*image1FileContents)}
167+
image2Contents := []string{string(*image2FileContents)}
168+
169+
//Run diff
170+
diff := difflib.UnifiedDiff{
171+
A: image1Contents,
172+
B: image2Contents,
173+
FromFile: image1.Source,
174+
ToFile: image2.Source,
175+
}
176+
177+
text, err := difflib.GetUnifiedDiffString(diff)
178+
179+
if err != nil {
180+
return nil, err
181+
}
182+
return &FileNameDiff{filename, description, text}, nil
183+
}
184+
121185
// Checks for content differences between files of the same name from different directories
122186
func GetModifiedEntries(d1, d2 pkgutil.Directory) []string {
123187
d1files := d1.Content

util/format_utils.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ import (
2020
"bufio"
2121
"encoding/json"
2222
"errors"
23-
"html/template"
2423
"os"
2524
"strings"
2625
"text/tabwriter"
26+
"text/template"
2727

2828
"github.com/sirupsen/logrus"
2929
)
@@ -33,6 +33,7 @@ var templates = map[string]string{
3333
"MultiVersionPackageDiff": MultiVersionDiffOutput,
3434
"HistDiff": HistoryDiffOutput,
3535
"DirDiff": FSDiffOutput,
36+
"FilenameDiff": FilenameDiffOutput,
3637
"ListAnalyze": ListAnalysisOutput,
3738
"FileAnalyze": FileAnalysisOutput,
3839
"MultiVersionPackageAnalyze": MultiVersionPackageOutput,

util/template_utils.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ Docker history lines found only in {{.Image1}}:{{if not .Diff.Adds}} None{{else}
6565
6666
Docker history lines found only in {{.Image2}}:{{if not .Diff.Dels}} None{{else}}{{block "list2" .Diff.Dels}}{{"\n"}}{{range .}}{{print "-" .}}{{"\n"}}{{end}}{{end}}{{end}}
6767
`
68+
const FilenameDiffOutput = `
69+
-----Diff of {{.Filename}}-----
70+
{{.Description}}
71+
72+
{{.Diff}}
73+
`
6874

6975
const ListAnalysisOutput = `
7076
-----{{.AnalyzeType}}-----

0 commit comments

Comments
 (0)