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{
|
var cmdFind = &cobra.Command{
|
||||||
Use: "find [flags] PATTERN",
|
Use: "find [flags] PATTERN...",
|
||||||
Short: "Find a file, a directory or restic IDs",
|
Short: "Find a file, a directory or restic IDs",
|
||||||
Long: `
|
Long: `
|
||||||
The "find" command searches for files or directories in snapshots stored in the
|
The "find" command searches for files or directories in snapshots stored in the
|
||||||
repo.
|
repo.
|
||||||
It can also be used to search for restic blobs or trees for troubleshooting.`,
|
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,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runFind(findOptions, globalOptions, args)
|
return runFind(findOptions, globalOptions, args)
|
||||||
|
@ -67,7 +73,7 @@ func init() {
|
||||||
|
|
||||||
type findPattern struct {
|
type findPattern struct {
|
||||||
oldest, newest time.Time
|
oldest, newest time.Time
|
||||||
pattern string
|
pattern []string
|
||||||
ignoreCase bool
|
ignoreCase bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,20 +269,35 @@ func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error
|
||||||
normalizedNodepath = strings.ToLower(nodepath)
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
if found {
|
||||||
|
foundMatch = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ignoreIfNoMatch = true
|
ignoreIfNoMatch = true
|
||||||
errIfNoMatch error
|
errIfNoMatch error
|
||||||
)
|
)
|
||||||
if node.Type == "dir" {
|
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 {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
if mayMatch {
|
||||||
|
childMayMatch = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !childMayMatch {
|
if !childMayMatch {
|
||||||
ignoreIfNoMatch = true
|
ignoreIfNoMatch = true
|
||||||
|
@ -444,14 +465,16 @@ func (f *Finder) findBlobsPacks(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) == 0 {
|
||||||
return errors.Fatal("wrong number of arguments")
|
return errors.Fatal("wrong number of arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
pat := findPattern{pattern: args[0]}
|
pat := findPattern{pattern: args}
|
||||||
if opts.CaseInsensitive {
|
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
|
pat.ignoreCase = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,17 +527,19 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
if opts.BlobID {
|
if opts.BlobID {
|
||||||
f.blobIDs = make(map[string]struct{})
|
f.blobIDs = make(map[string]struct{})
|
||||||
// for _, i := range pat {} // TODO: support multiple args
|
for _, pat := range f.pat.pattern {
|
||||||
f.blobIDs[f.pat.pattern] = struct{}{}
|
f.blobIDs[pat] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if opts.TreeID {
|
if opts.TreeID {
|
||||||
f.treeIDs = make(map[string]struct{})
|
f.treeIDs = make(map[string]struct{})
|
||||||
// for _, i := range pat {} // TODO: support multiple args
|
for _, pat := range f.pat.pattern {
|
||||||
f.treeIDs[f.pat.pattern] = struct{}{}
|
f.treeIDs[pat] = struct{}{}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.PackID {
|
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) {
|
for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue