diff --git a/README.md b/README.md index a581a64..524a719 100644 --- a/README.md +++ b/README.md @@ -31,20 +31,20 @@ Semantic Versioning 2.0.0 is used for tags. ## Usage ```bash -# add checksum & timestamp xattrs to every regular file under DIR -attrsum sum add DIR +# add checksum & timestamp xattrs to every regular file under one or more paths +attrsum sum add DIR1 DIR2 file.txt # update checksum only when file mtime is newer than stored sumtime -attrsum sum update DIR +attrsum sum update DIR1 DIR2 # verify checksums, stop on first error -attrsum check DIR +attrsum check DIR1 DIR2 # verify every file, reporting each result, keep going after errors -attrsum -v check --continue DIR +attrsum -v check --continue DIR1 DIR2 # remove checksum & timestamp xattrs -attrsum clear DIR +attrsum clear DIR1 DIR2 ``` | xattr key | meaning | @@ -71,6 +71,21 @@ required. Now you can trust a USB stick didn't eat your data. --- +## TODO + +Future improvements under consideration: + +- **Quiet mode (`-q`)** — suppress all output except errors +- **Dry-run mode (`--dry-run`, `-n`)** — show what would be done without making changes +- **JSON output (`--json`)** — machine-readable output for scripting and integration +- **Parallel processing (`-j N`)** — use multiple goroutines for faster checksumming on large trees +- **Progress indicator** — show progress bar or spinner for long-running operations +- **Summary report** — print statistics on completion (files processed, errors, bytes hashed) +- **Read paths from stdin (`-`)** — support piping file lists, e.g. `find ... | attrsum sum add -` +- **Exit code documentation** — formalize and document exit codes for scripting + +--- + ## Contributing * Author & maintainer: **sneak** – diff --git a/attrsum.go b/attrsum.go index 2a5d7b1..51eab1e 100644 --- a/attrsum.go +++ b/attrsum.go @@ -62,17 +62,31 @@ func newSumCmd() *cobra.Command { } add := &cobra.Command{ - Use: "add ", + Use: "add ...", Short: "Write checksums for files missing them", - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, a []string) error { return ProcessSumAdd(a[0]) }, + Args: cobra.MinimumNArgs(1), + RunE: func(_ *cobra.Command, a []string) error { + for _, p := range a { + if err := ProcessSumAdd(p); err != nil { + return err + } + } + return nil + }, } upd := &cobra.Command{ - Use: "update ", + Use: "update ...", Short: "Recalculate checksum when file newer than stored sumtime", - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, a []string) error { return ProcessSumUpdate(a[0]) }, + Args: cobra.MinimumNArgs(1), + RunE: func(_ *cobra.Command, a []string) error { + for _, p := range a { + if err := ProcessSumUpdate(p); err != nil { + return err + } + } + return nil + }, } cmd.AddCommand(add, upd) @@ -129,10 +143,17 @@ func readSumTime(path string) (time.Time, error) { func newClearCmd() *cobra.Command { return &cobra.Command{ - Use: "clear ", + Use: "clear ...", Short: "Remove checksum xattrs from tree", - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, a []string) error { return ProcessClear(a[0]) }, + Args: cobra.MinimumNArgs(1), + RunE: func(_ *cobra.Command, a []string) error { + for _, p := range a { + if err := ProcessClear(p); err != nil { + return err + } + } + return nil + }, } } @@ -164,10 +185,17 @@ func ProcessClear(dir string) error { func newCheckCmd() *cobra.Command { var cont bool cmd := &cobra.Command{ - Use: "check ", + Use: "check ...", Short: "Verify stored checksums", - Args: cobra.ExactArgs(1), - RunE: func(_ *cobra.Command, a []string) error { return ProcessCheck(a[0], cont) }, + Args: cobra.MinimumNArgs(1), + RunE: func(_ *cobra.Command, a []string) error { + for _, p := range a { + if err := ProcessCheck(p, cont); err != nil { + return err + } + } + return nil + }, } cmd.Flags().BoolVar(&cont, "continue", false, "continue after errors and report each file") return cmd