Skip to content

Commit

Permalink
Fix color-words and word-diff not respecting --include flag (fixes #24)
Browse files Browse the repository at this point in the history
  • Loading branch information
aswinkarthik committed Oct 8, 2019
1 parent 684b899 commit bc535ee
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 53 deletions.
8 changes: 1 addition & 7 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@ import (
"github.com/aswinkarthik/csvdiff/pkg/digest"
)

var config Config

func init() {
config = Config{}
}

// Config is to store all command line Flags.
type Config struct {
PrimaryKeyPositions []int
Expand All @@ -39,7 +33,7 @@ func (c *Config) GetValueColumns() digest.Positions {

// GetIncludeColumnPositions is to return the --include flags as digest.Positions array.
// If empty, it is value columns
func (c *Config) GetIncludeColumnPositions() digest.Positions {
func (c Config) GetIncludeColumnPositions() digest.Positions {
if len(c.IncludeColumnPositions) > 0 {
return c.IncludeColumnPositions
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (f *Formatter) legacyJSON(diff digest.Differences) error {
Deletions []string
}

includes := config.GetIncludeColumnPositions()
includes := f.config.GetIncludeColumnPositions()

additions := make([]string, 0, len(diff.Additions))
for _, addition := range diff.Additions {
Expand Down Expand Up @@ -99,7 +99,7 @@ func (f *Formatter) legacyJSON(diff digest.Differences) error {
// JSONFormatter formats diff to as a JSON Object
// { "Additions": [...], "Modifications": [{ "Original": [...], "Current": [...]}]}
func (f *Formatter) json(diff digest.Differences) error {
includes := config.GetIncludeColumnPositions()
includes := f.config.GetIncludeColumnPositions()

additions := make([]string, 0, len(diff.Additions))
for _, addition := range diff.Additions {
Expand Down Expand Up @@ -151,7 +151,7 @@ func (f *Formatter) rowMark(diff digest.Differences) error {
_, _ = fmt.Fprintf(f.stderr, "Deletions %d\n", len(diff.Deletions))
_, _ = fmt.Fprintf(f.stderr, "Rows:\n")

includes := config.GetIncludeColumnPositions()
includes := f.config.GetIncludeColumnPositions()

additions := make([]string, 0, len(diff.Additions))
for _, addition := range diff.Additions {
Expand Down Expand Up @@ -185,7 +185,7 @@ func (f *Formatter) rowMark(diff digest.Differences) error {

// lineDiff is git-style line diff
func (f *Formatter) lineDiff(diff digest.Differences) error {
includes := config.GetIncludeColumnPositions()
includes := f.config.GetIncludeColumnPositions()

blue := color.New(color.FgBlue).FprintfFunc()
red := color.New(color.FgRed).FprintfFunc()
Expand Down Expand Up @@ -219,9 +219,9 @@ func (f *Formatter) colorWords(diff digest.Differences) error {
}

func (f *Formatter) wordLevelDiffs(diff digest.Differences, deletionFormat, additionFormat string) error {
includes := config.GetIncludeColumnPositions()
includes := f.config.GetIncludeColumnPositions()
if len(includes) <= 0 {
includes = config.GetValueColumns()
includes = f.config.GetValueColumns()
}
blue := color.New(color.FgBlue).SprintfFunc()
red := color.New(color.FgRed).SprintfFunc()
Expand All @@ -244,7 +244,7 @@ func (f *Formatter) wordLevelDiffs(diff digest.Differences, deletionFormat, addi
result = append(result, modification.Current[i])
}
}
_, _ = fmt.Fprintln(f.stdout, digest.Positions{}.String(result))
_, _ = fmt.Fprintln(f.stdout, includes.String(result))
}

_, _ = fmt.Fprintln(f.stderr, blue("# Deletions (%d)", len(diff.Deletions)))
Expand Down
63 changes: 49 additions & 14 deletions cmd/formatter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,30 +130,65 @@ func TestLineDiff(t *testing.T) {
}

func TestWordDiff(t *testing.T) {
diff := digest.Differences{
Additions: []digest.Addition{[]string{"additions"}},
Modifications: []digest.Modification{{Original: []string{"original"}, Current: []string{"modification"}}},
Deletions: []digest.Deletion{{"deletions"}},
}
expectedStdout := `{+additions+}
t.Run("should cover single column happy path", func(t *testing.T) {
diff := digest.Differences{
Additions: []digest.Addition{[]string{"additions"}},
Modifications: []digest.Modification{{Original: []string{"original"}, Current: []string{"modification"}}},
Deletions: []digest.Deletion{{"deletions"}},
}
expectedStdout := `{+additions+}
[-original-]{+modification+}
[-deletions-]
`
expectedStderr := `# Additions (1)
expectedStderr := `# Additions (1)
# Modifications (1)
# Deletions (1)
`

var stdout bytes.Buffer
var stderr bytes.Buffer
var stdout bytes.Buffer
var stderr bytes.Buffer

formatter := cmd.NewFormatter(&stdout, &stderr, cmd.Config{Format: "word-diff"})
formatter := cmd.NewFormatter(&stdout, &stderr, cmd.Config{Format: "word-diff"})

err := formatter.Format(diff)
err := formatter.Format(diff)

assert.NoError(t, err)
assert.Equal(t, expectedStdout, stdout.String())
assert.Equal(t, expectedStderr, stderr.String())
assert.NoError(t, err)
assert.Equal(t, expectedStdout, stdout.String())
assert.Equal(t, expectedStderr, stderr.String())
})

t.Run("should ouput only selective columns", func(t *testing.T) {
diff := digest.Differences{
Additions: []digest.Addition{[]string{"additions", "ignored-column"}},
Modifications: []digest.Modification{
{Original: []string{"original", "ignored-column"}, Current: []string{"modification", "ignored-column"}},
},
Deletions: []digest.Deletion{{"deletions", "ignored-column"}},
}
expectedStdout := `{+additions+}
[-original-]{+modification+}
[-deletions-]
`
expectedStderr := `# Additions (1)
# Modifications (1)
# Deletions (1)
`

var stdout bytes.Buffer
var stderr bytes.Buffer

formatter := cmd.NewFormatter(&stdout, &stderr, cmd.Config{
Format: "word-diff",
IncludeColumnPositions: digest.Positions{0},
})

err := formatter.Format(diff)

assert.NoError(t, err)
assert.Equal(t, expectedStdout, stdout.String())
assert.Equal(t, expectedStderr, stderr.String())

})
}

func TestColorWords(t *testing.T) {
Expand Down
63 changes: 38 additions & 25 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package cmd

import (
"fmt"
"github.com/fatih/color"
"io"
"os"
"strings"
Expand All @@ -37,8 +38,10 @@ var (

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "csvdiff <base-csv> <delta-csv>",
Short: "A diff tool for database tables dumped as csv files",
Use: "csvdiff <base-csv> <delta-csv>",
SilenceUsage: true,
SilenceErrors: true,
Short: "A diff tool for database tables dumped as csv files",
Long: `Differentiates two csv files and finds out the additions and modifications.
Most suitable for csv files created from database tables`,
PreRunE: func(cmd *cobra.Command, args []string) error {
Expand All @@ -55,14 +58,9 @@ Most suitable for csv files created from database tables`,
return err
}

// Validate flags
if err := config.Validate(); err != nil {
return err
}

return nil
},
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if timed {
defer timeTrack(time.Now(), "csvdiff")
}
Expand All @@ -72,30 +70,37 @@ Most suitable for csv files created from database tables`,
deltaFile := newReadCloser(args[1])
defer deltaFile.Close()

config := Config{
IncludeColumnPositions: includeColumnPositions,
Format: format,
PrimaryKeyPositions: primaryKeyPositions,
ValueColumnPositions: valueColumnPositions,
}

if err := config.Validate(); err != nil {
return err
}

baseConfig := digest.NewConfig(
baseFile,
config.GetPrimaryKeys(),
config.GetValueColumns(),
config.GetIncludeColumnPositions(),
primaryKeyPositions,
valueColumnPositions,
includeColumnPositions,
)
deltaConfig := digest.NewConfig(
deltaFile,
config.GetPrimaryKeys(),
config.GetValueColumns(),
config.GetIncludeColumnPositions(),
primaryKeyPositions,
valueColumnPositions,
includeColumnPositions,
)

diff, err := digest.Diff(*baseConfig, *deltaConfig)

if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "csvdiff failed: %v\n", err)
os.Exit(2)
return err
}

if err := NewFormatter(os.Stdout, os.Stderr, config).Format(diff); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "csvdiff failed: %v\n", err)
os.Exit(3)
}
return NewFormatter(os.Stdout, os.Stderr, config).Format(diff)
},
}

Expand All @@ -122,18 +127,26 @@ func isValidFile(path string) error {
func Execute() {
rootCmd.Version = Version()
if err := rootCmd.Execute(); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "%v\n", err)
_, _ = fmt.Fprint(os.Stderr, color.RedString("csvdiff: command failed - %v\n\n", err))
_ = rootCmd.Help()
os.Exit(1)
}
}

var (
primaryKeyPositions []int
valueColumnPositions []int
includeColumnPositions []int
format string
)

func init() {
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")

rootCmd.Flags().IntSliceVarP(&config.PrimaryKeyPositions, "primary-key", "p", []int{0}, "Primary key positions of the Input CSV as comma separated values Eg: 1,2")
rootCmd.Flags().IntSliceVarP(&config.ValueColumnPositions, "columns", "", []int{}, "Selectively compare positions in CSV Eg: 1,2. Default is entire row")
rootCmd.Flags().IntSliceVarP(&config.IncludeColumnPositions, "include", "", []int{}, "Include positions in CSV to display Eg: 1,2. Default is entire row")
rootCmd.Flags().StringVarP(&config.Format, "format", "o", "diff", fmt.Sprintf("Available (%s)", strings.Join(allFormats, "|")))
rootCmd.Flags().IntSliceVarP(&primaryKeyPositions, "primary-key", "p", []int{0}, "Primary key positions of the Input CSV as comma separated values Eg: 1,2")
rootCmd.Flags().IntSliceVarP(&valueColumnPositions, "columns", "", []int{}, "Selectively compare positions in CSV Eg: 1,2. Default is entire row")
rootCmd.Flags().IntSliceVarP(&includeColumnPositions, "include", "", []int{}, "Include positions in CSV to display Eg: 1,2. Default is entire row")
rootCmd.Flags().StringVarP(&format, "format", "o", "diff", fmt.Sprintf("Available (%s)", strings.Join(allFormats, "|")))

rootCmd.Flags().BoolVarP(&timed, "time", "", false, "Measure time")
}
Expand Down

0 comments on commit bc535ee

Please sign in to comment.