2
2
mirror of https://github.com/octoleo/restic.git synced 2024-12-22 10:58:55 +00:00

Ensure consistent naming for <snapshot>:<subfolder> syntax

This commit is contained in:
Michael Eischer 2023-07-16 16:50:54 +02:00
parent 184b7616ba
commit 8154f6a77a
9 changed files with 43 additions and 43 deletions

View File

@ -13,7 +13,7 @@ import (
) )
var cmdCat = &cobra.Command{ var cmdCat = &cobra.Command{
Use: "cat [flags] [masterkey|config|pack ID|blob ID|snapshot ID|index ID|key ID|lock ID|tree snapshot:path]", Use: "cat [flags] [masterkey|config|pack ID|blob ID|snapshot ID|index ID|key ID|lock ID|tree snapshot:subfolder]",
Short: "Print internal objects to stdout", Short: "Print internal objects to stdout",
Long: ` Long: `
The "cat" command is used to print internal objects to stdout. The "cat" command is used to print internal objects to stdout.
@ -166,7 +166,7 @@ func runCat(ctx context.Context, gopts GlobalOptions, args []string) error {
return errors.Fatal("blob not found") return errors.Fatal("blob not found")
case "tree": case "tree":
sn, subpath, err := restic.FindSnapshot(ctx, repo.Backend(), repo, args[1]) sn, subfolder, err := restic.FindSnapshot(ctx, repo.Backend(), repo, args[1])
if err != nil { if err != nil {
return errors.Fatalf("could not find snapshot: %v\n", err) return errors.Fatalf("could not find snapshot: %v\n", err)
} }
@ -176,7 +176,7 @@ func runCat(ctx context.Context, gopts GlobalOptions, args []string) error {
return err return err
} }
sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subpath) sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subfolder)
if err != nil { if err != nil {
return err return err
} }

View File

@ -55,11 +55,11 @@ func init() {
} }
func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.Repository, desc string) (*restic.Snapshot, string, error) { func loadSnapshot(ctx context.Context, be restic.Lister, repo restic.Repository, desc string) (*restic.Snapshot, string, error) {
sn, subpath, err := restic.FindSnapshot(ctx, be, repo, desc) sn, subfolder, err := restic.FindSnapshot(ctx, be, repo, desc)
if err != nil { if err != nil {
return nil, "", errors.Fatal(err.Error()) return nil, "", errors.Fatal(err.Error())
} }
return sn, subpath, err return sn, subfolder, err
} }
// Comparer collects all things needed to compare two snapshots. // Comparer collects all things needed to compare two snapshots.
@ -346,12 +346,12 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
if err != nil { if err != nil {
return err return err
} }
sn1, subpath1, err := loadSnapshot(ctx, be, repo, args[0]) sn1, subfolder1, err := loadSnapshot(ctx, be, repo, args[0])
if err != nil { if err != nil {
return err return err
} }
sn2, subpath2, err := loadSnapshot(ctx, be, repo, args[1]) sn2, subfolder2, err := loadSnapshot(ctx, be, repo, args[1])
if err != nil { if err != nil {
return err return err
} }
@ -372,12 +372,12 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
return errors.Errorf("snapshot %v has nil tree", sn2.ID().Str()) return errors.Errorf("snapshot %v has nil tree", sn2.ID().Str())
} }
sn1.Tree, err = restic.FindTreeDirectory(ctx, repo, sn1.Tree, subpath1) sn1.Tree, err = restic.FindTreeDirectory(ctx, repo, sn1.Tree, subfolder1)
if err != nil { if err != nil {
return err return err
} }
sn2.Tree, err = restic.FindTreeDirectory(ctx, repo, sn2.Tree, subpath2) sn2.Tree, err = restic.FindTreeDirectory(ctx, repo, sn2.Tree, subfolder2)
if err != nil { if err != nil {
return err return err
} }

View File

