Skip to content

Commit

Permalink
adding json support and refactoring (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
agrimrules authored Jul 21, 2021
1 parent 6411122 commit 55e794e
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 25 deletions.
32 changes: 30 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,53 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"name": "two files",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": [
"README.md",
"README.md",
"-o",
"json"
]
},
{
"name": "test with dirs",
"name": "two dirs",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": [
"/home/agrim/Downloads/kubernetes-master",
"/home/agrim/Downloads/kubernetes-master-1",
"-o",
"json"
]
},
{
"name": "one dir",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": [
"/home/agrim/Downloads/kubernetes-master",
"-o",
"json"
]
},
{
"name": "one file",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"args": [
"README.md",
"-o",
"json"
]
}
]
Expand Down
36 changes: 20 additions & 16 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cmd

import (
"encoding/json"
"fmt"
"os"

Expand All @@ -27,6 +28,7 @@ import (
var version = "dev"
var v bool
var h string
var o string

var rootCmd = &cobra.Command{
Use: "hashmatch",
Expand All @@ -52,32 +54,33 @@ var rootCmd = &cobra.Command{
case 1:
var d []utils.HashResults
if isArg0Directory {
d = utils.GetMD5ForFiles(utils.ReturnFilesInFolder(args[0]), h)
d = utils.GetHashesForFiles(utils.ReturnFilesInFolder(args[0]), h)
} else {
d = utils.GetMD5ForFiles(args, h)
d = utils.GetHashesForFiles(args, h)
}
table := utils.CreateTable(d, h)
table.ClearFooter()
table.Render()
os.Exit(exitcode)
utils.HandleOutput(d, h, o, false, true)

case 2:
if isArg0Directory && isArg1Directory {
d1 := utils.GetMD5ForFiles(utils.ReturnFilesInFolder(args[0]), h)
d2 := utils.GetMD5ForFiles(utils.ReturnFilesInFolder(args[1]), h)
d1 := utils.GetHashesForFiles(utils.ReturnFilesInFolder(args[0]), h)
d2 := utils.GetHashesForFiles(utils.ReturnFilesInFolder(args[1]), h)
areEqual, diff := utils.HashesAreEqual(d1, d2)
if !areEqual {
table := utils.CreateDirTable(diff, h)
table.Render()
os.Exit(exitcode)
utils.HandleOutput(diff, h, o, true, false)
}
if o == "table" {
fmt.Println("Files match ✅")
}
if o == "json" {
op, _ := json.MarshalIndent(struct {
Matched bool `json:"matched"`
}{Matched: true}, "", " ")
fmt.Println(string(op))
}
fmt.Println("Files match ✅")
os.Exit(exitcode)
} else if !isArg0Directory && !isArg1Directory {
data := utils.GetMD5ForFiles(args, h)
table := utils.CreateTable(data, h)
table.Render()
os.Exit(exitcode)
data := utils.GetHashesForFiles(args, h)
utils.HandleOutput(data, h, o, false, false)
}
fmt.Println("Can only compare two folders or two files")

Expand All @@ -93,5 +96,6 @@ var rootCmd = &cobra.Command{
func Execute() {
rootCmd.Flags().BoolVarP(&v, "version", "v", false, "Print version")
rootCmd.Flags().StringVarP(&h, "hash", "", "md5sum", "Specify hash algorithm to use")
rootCmd.Flags().StringVarP(&o, "output", "o", "table", "Specify the output format to use")
cobra.CheckErr(rootCmd.Execute())
}
21 changes: 17 additions & 4 deletions utils/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ import (
"os"
)

// HashResults store the computed hash of a filename
type HashResults struct {
filename string
hash string
Filename string `json:"filename"`
Hash string `json:"hash"`
}

func GetMD5ForFiles(files []string, algo string) []HashResults {
// JSONHashResults are a json representation of the results
type JSONHashResults struct {
Results []HashResults `json:"results"`
Match bool `json:"matched"`
Algo string `json:"algo"`
}

// GetHashesForFiles returns the hashes for a given set of files
func GetHashesForFiles(files []string, algo string) []HashResults {
results := []HashResults{}
var h hash.Hash
switch algo {
Expand Down Expand Up @@ -51,8 +60,12 @@ func GetMD5ForFiles(files []string, algo string) []HashResults {

func HashesAreEqual(hr1 []HashResults, hr2 []HashResults) (bool, []HashResults) {
mismatches := []HashResults{}
if len(hr1) != len(hr2) {
fmt.Println("Number of files do not match")
os.Exit(-1)
}
for i, v := range hr1 {
if v.hash != hr2[i].hash {
if v.Hash != hr2[i].Hash {
mismatches = append(mismatches, v, hr2[i])
}
}
Expand Down
49 changes: 46 additions & 3 deletions utils/table.go → utils/output.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package utils

import (
"encoding/json"
"fmt"
"os"
"strings"

"github.com/olekukonko/tablewriter"
"github.com/thoas/go-funk"
)

// CreateTable returns a formatted table to render
func CreateTable(rows []HashResults, algo string) *tablewriter.Table {
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"File", algo})
table.SetHeaderColor(tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold, tablewriter.BgGreenColor},
tablewriter.Colors{tablewriter.FgBlackColor, tablewriter.Bold, tablewriter.BgGreenColor})

for _, v := range rows {
table.Append([]string{v.filename, v.hash})
table.Append([]string{v.Filename, v.Hash})
}
if len(rows) >= 2 {
if strings.Compare(rows[0].hash, rows[1].hash) == 0 {
if strings.Compare(rows[0].Hash, rows[1].Hash) == 0 {
table.SetFooter([]string{"Files match ✅", ""})
} else {
table.SetFooter([]string{"Files don't match ❌", ""})
Expand All @@ -27,6 +30,7 @@ func CreateTable(rows []HashResults, algo string) *tablewriter.Table {
return table
}

//CreateDirTable returns a two column table to render
func CreateDirTable(rows []HashResults, algo string) *tablewriter.Table {
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Source File", algo, "Destination File", algo})
Expand All @@ -38,8 +42,47 @@ func CreateDirTable(rows []HashResults, algo string) *tablewriter.Table {
table.SetFooter([]string{"Files don't match ❌", "", "", ""})
dualRows := funk.Chunk(rows, 2).([][]HashResults)
for _, v := range dualRows {
table.Append([]string{v[0].filename, v[0].hash, v[1].filename, v[1].hash})
table.Append([]string{v[0].Filename, v[0].Hash, v[1].Filename, v[1].Hash})
}
}
return table
}

//HandleOutput is used to provide the output in the required format
func HandleOutput(op []HashResults, h string, format string, isDir bool, clearFooter bool) {
var table *tablewriter.Table
switch format {
case "table":
if !isDir {
table = CreateTable(op, h)
} else {
table = CreateDirTable(op, h)
}
if clearFooter {
table.ClearFooter()
}
table.Render()
os.Exit(0)
case "json":
outputArray := JSONHashResults{Results: op, Algo: h}
if clearFooter {
s, _ := json.MarshalIndent(struct {
Results []HashResults `json:"results"`
Algo string `json:"algo"`
}{Results: op, Algo: h}, "", " ")
fmt.Println(string(s))
os.Exit(0)
} else {
if len(op) >= 2 {
if strings.Compare(op[0].Hash, op[1].Hash) == 0 {
outputArray.Match = true
} else {
outputArray.Match = false
}
}
}
s, _ := json.MarshalIndent(outputArray, "", " ")
fmt.Println(string(s))
os.Exit(0)
}
}

0 comments on commit 55e794e

Please sign in to comment.