Support multiple file/directory arguments for all commands
- Change sum add, sum update, check, and clear to accept 1+ paths - Update README usage examples to show multiple path support - Add TODO section with planned future improvements
This commit is contained in:
parent
9ad48fb9b0
commit
c856ea25be
27
README.md
27
README.md
@ -31,20 +31,20 @@ Semantic Versioning 2.0.0 is used for tags.
|
|||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# add checksum & timestamp xattrs to every regular file under DIR
|
# add checksum & timestamp xattrs to every regular file under one or more paths
|
||||||
attrsum sum add DIR
|
attrsum sum add DIR1 DIR2 file.txt
|
||||||
|
|
||||||
# update checksum only when file mtime is newer than stored sumtime
|
# 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
|
# verify checksums, stop on first error
|
||||||
attrsum check DIR
|
attrsum check DIR1 DIR2
|
||||||
|
|
||||||
# verify every file, reporting each result, keep going after errors
|
# 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
|
# remove checksum & timestamp xattrs
|
||||||
attrsum clear DIR
|
attrsum clear DIR1 DIR2
|
||||||
```
|
```
|
||||||
|
|
||||||
| xattr key | meaning |
|
| 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
|
## Contributing
|
||||||
|
|
||||||
* Author & maintainer: **sneak** – <sneak@sneak.berlin>
|
* Author & maintainer: **sneak** – <sneak@sneak.berlin>
|
||||||
|
|||||||
52
attrsum.go
52
attrsum.go
@ -62,17 +62,31 @@ func newSumCmd() *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add := &cobra.Command{
|
add := &cobra.Command{
|
||||||
Use: "add <dir>",
|
Use: "add <path>...",
|
||||||
Short: "Write checksums for files missing them",
|
Short: "Write checksums for files missing them",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
RunE: func(_ *cobra.Command, a []string) error { return ProcessSumAdd(a[0]) },
|
RunE: func(_ *cobra.Command, a []string) error {
|
||||||
|
for _, p := range a {
|
||||||
|
if err := ProcessSumAdd(p); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
upd := &cobra.Command{
|
upd := &cobra.Command{
|
||||||
Use: "update <dir>",
|
Use: "update <path>...",
|
||||||
Short: "Recalculate checksum when file newer than stored sumtime",
|
Short: "Recalculate checksum when file newer than stored sumtime",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
RunE: func(_ *cobra.Command, a []string) error { return ProcessSumUpdate(a[0]) },
|
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)
|
cmd.AddCommand(add, upd)
|
||||||
@ -129,10 +143,17 @@ func readSumTime(path string) (time.Time, error) {
|
|||||||
|
|
||||||
func newClearCmd() *cobra.Command {
|
func newClearCmd() *cobra.Command {
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "clear <dir>",
|
Use: "clear <path>...",
|
||||||
Short: "Remove checksum xattrs from tree",
|
Short: "Remove checksum xattrs from tree",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
RunE: func(_ *cobra.Command, a []string) error { return ProcessClear(a[0]) },
|
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 {
|
func newCheckCmd() *cobra.Command {
|
||||||
var cont bool
|
var cont bool
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "check <dir>",
|
Use: "check <path>...",
|
||||||
Short: "Verify stored checksums",
|
Short: "Verify stored checksums",
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
RunE: func(_ *cobra.Command, a []string) error { return ProcessCheck(a[0], cont) },
|
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")
|
cmd.Flags().BoolVar(&cont, "continue", false, "continue after errors and report each file")
|
||||||
return cmd
|
return cmd
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user