@ -139,7 +139,7 @@ func runDump(ctx context.Context, opts DumpOptions, gopts GlobalOptions, args []
} }
} }
sn, subpath, err := (&restic.SnapshotFilter{ sn, subfolder, err := (&restic.SnapshotFilter{
Hosts: opts.Hosts, Hosts: opts.Hosts,
Paths: opts.Paths, Paths: opts.Paths,
Tags: opts.Tags, Tags: opts.Tags,
@ -153,7 +153,7 @@ func runDump(ctx context.Context, opts DumpOptions, gopts GlobalOptions, args []
return err return err
} }
sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subpath) sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subfolder)
if err != nil { if err != nil {
return err return err
} }

View File

@ -212,7 +212,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
} }
} }
sn, subpath, err := (&restic.SnapshotFilter{ sn, subfolder, err := (&restic.SnapshotFilter{
Hosts: opts.Hosts, Hosts: opts.Hosts,
Paths: opts.Paths, Paths: opts.Paths,
Tags: opts.Tags, Tags: opts.Tags,
@ -221,7 +221,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
return err return err
} }
sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subpath) sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subfolder)
if err != nil { if err != nil {
return err return err
} }

View File

@ -161,7 +161,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
} }
} }
sn, subpath, err := (&restic.SnapshotFilter{ sn, subfolder, err := (&restic.SnapshotFilter{
Hosts: opts.Hosts, Hosts: opts.Hosts,
Paths: opts.Paths, Paths: opts.Paths,
Tags: opts.Tags, Tags: opts.Tags,
@ -175,7 +175,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
return err return err
} }
sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subpath) sn.Tree, err = restic.FindTreeDirectory(ctx, repo, sn.Tree, subfolder)
if err != nil { if err != nil {
return err return err
} }

View File

@ -83,15 +83,15 @@ func (f *SnapshotFilter) findLatest(ctx context.Context, be Lister, loader Loade
return latest, nil return latest, nil
} }
func splitSnapshotID(s string) (id, subpath string) { func splitSnapshotID(s string) (id, subfolder string) {
id, subpath, _ = strings.Cut(s, ":") id, subfolder, _ = strings.Cut(s, ":")
return return
} }
// FindSnapshot takes a string and tries to find a snapshot whose ID matches // FindSnapshot takes a string and tries to find a snapshot whose ID matches
// the string as closely as possible. // the string as closely as possible.
func FindSnapshot(ctx context.Context, be Lister, loader LoaderUnpacked, s string) (*Snapshot, string, error) { func FindSnapshot(ctx context.Context, be Lister, loader LoaderUnpacked, s string) (*Snapshot, string, error) {
s, subpath := splitSnapshotID(s) s, subfolder := splitSnapshotID(s)
// no need to list snapshots if `s` is already a full id // no need to list snapshots if `s` is already a full id
id, err := ParseID(s) id, err := ParseID(s)
@ -103,27 +103,27 @@ func FindSnapshot(ctx context.Context, be Lister, loader LoaderUnpacked, s strin
} }
} }
sn, err := LoadSnapshot(ctx, loader, id) sn, err := LoadSnapshot(ctx, loader, id)
return sn, subpath, err return sn, subfolder, err
} }
// FindLatest returns either the latest of a filtered list of all snapshots // FindLatest returns either the latest of a filtered list of all snapshots
// or a snapshot specified by `snapshotID`. // or a snapshot specified by `snapshotID`.
func (f *SnapshotFilter) FindLatest(ctx context.Context, be Lister, loader LoaderUnpacked, snapshotID string) (*Snapshot, string, error) { func (f *SnapshotFilter) FindLatest(ctx context.Context, be Lister, loader LoaderUnpacked, snapshotID string) (*Snapshot, string, error) {
id, subpath := splitSnapshotID(snapshotID) id, subfolder := splitSnapshotID(snapshotID)
if id == "latest" { if id == "latest" {
sn, err := f.findLatest(ctx, be, loader) sn, err := f.findLatest(ctx, be, loader)
if err == ErrNoSnapshotFound { if err == ErrNoSnapshotFound {
err = fmt.Errorf("snapshot filter (Paths:%v Tags:%v Hosts:%v): %w", err = fmt.Errorf("snapshot filter (Paths:%v Tags:%v Hosts:%v): %w",
f.Paths, f.Tags, f.Hosts, err) f.Paths, f.Tags, f.Hosts, err)
} }
return sn, subpath, err return sn, subfolder, err
} }
return FindSnapshot(ctx, be, loader, snapshotID) return FindSnapshot(ctx, be, loader, snapshotID)
} }
type SnapshotFindCb func(string, *Snapshot, error) error type SnapshotFindCb func(string, *Snapshot, error) error
var ErrInvalidSnapshotSyntax = errors.New("snapshot:path syntax not allowed") var ErrInvalidSnapshotSyntax = errors.New("<snapshot>:<subfolder> syntax not allowed")
// FindAll yields Snapshots, either given explicitly by `snapshotIDs` or filtered from the list of all snapshots. // FindAll yields Snapshots, either given explicitly by `snapshotIDs` or filtered from the list of all snapshots.
func (f *SnapshotFilter) FindAll(ctx context.Context, be Lister, loader LoaderUnpacked, snapshotIDs []string, fn SnapshotFindCb) error { func (f *SnapshotFilter) FindAll(ctx context.Context, be Lister, loader LoaderUnpacked, snapshotIDs []string, fn SnapshotFindCb) error {
@ -153,9 +153,9 @@ func (f *SnapshotFilter) FindAll(ctx context.Context, be Lister, loader LoaderUn
} else if strings.HasPrefix(s, "latest:") { } else if strings.HasPrefix(s, "latest:") {
err = ErrInvalidSnapshotSyntax err = ErrInvalidSnapshotSyntax
} else { } else {
var subpath string var subfolder string
sn, subpath, err = FindSnapshot(ctx, be, loader, s) sn, subfolder, err = FindSnapshot(ctx, be, loader, s)
if err == nil && subpath != "" { if err == nil && subfolder != "" {
err = ErrInvalidSnapshotSyntax err = ErrInvalidSnapshotSyntax
} else if err == nil { } else if err == nil {
if ids.Has(*sn.ID()) { if ids.Has(*sn.ID()) {

View File

@ -51,24 +51,24 @@ func TestFindLatestWithSubpath(t *testing.T) {
desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1) desiredSnapshot := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:07"), 1)
for _, exp := range []struct { for _, exp := range []struct {
query string query string
subpath string subfolder string
}{ }{
{"latest", ""}, {"latest", ""},
{"latest:subpath", "subpath"}, {"latest:subfolder", "subfolder"},
{desiredSnapshot.ID().Str(), ""}, {desiredSnapshot.ID().Str(), ""},
{desiredSnapshot.ID().Str() + ":subpath", "subpath"}, {desiredSnapshot.ID().Str() + ":subfolder", "subfolder"},
{desiredSnapshot.ID().String(), ""}, {desiredSnapshot.ID().String(), ""},
{desiredSnapshot.ID().String() + ":subpath", "subpath"}, {desiredSnapshot.ID().String() + ":subfolder", "subfolder"},
} { } {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
sn, subpath, err := (&restic.SnapshotFilter{}).FindLatest(context.TODO(), repo.Backend(), repo, exp.query) sn, subfolder, err := (&restic.SnapshotFilter{}).FindLatest(context.TODO(), repo.Backend(), repo, exp.query)
if err != nil { if err != nil {
t.Fatalf("FindLatest returned error: %v", err) t.Fatalf("FindLatest returned error: %v", err)
} }
test.Assert(t, *sn.ID() == *desiredSnapshot.ID(), "FindLatest returned wrong snapshot ID: %v", *sn.ID()) test.Assert(t, *sn.ID() == *desiredSnapshot.ID(), "FindLatest returned wrong snapshot ID: %v", *sn.ID())
test.Assert(t, subpath == exp.subpath, "FindLatest returned wrong path in snapshot: %v", subpath) test.Assert(t, subfolder == exp.subfolder, "FindLatest returned wrong path in snapshot: %v", subfolder)
}) })
} }
} }
@ -79,7 +79,7 @@ func TestFindAllSubpathError(t *testing.T) {
count := 0 count := 0
test.OK(t, (&restic.SnapshotFilter{}).FindAll(context.TODO(), repo.Backend(), repo, test.OK(t, (&restic.SnapshotFilter{}).FindAll(context.TODO(), repo.Backend(), repo,
[]string{"latest:subpath", desiredSnapshot.ID().Str() + ":subpath"}, []string{"latest:subfolder", desiredSnapshot.ID().Str() + ":subfolder"},
func(id string, sn *restic.Snapshot, err error) error { func(id string, sn *restic.Snapshot, err error) error {
if err == restic.ErrInvalidSnapshotSyntax { if err == restic.ErrInvalidSnapshotSyntax {
count++ count++
@ -87,5 +87,5 @@ func TestFindAllSubpathError(t *testing.T) {
} }
return err return err
})) }))
test.Assert(t, count == 2, "unexpected number of subpath errors: %v, wanted %v", count, 2) test.Assert(t, count == 2, "unexpected number of subfolder errors: %v, wanted %v", count, 2)
} }

View File

@ -193,23 +193,23 @@ func FindTreeDirectory(ctx context.Context, repo BlobLoader, id *ID, dir string)
} }
dirs := strings.Split(path.Clean(dir), "/") dirs := strings.Split(path.Clean(dir), "/")
subpath := "" subfolder := ""
for _, name := range dirs { for _, name := range dirs {
if name == "" || name == "." { if name == "" || name == "." {
continue continue
} }
subpath = path.Join(subpath, name) subfolder = path.Join(subfolder, name)
tree, err := LoadTree(ctx, repo, *id) tree, err := LoadTree(ctx, repo, *id)
if err != nil { if err != nil {
return nil, fmt.Errorf("path %s: %w", subpath, err) return nil, fmt.Errorf("path %s: %w", subfolder, err)
} }
node := tree.Find(name) node := tree.Find(name)
if node == nil { if node == nil {
return nil, fmt.Errorf("path %s: not found", subpath) return nil, fmt.Errorf("path %s: not found", subfolder)
} }
if node.Type != "dir" || node.Subtree == nil { if node.Type != "dir" || node.Subtree == nil {
return nil, fmt.Errorf("path %s: not a directory", subpath) return nil, fmt.Errorf("path %s: not a directory", subfolder)
} }
id = node.Subtree id = node.Subtree
} }

