summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/rsc/arq/hist/hist.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mattermost/rsc/arq/hist/hist.go')
-rw-r--r--vendor/github.com/mattermost/rsc/arq/hist/hist.go160
1 files changed, 160 insertions, 0 deletions
diff --git a/vendor/github.com/mattermost/rsc/arq/hist/hist.go b/vendor/github.com/mattermost/rsc/arq/hist/hist.go
new file mode 100644
index 000000000..02fb5fbf0
--- /dev/null
+++ b/vendor/github.com/mattermost/rsc/arq/hist/hist.go
@@ -0,0 +1,160 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Hist shows the history of a given file, using Arq backups.
+
+ usage: hist [-d] [-h host] [-m mtpt] [-s yyyy/mmdd] file ...
+
+The -d flag causes it to show diffs between successive versions.
+
+By default, hist assumes backups are mounted at mtpt/host, where
+mtpt defaults to /mnt/arq and host is the first element of the local host name.
+Hist starts the file list with the present copy of the file.
+
+The -h and -s flags override these assumptions.
+
+*/
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+var usageString = `usage: hist [-d] [-h host] [-m mtpt] [-s yyyy/mmdd] file ...
+
+Hist lists the known versions of the given file.
+The -d flag causes it to show diffs between successive versions.
+
+By default, hist assumes backups are mounted at mtpt/host, where
+mtpt defaults to /mnt/arq and host is the first element of the local host name.
+Hist starts the file list with the present copy of the file.
+
+The -h and -s flags override these assumptions.
+`
+
+var (
+ diff = flag.Bool("d", false, "diff")
+ host = flag.String("h", defaultHost(), "host name")
+ mtpt = flag.String("m", "/mnt/arq", "mount point")
+ vers = flag.String("s", "", "version")
+)
+
+func defaultHost() string {
+ name, _ := os.Hostname()
+ if name == "" {
+ name = "gnot"
+ }
+ if i := strings.Index(name, "."); i >= 0 {
+ name = name[:i]
+ }
+ return name
+}
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprint(os.Stderr, usageString)
+ os.Exit(2)
+ }
+
+ flag.Parse()
+ args := flag.Args()
+ if len(args) == 0 {
+ flag.Usage()
+ }
+
+ dates := loadDates()
+ for _, file := range args {
+ list(dates, file)
+ }
+}
+
+var (
+ yyyy = regexp.MustCompile(`^\d{4}$`)
+ mmdd = regexp.MustCompile(`^\d{4}(\.\d+)?$`)
+)
+
+func loadDates() []string {
+ var all []string
+ ydir, err := ioutil.ReadDir(filepath.Join(*mtpt, *host))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ os.Exit(3)
+ }
+ for _, y := range ydir {
+ if !y.IsDir() || !yyyy.MatchString(y.Name()) {
+ continue
+ }
+ ddir, err := ioutil.ReadDir(filepath.Join(*mtpt, *host, y.Name()))
+ if err != nil {
+ continue
+ }
+ for _, d := range ddir {
+ if !d.IsDir() || !mmdd.MatchString(d.Name()) {
+ continue
+ }
+ date := y.Name() + "/" + d.Name()
+ if *vers > date {
+ continue
+ }
+ all = append(all, filepath.Join(*mtpt, *host, date))
+ }
+ }
+ return all
+}
+
+const timeFormat = "Jan 02 15:04:05 MST 2006"
+
+func list(dates []string, file string) {
+ var (
+ last os.FileInfo
+ lastPath string
+ )
+
+ fi, err := os.Stat(file)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "hist: warning: %s: %v\n", file, err)
+ } else {
+ fmt.Printf("%s %s %d\n", fi.ModTime().Format(timeFormat), file, fi.Size())
+ last = fi
+ lastPath = file
+ }
+
+ file, err = filepath.Abs(file)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "hist: abs: %v\n", err)
+ return
+ }
+
+ for i := len(dates)-1; i >= 0; i-- {
+ p := filepath.Join(dates[i], file)
+ fi, err := os.Stat(p)
+ if err != nil {
+ continue
+ }
+ if last != nil && fi.ModTime() == last.ModTime() && fi.Size() == last.Size() {
+ continue
+ }
+ if *diff {
+ cmd := exec.Command("diff", lastPath, p)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Start(); err != nil {
+ fmt.Fprintf(os.Stderr, "%s\n", err)
+ }
+ cmd.Wait()
+ }
+ fmt.Printf("%s %s %d\n", fi.ModTime().Format(timeFormat), p, fi.Size())
+ last = fi
+ lastPath = p
+ }
+}
+