find: Add support for multiple patterns or objects
This commit is contained in:
parent
bb5425a1d8
commit
8af918a1e4
1 changed files with 41 additions and 16 deletions
|
@ -16,12 +16,18 @@ import (
|
|||
)
|
||||
|
||||
var cmdFind = &cobra.Command{
|
||||
Use: "find [flags] PATTERN",
|
||||
Use: "find [flags] PATTERN...",
|
||||
Short: "Find a file, a directory or restic IDs",
|
||||
Long: `
|
||||
The "find" command searches for files or directories in snapshots stored in the
|
||||
repo.
|
||||
It can also be used to search for restic blobs or trees for troubleshooting.`,
|
||||
Example: `restic find config.json
|
||||
restic find --json "*.yml" "*.json"
|
||||
restic find --json --blob 420f620f b46ebe8a ddd38656
|
||||
restic find --show-pack-id --blob 420f620f
|
||||
restic find --tree 577c2bc9 f81f2e22 a62827a9
|
||||
restic find --pack 025c1d06`,
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runFind(findOptions, globalOptions, args)
|
||||
|
@ -67,7 +73,7 @@ func init() {
|
|||
|
||||
type findPattern struct {
|
||||
oldest, newest time.Time
|
||||
pattern string
|
||||
pattern []string
|
||||
ignoreCase bool
|
||||
}
|
||||
|
||||
|
@ -263,20 +269,35 @@ func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error
|
|||
normalizedNodepath = strings.ToLower(nodepath)
|
||||
}
|
||||
|
||||
foundMatch, err := filter.Match(f.pat.pattern, normalizedNodepath)
|
||||
var foundMatch bool
|
||||
|
||||
for _, pat := range f.pat.pattern {
|
||||
found, err := filter.Match(pat, normalizedNodepath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if found {
|
||||
foundMatch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
ignoreIfNoMatch = true
|
||||
errIfNoMatch error
|
||||
)
|
||||
if node.Type == "dir" {
|
||||
childMayMatch, err := filter.ChildMatch(f.pat.pattern, normalizedNodepath)
|
||||
var childMayMatch bool
|
||||
for _, pat := range f.pat.pattern {
|
||||
mayMatch, err := filter.ChildMatch(pat, normalizedNodepath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if mayMatch {
|
||||
childMayMatch = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !childMayMatch {
|
||||
ignoreIfNoMatch = true
|
||||
|
@ -444,14 +465,16 @@ func (f *Finder) findBlobsPacks(ctx context.Context) {
|
|||
}
|
||||
|
||||
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||
if len(args) != 1 {
|
||||
if len(args) == 0 {
|
||||
return errors.Fatal("wrong number of arguments")
|
||||
}
|
||||
|
||||
var err error
|
||||
pat := findPattern{pattern: args[0]}
|
||||
pat := findPattern{pattern: args}
|
||||
if opts.CaseInsensitive {
|
||||
pat.pattern = strings.ToLower(pat.pattern)
|
||||
for i := range pat.pattern {
|
||||
pat.pattern[i] = strings.ToLower(pat.pattern[i])
|
||||
}
|
||||
pat.ignoreCase = true
|
||||
}
|
||||
|
||||
|
@ -504,17 +527,19 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
|||
|
||||
if opts.BlobID {
|
||||
f.blobIDs = make(map[string]struct{})
|
||||
// for _, i := range pat {} // TODO: support multiple args
|
||||
f.blobIDs[f.pat.pattern] = struct{}{}
|
||||
for _, pat := range f.pat.pattern {
|
||||
f.blobIDs[pat] = struct{}{}
|
||||
}
|
||||
}
|
||||
if opts.TreeID {
|
||||
f.treeIDs = make(map[string]struct{})
|
||||
// for _, i := range pat {} // TODO: support multiple args
|
||||
f.treeIDs[f.pat.pattern] = struct{}{}
|
||||
for _, pat := range f.pat.pattern {
|
||||
f.treeIDs[pat] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
if opts.PackID {
|
||||
f.packsToBlobs(ctx, []string{f.pat.pattern}) // TODO: support multiple packs
|
||||
f.packsToBlobs(ctx, []string{f.pat.pattern[0]}) // TODO: support multiple packs
|
||||
}
|
||||
|
||||
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) {
|
||||
|
|
Loading…
Reference in a new issue