View File

@ -216,9 +216,9 @@ func TestFindTreeDirectory(t *testing.T) {
sn := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:08"), 3) sn := restic.TestCreateSnapshot(t, repo, parseTimeUTC("2017-07-07 07:07:08"), 3)
for _, exp := range []struct { for _, exp := range []struct {
subpath string subfolder string
id restic.ID id restic.ID
err error err error
}{ }{
{"", restic.TestParseID("c25199703a67455b34cc0c6e49a8ac8861b268a5dd09dc5b2e31e7380973fc97"), nil}, {"", restic.TestParseID("c25199703a67455b34cc0c6e49a8ac8861b268a5dd09dc5b2e31e7380973fc97"), nil},
{"/", restic.TestParseID("c25199703a67455b34cc0c6e49a8ac8861b268a5dd09dc5b2e31e7380973fc97"), nil}, {"/", restic.TestParseID("c25199703a67455b34cc0c6e49a8ac8861b268a5dd09dc5b2e31e7380973fc97"), nil},
@ -231,7 +231,7 @@ func TestFindTreeDirectory(t *testing.T) {
{"dir-21/dir-24", restic.TestParseID("74626b3fb2bd4b3e572b81a4059b3e912bcf2a8f69fecd9c187613b7173f13b1"), nil}, {"dir-21/dir-24", restic.TestParseID("74626b3fb2bd4b3e572b81a4059b3e912bcf2a8f69fecd9c187613b7173f13b1"), nil},
} { } {
t.Run("", func(t *testing.T) { t.Run("", func(t *testing.T) {
id, err := restic.FindTreeDirectory(context.TODO(), repo, sn.Tree, exp.subpath) id, err := restic.FindTreeDirectory(context.TODO(), repo, sn.Tree, exp.subfolder)
if exp.err == nil { if exp.err == nil {
rtest.OK(t, err) rtest.OK(t, err)
rtest.Assert(t, exp.id == *id, "unexpected id, expected %v, got %v", exp.id, id) rtest.Assert(t, exp.id == *id, "unexpected id, expected %v, got %v", exp.id, id)