diff options
-rw-r--r-- | README.md | 16 | ||||
-rw-r--r-- | cmd/cat.go | 11 | ||||
-rw-r--r-- | cmd/diff.go | 18 | ||||
-rw-r--r-- | cmd/helpers.go | 16 | ||||
-rw-r--r-- | cmd/list.go | 24 | ||||
-rw-r--r-- | cmd/overwrite.go | 20 | ||||
-rw-r--r-- | main.go | 4 | ||||
-rw-r--r-- | snap/parsing.go | 19 | ||||
-rw-r--r-- | snap/parsing_test.go | 12 |
9 files changed, 108 insertions, 32 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..1cd5b1e --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +ZFS File Diff: +============== + +Instead of operating at a dataset level, ZFS File Diff provides extra tools +for operating on single files within a snapshot. + +This is useful when you: +- Accedently deleted a file +- Identify the changes file over time + +``` +zfdiff list [--with-paths|-p] <reference> +zfdiff cat <snap> <reference> +zfdiff overwrite <snap> <reference> +zfdiff diff <snap>..<snap> <reference> +```
\ No newline at end of file @@ -6,7 +6,16 @@ import ( ) func Cat(params []string) { + if(len(params) == 0) { + die.Fatal("Reference file is required") + } + + if(len(params) > 3) { + die.Fatal("Too many arguments provided") + } + snapRef := snap.ToRelative(params[0]) + reference := params[1] - fmt.Println(snapRef); + fmt.Println(snapRef, reference); }
\ No newline at end of file diff --git a/cmd/diff.go b/cmd/diff.go index 7caf96b..46327b3 100644 --- a/cmd/diff.go +++ b/cmd/diff.go @@ -1,21 +1,23 @@ package cmd import ( - "flag" "fmt" + "golang.flu0r1ne.net/zfdiff/snap" ) func Diff(params []string) { - flags := flag.NewFlagSet("diff", flag.ExitOnError) - var walk bool + if(len(params) == 0) { + die.Fatal("Reference file is required") + } - const WALK_HELP = "walk backwards through the diff history" + if(len(params) > 2) { + die.Fatal("Too many arguments provided") + } - flags.BoolVar(&walk, "walk", false, WALK_HELP); - flags.BoolVar(&walk, "w", false, WALK_HELP); + from, to := snap.ParseDiff(params[0]) - flags.Parse(params); + reference := params[1] - fmt.Printf("Your flag is: %t", walk); + fmt.Println(from, to, reference); } diff --git a/cmd/helpers.go b/cmd/helpers.go new file mode 100644 index 0000000..858cdfd --- /dev/null +++ b/cmd/helpers.go @@ -0,0 +1,16 @@ +package cmd + +import ( + "os" + "log" + "flag" +) + +var die = log.New(os.Stderr, "", 0) + +func aliasedBoolVar(f * flag.FlagSet, p * bool, value bool, usage string) func(string) { + + return func(name string) { + f.BoolVar(p, name, value, usage) + } +}
\ No newline at end of file diff --git a/cmd/list.go b/cmd/list.go index d2b9a03..99d5f24 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -1,8 +1,8 @@ package cmd import ( - "flag" "fmt" + "flag" ) func List(params []string) { @@ -10,12 +10,28 @@ func List(params []string) { var withPaths bool - const WITH_PATHS_HELP = "print paths to the provided reference within the snapshot" + withName := aliasedBoolVar( + flags, + &withPaths, + false, + "print paths to the provided reference within the snapshot", + ) - flags.BoolVar(&withPaths, "paths", false, WITH_PATHS_HELP); - flags.BoolVar(&withPaths, "p", false, WITH_PATHS_HELP); + withName("paths") + withName("p") flags.Parse(params); + if(flags.NArg() == 0) { + die.Fatal("Reference file is required") + } + + if(flags.NArg() > 1) { + die.Fatal("Too many arguments provided") + } + + reference := flags.Arg(0) + + fmt.Printf(reference) fmt.Printf("Your flag is: %t", withPaths); } diff --git a/cmd/overwrite.go b/cmd/overwrite.go index 6f4a00b..324dfb4 100644 --- a/cmd/overwrite.go +++ b/cmd/overwrite.go @@ -1,21 +1,21 @@ package cmd import ( - "flag" "fmt" + "golang.flu0r1ne.net/zfdiff/snap" ) func Overwrite(params [] string) { - flags := flag.NewFlagSet("overwrite", flag.ExitOnError); + if(len(params) == 0) { + die.Fatal("Reference file is required") + } - var withBackup bool + if(len(params) > 3) { + die.Fatal("Too many arguments provided") + } - const WITH_BACKUP_HELP = "backup the file by creating a snapshot" + snapRef := snap.ToRelative(params[0]) + reference := params[1] - flags.BoolVar(&withBackup, "backup", false, WITH_BACKUP_HELP); - flags.BoolVar(&withBackup, "b", false, WITH_BACKUP_HELP); - - flags.Parse(params); - - fmt.Printf("Your flag is: %t", withBackup); + fmt.Print(snapRef, reference) }
\ No newline at end of file @@ -12,9 +12,9 @@ func printUsage(w io.Writer) { fmt.Fprintln(w, " help ") fmt.Fprintln(w, " version ") fmt.Fprintln(w, " list [-paths|-p] <reference> ") - fmt.Fprintln(w, " diff [-walk|-w] <snap-ish>..<snap-ish> <reference> ") + fmt.Fprintln(w, " diff <snap-ish>..<snap-ish> <reference> ") fmt.Fprintln(w, " cat <snap-ish> <reference> ") - fmt.Fprintln(w, " overwrite [-backup|-b] <snap-ish> <reference> ") + fmt.Fprintln(w, " overwrite <snap-ish> <reference> ") } func dieUsage() { diff --git a/snap/parsing.go b/snap/parsing.go index a848c33..e878077 100644 --- a/snap/parsing.go +++ b/snap/parsing.go @@ -78,7 +78,7 @@ func ToRelative(snapish string) * Relative { return ref; } - if ref := parseRelativeSyntax(snapish, "-"); ref != nil { + if ref := parseRelativeSyntax(snapish, "~"); ref != nil { ref.offset = -ref.offset; return ref; } @@ -86,4 +86,21 @@ func ToRelative(snapish string) * Relative { return &Relative{ snapshot: snapish, }; +} + +// FROM, TO +func ParseDiff(snapdiff string) (fromRel, toRel *Relative) { + snapishes := strings.Split(snapdiff, "..") + + if(len(snapishes) > 2) { + die.Fatal("Cannot diff more than two snapshots"); + } + + fromRel = ToRelative(snapishes[0]) + toRel = &Relative{} + if(len(snapishes) == 2) { + toRel = ToRelative(snapishes[1]) + } + + return }
\ No newline at end of file diff --git a/snap/parsing_test.go b/snap/parsing_test.go index 1a87723..4aa232e 100644 --- a/snap/parsing_test.go +++ b/snap/parsing_test.go @@ -9,16 +9,16 @@ func TestRelativeParsing(t * testing.T) { offset int } { {"snapshot", "snapshot", 0}, - {"testing--", "testing", -2}, + {"testing~~", "testing", -2}, {"%SNAPSHOT%^+++", "%SNAPSHOT%^", 3}, - {"--prefixed", "--prefixed", 0}, + {"~~prefixed", "~~prefixed", 0}, {"+++", "", 3}, - {"---", "", -3}, + {"~~~", "", -3}, {"+5", "", 5}, - {"-3", "", -3}, + {"~3", "", -3}, {"+", "", 1}, - {"-", "", -1}, - {`"-"`, "-", 0}, + {"~", "", -1}, + {`"~"`, "~", 0}, } for _, c := range cases { |