From af8f52e2e4c879935656dd93c2fb564c6e2ce515 Mon Sep 17 00:00:00 2001
From: flu0r1ne <flu0r1ne@flu0r1ne.net>
Date: Thu, 22 Jul 2021 00:41:30 -0500
Subject: Parse within subcommands

---
 README.md            | 16 ++++++++++++++++
 cmd/cat.go           | 11 ++++++++++-
 cmd/diff.go          | 18 ++++++++++--------
 cmd/helpers.go       | 16 ++++++++++++++++
 cmd/list.go          | 24 ++++++++++++++++++++----
 cmd/overwrite.go     | 20 ++++++++++----------
 main.go              |  4 ++--
 snap/parsing.go      | 19 ++++++++++++++++++-
 snap/parsing_test.go | 12 ++++++------
 9 files changed, 108 insertions(+), 32 deletions(-)
 create mode 100644 README.md
 create mode 100644 cmd/helpers.go

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
diff --git a/cmd/cat.go b/cmd/cat.go
index 4f54abc..d5a275d 100644
--- a/cmd/cat.go
+++ b/cmd/cat.go
@@ -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
diff --git a/main.go b/main.go
index 31a9640..42c9f16 100644
--- a/main.go
+++ b/main.go
@@ -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 {
-- 
cgit v1.2.3