From c51d97c75247d1a7ddf64a452d1c1afdd0ba97bb Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 20 Apr 2018 11:33:50 +0100 Subject: [PATCH] hashsum: make generic tool for any hash to produce md5sum like output --- cmd/all/all.go | 1 + cmd/hashsum/hashsum.go | 61 +++++++++++++++++++++++++++++++++++++ fs/operations/operations.go | 9 +++--- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 cmd/hashsum/hashsum.go diff --git a/cmd/all/all.go b/cmd/all/all.go index 79b6900be..be05071bc 100644 --- a/cmd/all/all.go +++ b/cmd/all/all.go @@ -21,6 +21,7 @@ import ( _ "github.com/ncw/rclone/cmd/delete" _ "github.com/ncw/rclone/cmd/genautocomplete" _ "github.com/ncw/rclone/cmd/gendocs" + _ "github.com/ncw/rclone/cmd/hashsum" _ "github.com/ncw/rclone/cmd/info" _ "github.com/ncw/rclone/cmd/link" _ "github.com/ncw/rclone/cmd/listremotes" diff --git a/cmd/hashsum/hashsum.go b/cmd/hashsum/hashsum.go new file mode 100644 index 000000000..e6afcb9fd --- /dev/null +++ b/cmd/hashsum/hashsum.go @@ -0,0 +1,61 @@ +package hashsum + +import ( + "errors" + "fmt" + "os" + + "github.com/ncw/rclone/cmd" + "github.com/ncw/rclone/fs/hash" + "github.com/ncw/rclone/fs/operations" + "github.com/spf13/cobra" +) + +func init() { + cmd.Root.AddCommand(commandDefinition) +} + +var commandDefinition = &cobra.Command{ + Use: "hashsum remote:path", + Short: `Produces an hashsum file for all the objects in the path.`, + Long: ` +Produces a hash file for all the objects in the path using the hash +named. The output is in the same format as the standard +md5sum/sha1sum tool. + +Run without a hash to see the list of supported hashes, eg + + $ rclone hashsum + Supported hashes are: + * MD5 + * SHA-1 + * DropboxHash + * QuickXorHash + +Then + + $ rclone hashsum MD5 remote:path +`, + RunE: func(command *cobra.Command, args []string) error { + cmd.CheckArgs(0, 2, command, args) + if len(args) == 0 { + fmt.Printf("Supported hashes are:\n") + for _, ht := range hash.Supported.Array() { + fmt.Printf(" * %v\n", ht) + } + return nil + } else if len(args) == 1 { + return errors.New("need hash type and remote") + } + var ht hash.Type + err := ht.Set(args[0]) + if err != nil { + return err + } + fsrc := cmd.NewFsSrc(args[1:]) + cmd.Run(false, false, command, func() error { + return operations.HashLister(ht, fsrc, os.Stdout) + }) + return nil + }, +} diff --git a/fs/operations/operations.go b/fs/operations/operations.go index 6882e06c9..ae12748fa 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -840,7 +840,7 @@ func ListLong(f fs.Fs, w io.Writer) error { // // Lists in parallel which may get them out of order func Md5sum(f fs.Fs, w io.Writer) error { - return hashLister(hash.MD5, f, w) + return HashLister(hash.MD5, f, w) } // Sha1sum list the Fs to the supplied writer @@ -849,7 +849,7 @@ func Md5sum(f fs.Fs, w io.Writer) error { // // Lists in parallel which may get them out of order func Sha1sum(f fs.Fs, w io.Writer) error { - return hashLister(hash.SHA1, f, w) + return HashLister(hash.SHA1, f, w) } // DropboxHashSum list the Fs to the supplied writer @@ -858,7 +858,7 @@ func Sha1sum(f fs.Fs, w io.Writer) error { // // Lists in parallel which may get them out of order func DropboxHashSum(f fs.Fs, w io.Writer) error { - return hashLister(hash.Dropbox, f, w) + return HashLister(hash.Dropbox, f, w) } // hashSum returns the human readable hash for ht passed in. This may @@ -876,7 +876,8 @@ func hashSum(ht hash.Type, o fs.Object) string { return sum } -func hashLister(ht hash.Type, f fs.Fs, w io.Writer) error { +// HashLister does a md5sum equivalent for the hash type passed in +func HashLister(ht hash.Type, f fs.Fs, w io.Writer) error { return ListFn(f, func(o fs.Object) { sum := hashSum(ht, o) syncFprintf(w, "%*s %s\n", hash.Width[ht], sum, o.Remote())