mirror of
https://github.com/octoleo/restic.git
synced 2024-11-29 16:23:59 +00:00
Merge pull request #3974 from greatroar/cleanup
More cleanups and a micro-optimization
This commit is contained in:
commit
c8c8391b21
@ -217,7 +217,7 @@ func TestTestWalkFiles(t *testing.T) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
got[p] = fmt.Sprintf("%v", item)
|
got[p] = fmt.Sprint(item)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
5
internal/cache/file.go
vendored
5
internal/cache/file.go
vendored
@ -59,13 +59,14 @@ func (c *Cache) load(h restic.Handle, length int, offset int64) (io.ReadCloser,
|
|||||||
return nil, errors.WithStack(err)
|
return nil, errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Size() <= int64(crypto.CiphertextLength(0)) {
|
size := fi.Size()
|
||||||
|
if size <= int64(crypto.CiphertextLength(0)) {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.remove(h)
|
_ = c.remove(h)
|
||||||
return nil, errors.Errorf("cached file %v is truncated, removing", h)
|
return nil, errors.Errorf("cached file %v is truncated, removing", h)
|
||||||
}
|
}
|
||||||
|
|
||||||
if fi.Size() < offset+int64(length) {
|
if size < offset+int64(length) {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
_ = c.remove(h)
|
_ = c.remove(h)
|
||||||
return nil, errors.Errorf("cached file %v is too small, removing", h)
|
return nil, errors.Errorf("cached file %v is too small, removing", h)
|
||||||
|
2
internal/cache/file_test.go
vendored
2
internal/cache/file_test.go
vendored
@ -97,7 +97,7 @@ func TestFiles(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, tpe := range tests {
|
for _, tpe := range tests {
|
||||||
t.Run(fmt.Sprintf("%v", tpe), func(t *testing.T) {
|
t.Run(tpe.String(), func(t *testing.T) {
|
||||||
ids := generateRandomFiles(t, tpe, c)
|
ids := generateRandomFiles(t, tpe, c)
|
||||||
id := randomID(ids)
|
id := randomID(ids)
|
||||||
|
|
||||||
|
@ -114,11 +114,7 @@ func (h BlobHandles) Less(i, j int) bool {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if b < h[j].ID[k] {
|
return b < h[j].ID[k]
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return h[i].Type < h[j].Type
|
return h[i].Type < h[j].Type
|
||||||
@ -133,5 +129,5 @@ func (h BlobHandles) String() string {
|
|||||||
for _, e := range h {
|
for _, e := range h {
|
||||||
elements = append(elements, e.String())
|
elements = append(elements, e.String())
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%v", elements)
|
return fmt.Sprint(elements)
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,38 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// FileType is the type of a file in the backend.
|
// FileType is the type of a file in the backend.
|
||||||
type FileType string
|
type FileType uint8
|
||||||
|
|
||||||
// These are the different data types a backend can store.
|
// These are the different data types a backend can store.
|
||||||
const (
|
const (
|
||||||
PackFile FileType = "data" // use data, as packs are stored under /data in repo
|
PackFile FileType = 1 + iota
|
||||||
KeyFile FileType = "key"
|
KeyFile
|
||||||
LockFile FileType = "lock"
|
LockFile
|
||||||
SnapshotFile FileType = "snapshot"
|
SnapshotFile
|
||||||
IndexFile FileType = "index"
|
IndexFile
|
||||||
ConfigFile FileType = "config"
|
ConfigFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (t FileType) String() string {
|
||||||
|
s := "invalid"
|
||||||
|
switch t {
|
||||||
|
case PackFile:
|
||||||
|
// Spelled "data" instead of "pack" for historical reasons.
|
||||||
|
s = "data"
|
||||||
|
case KeyFile:
|
||||||
|
s = "key"
|
||||||
|
case LockFile:
|
||||||
|
s = "lock"
|
||||||
|
case SnapshotFile:
|
||||||
|
s = "snapshot"
|
||||||
|
case IndexFile:
|
||||||
|
s = "index"
|
||||||
|
case ConfigFile:
|
||||||
|
s = "config"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// Handle is used to store and access data in a backend.
|
// Handle is used to store and access data in a backend.
|
||||||
type Handle struct {
|
type Handle struct {
|
||||||
Type FileType
|
Type FileType
|
||||||
@ -36,10 +56,6 @@ func (h Handle) String() string {
|
|||||||
|
|
||||||
// Valid returns an error if h is not valid.
|
// Valid returns an error if h is not valid.
|
||||||
func (h Handle) Valid() error {
|
func (h Handle) Valid() error {
|
||||||
if h.Type == "" {
|
|
||||||
return errors.New("type is empty")
|
|
||||||
}
|
|
||||||
|
|
||||||
switch h.Type {
|
switch h.Type {
|
||||||
case PackFile:
|
case PackFile:
|
||||||
case KeyFile:
|
case KeyFile:
|
||||||
@ -48,7 +64,7 @@ func (h Handle) Valid() error {
|
|||||||
case IndexFile:
|
case IndexFile:
|
||||||
case ConfigFile:
|
case ConfigFile:
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid Type %q", h.Type)
|
return errors.Errorf("invalid Type %d", h.Type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if h.Type == ConfigFile {
|
if h.Type == ConfigFile {
|
||||||
|
@ -1,20 +1,28 @@
|
|||||||
package restic
|
package restic
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
rtest "github.com/restic/restic/internal/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHandleString(t *testing.T) {
|
||||||
|
rtest.Equals(t, "<data/foobar>", Handle{Type: PackFile, Name: "foobar"}.String())
|
||||||
|
rtest.Equals(t, "<lock/1>", Handle{Type: LockFile, Name: "1"}.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHandleValid(t *testing.T) {
|
||||||
var handleTests = []struct {
|
var handleTests = []struct {
|
||||||
h Handle
|
h Handle
|
||||||
valid bool
|
valid bool
|
||||||
}{
|
}{
|
||||||
{Handle{Name: "foo"}, false},
|
{Handle{Name: "foo"}, false},
|
||||||
{Handle{Type: "foobar"}, false},
|
{Handle{Type: 0}, false},
|
||||||
{Handle{Type: ConfigFile, Name: ""}, true},
|
{Handle{Type: ConfigFile, Name: ""}, true},
|
||||||
{Handle{Type: PackFile, Name: ""}, false},
|
{Handle{Type: PackFile, Name: ""}, false},
|
||||||
{Handle{Type: "", Name: "x"}, false},
|
|
||||||
{Handle{Type: LockFile, Name: "010203040506"}, true},
|
{Handle{Type: LockFile, Name: "010203040506"}, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHandleValid(t *testing.T) {
|
|
||||||
for i, test := range handleTests {
|
for i, test := range handleTests {
|
||||||
err := test.h.Valid()
|
err := test.h.Valid()
|
||||||
if err != nil && test.valid {
|
if err != nil && test.valid {
|
||||||
|
@ -6,8 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/errors"
|
|
||||||
|
|
||||||
"github.com/minio/sha256-simd"
|
"github.com/minio/sha256-simd"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -24,14 +22,13 @@ type ID [idSize]byte
|
|||||||
|
|
||||||
// ParseID converts the given string to an ID.
|
// ParseID converts the given string to an ID.
|
||||||
func ParseID(s string) (ID, error) {
|
func ParseID(s string) (ID, error) {
|
||||||
b, err := hex.DecodeString(s)
|
if len(s) != hex.EncodedLen(idSize) {
|
||||||
|
return ID{}, fmt.Errorf("invalid length for ID: %q", s)
|
||||||
if err != nil {
|
|
||||||
return ID{}, errors.Wrap(err, "hex.DecodeString")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b) != idSize {
|
b, err := hex.DecodeString(s)
|
||||||
return ID{}, errors.New("invalid length for hash")
|
if err != nil {
|
||||||
|
return ID{}, fmt.Errorf("invalid ID: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
id := ID{}
|
id := ID{}
|
||||||
@ -96,34 +93,21 @@ func (id ID) MarshalJSON() ([]byte, error) {
|
|||||||
// UnmarshalJSON parses the JSON-encoded data and stores the result in id.
|
// UnmarshalJSON parses the JSON-encoded data and stores the result in id.
|
||||||
func (id *ID) UnmarshalJSON(b []byte) error {
|
func (id *ID) UnmarshalJSON(b []byte) error {
|
||||||
// check string length
|
// check string length
|
||||||
if len(b) < 2 {
|
if len(b) != len(`""`)+hex.EncodedLen(idSize) {
|
||||||
return fmt.Errorf("invalid ID: %q", b)
|
return fmt.Errorf("invalid length for ID: %q", b)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(b)%2 != 0 {
|
if b[0] != '"' {
|
||||||
return fmt.Errorf("invalid ID length: %q", b)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check string delimiters
|
|
||||||
if b[0] != '"' && b[0] != '\'' {
|
|
||||||
return fmt.Errorf("invalid start of string: %q", b[0])
|
return fmt.Errorf("invalid start of string: %q", b[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
last := len(b) - 1
|
// Strip JSON string delimiters. The json.Unmarshaler contract says we get
|
||||||
if b[0] != b[last] {
|
// a valid JSON value, so we don't need to check that b[len(b)-1] == '"'.
|
||||||
return fmt.Errorf("starting string delimiter (%q) does not match end (%q)", b[0], b[last])
|
b = b[1 : len(b)-1]
|
||||||
}
|
|
||||||
|
|
||||||
// strip JSON string delimiters
|
|
||||||
b = b[1:last]
|
|
||||||
|
|
||||||
if len(b) != 2*len(id) {
|
|
||||||
return fmt.Errorf("invalid length for ID")
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := hex.Decode(id[:], b)
|
_, err := hex.Decode(id[:], b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "hex.Decode")
|
return fmt.Errorf("invalid ID: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -65,5 +65,5 @@ func (ids IDs) String() string {
|
|||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
elements = append(elements, shortID(id))
|
elements = append(elements, shortID(id))
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%v", elements)
|
return fmt.Sprint(elements)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ func (TagList) Type() string {
|
|||||||
type TagLists []TagList
|
type TagLists []TagList
|
||||||
|
|
||||||
func (l TagLists) String() string {
|
func (l TagLists) String() string {
|
||||||
return fmt.Sprintf("%v", []TagList(l))
|
return fmt.Sprint([]TagList(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flatten returns the list of all tags provided in TagLists
|
// Flatten returns the list of all tags provided in TagLists
|
||||||
|
Loading…
Reference in New Issue
Block a user