2
2
mirror of https://github.com/octoleo/restic.git synced 2024-06-18 16:52:22 +00:00

Merge pull request #4056 from greatroar/cleanup

backend, fs, options: Minor cleanup
This commit is contained in:
Michael Eischer 2022-12-02 19:44:54 +01:00 committed by GitHub
commit fa20a78bb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 58 additions and 76 deletions

View File

@ -43,14 +43,13 @@ func ParseConfig(s string) (interface{}, error) {
// use the first entry of the path as the bucket name and the // use the first entry of the path as the bucket name and the
// remainder as prefix // remainder as prefix
data := strings.SplitN(s, ":", 2) container, prefix, colon := strings.Cut(s, ":")
if len(data) < 2 { if !colon {
return nil, errors.New("azure: invalid format: bucket name or path not found") return nil, errors.New("azure: invalid format: bucket name or path not found")
} }
container, path := data[0], path.Clean(data[1]) prefix = strings.TrimPrefix(path.Clean(prefix), "/")
path = strings.TrimPrefix(path, "/")
cfg := NewConfig() cfg := NewConfig()
cfg.Container = container cfg.Container = container
cfg.Prefix = path cfg.Prefix = prefix
return cfg, nil return cfg, nil
} }

View File

@ -37,7 +37,7 @@ var bucketName = regexp.MustCompile("^[a-zA-Z0-9-]+$")
// https://help.backblaze.com/hc/en-us/articles/217666908-What-you-need-to-know-about-B2-Bucket-names // https://help.backblaze.com/hc/en-us/articles/217666908-What-you-need-to-know-about-B2-Bucket-names
func checkBucketName(name string) error { func checkBucketName(name string) error {
if name == "" { if name == "" {
return errors.New("bucket name is empty") return errors.New("bucket name not found")
} }
if len(name) < 6 { if len(name) < 6 {
@ -64,30 +64,18 @@ func ParseConfig(s string) (interface{}, error) {
} }
s = s[3:] s = s[3:]
data := strings.SplitN(s, ":", 2) bucket, prefix, _ := strings.Cut(s, ":")
if len(data) == 0 || len(data[0]) == 0 { if err := checkBucketName(bucket); err != nil {
return nil, errors.New("bucket name not found")
}
cfg := NewConfig()
cfg.Bucket = data[0]
if err := checkBucketName(cfg.Bucket); err != nil {
return nil, err return nil, err
} }
if len(data) == 2 { if len(prefix) > 0 {
p := data[1] prefix = strings.TrimPrefix(path.Clean(prefix), "/")
if len(p) > 0 {
p = path.Clean(p)
}
if len(p) > 0 && path.IsAbs(p) {
p = p[1:]
}
cfg.Prefix = p
} }
cfg := NewConfig()
cfg.Bucket = bucket
cfg.Prefix = prefix
return cfg, nil return cfg, nil
} }

View File

@ -42,17 +42,15 @@ func ParseConfig(s string) (interface{}, error) {
// use the first entry of the path as the bucket name and the // use the first entry of the path as the bucket name and the
// remainder as prefix // remainder as prefix
data := strings.SplitN(s, ":", 2) bucket, prefix, colon := strings.Cut(s, ":")
if len(data) < 2 { if !colon {
return nil, errors.New("gs: invalid format: bucket name or path not found") return nil, errors.New("gs: invalid format: bucket name or path not found")
} }
bucket, path := data[0], path.Clean(data[1]) prefix = strings.TrimPrefix(path.Clean(prefix), "/")
path = strings.TrimPrefix(path, "/")
cfg := NewConfig() cfg := NewConfig()
cfg.Bucket = bucket cfg.Bucket = bucket
cfg.Prefix = path cfg.Prefix = prefix
return cfg, nil return cfg, nil
} }

View File

@ -127,6 +127,6 @@ func StripPassword(s string) string {
} }
func extractScheme(s string) string { func extractScheme(s string) string {
data := strings.SplitN(s, ":", 2) scheme, _, _ := strings.Cut(s, ":")
return data[0] return scheme
} }

View File

@ -59,8 +59,8 @@ func ParseConfig(s string) (interface{}, error) {
return nil, errors.New("s3: bucket name not found") return nil, errors.New("s3: bucket name not found")
} }
path := strings.SplitN(url.Path[1:], "/", 2) bucket, path, _ := strings.Cut(url.Path[1:], "/")
return createConfig(url.Host, path, url.Scheme == "http") return createConfig(url.Host, bucket, path, url.Scheme == "http")
case strings.HasPrefix(s, "s3://"): case strings.HasPrefix(s, "s3://"):
s = s[5:] s = s[5:]
case strings.HasPrefix(s, "s3:"): case strings.HasPrefix(s, "s3:"):
@ -70,24 +70,24 @@ func ParseConfig(s string) (interface{}, error) {
} }
// use the first entry of the path as the endpoint and the // use the first entry of the path as the endpoint and the
// remainder as bucket name and prefix // remainder as bucket name and prefix
path := strings.SplitN(s, "/", 3) endpoint, rest, _ := strings.Cut(s, "/")
return createConfig(path[0], path[1:], false) bucket, prefix, _ := strings.Cut(rest, "/")
return createConfig(endpoint, bucket, prefix, false)
} }
func createConfig(endpoint string, p []string, useHTTP bool) (interface{}, error) { func createConfig(endpoint, bucket, prefix string, useHTTP bool) (interface{}, error) {
if len(p) < 1 { if endpoint == "" {
return nil, errors.New("s3: invalid format, host/region or bucket name not found") return nil, errors.New("s3: invalid format, host/region or bucket name not found")
} }
var prefix string if prefix != "" {
if len(p) > 1 && p[1] != "" { prefix = path.Clean(prefix)
prefix = path.Clean(p[1])
} }
cfg := NewConfig() cfg := NewConfig()
cfg.Endpoint = endpoint cfg.Endpoint = endpoint
cfg.UseHTTP = useHTTP cfg.UseHTTP = useHTTP
cfg.Bucket = p[0] cfg.Bucket = bucket
cfg.Prefix = prefix cfg.Prefix = prefix
return cfg, nil return cfg, nil
} }

View File

@ -1,6 +1,9 @@
package s3 package s3
import "testing" import (
"strings"
"testing"
)
var configTests = []struct { var configTests = []struct {
s string s string
@ -111,3 +114,14 @@ func TestParseConfig(t *testing.T) {
} }
} }
} }
func TestParseError(t *testing.T) {
const prefix = "s3: invalid format,"
for _, s := range []string{"", "/", "//", "/bucket/prefix"} {
_, err := ParseConfig("s3://" + s)
if err == nil || !strings.HasPrefix(err.Error(), prefix) {
t.Errorf("expected %q, got %q", prefix, err)
}
}
}

View File

@ -60,14 +60,13 @@ func ParseConfig(s string) (interface{}, error) {
// "user@host:path" in s // "user@host:path" in s
s = s[5:] s = s[5:]
// split user@host and path at the colon // split user@host and path at the colon
data := strings.SplitN(s, ":", 2) var colon bool
if len(data) < 2 { host, dir, colon = strings.Cut(s, ":")
if !colon {
return nil, errors.New("sftp: invalid format, hostname or path not found") return nil, errors.New("sftp: invalid format, hostname or path not found")
} }
host = data[0]
dir = data[1]
// split user and host at the "@" // split user and host at the "@"
data = strings.SplitN(host, "@", 3) data := strings.SplitN(host, "@", 3)
if len(data) == 3 { if len(data) == 3 {
user = data[0] + "@" + data[1] user = data[0] + "@" + data[1]
host = data[2] host = data[2]

View File

@ -51,17 +51,13 @@ func NewConfig() Config {
// ParseConfig parses the string s and extract swift's container name and prefix. // ParseConfig parses the string s and extract swift's container name and prefix.
func ParseConfig(s string) (interface{}, error) { func ParseConfig(s string) (interface{}, error) {
data := strings.SplitN(s, ":", 3) if !strings.HasPrefix(s, "swift:") {
if len(data) != 3 {
return nil, errors.New("invalid URL, expected: swift:container-name:/[prefix]") return nil, errors.New("invalid URL, expected: swift:container-name:/[prefix]")
} }
s = strings.TrimPrefix(s, "swift:")
scheme, container, prefix := data[0], data[1], data[2] container, prefix, _ := strings.Cut(s, ":")
if scheme != "swift" { if prefix == "" {
return nil, errors.Errorf("unexpected prefix: %s", data[0])
}
if len(prefix) == 0 {
return nil, errors.Errorf("prefix is empty") return nil, errors.Errorf("prefix is empty")
} }

View File

@ -4,7 +4,6 @@
package fs package fs
import ( import (
"fmt"
"os" "os"
"syscall" "syscall"
"time" "time"
@ -12,10 +11,7 @@ import (
// extendedStat extracts info into an ExtendedFileInfo for unix based operating systems. // extendedStat extracts info into an ExtendedFileInfo for unix based operating systems.
func extendedStat(fi os.FileInfo) ExtendedFileInfo { func extendedStat(fi os.FileInfo) ExtendedFileInfo {
s, ok := fi.Sys().(*syscall.Stat_t) s := fi.Sys().(*syscall.Stat_t)
if !ok {
panic(fmt.Sprintf("conversion to syscall.Stat_t failed, type is %T", fi.Sys()))
}
extFI := ExtendedFileInfo{ extFI := ExtendedFileInfo{
FileInfo: fi, FileInfo: fi,

View File

@ -4,7 +4,6 @@
package fs package fs
import ( import (
"fmt"
"os" "os"
"syscall" "syscall"
"time" "time"
@ -12,10 +11,7 @@ import (
// extendedStat extracts info into an ExtendedFileInfo for unix based operating systems. // extendedStat extracts info into an ExtendedFileInfo for unix based operating systems.
func extendedStat(fi os.FileInfo) ExtendedFileInfo { func extendedStat(fi os.FileInfo) ExtendedFileInfo {
s, ok := fi.Sys().(*syscall.Stat_t) s := fi.Sys().(*syscall.Stat_t)
if !ok {
panic(fmt.Sprintf("conversion to syscall.Stat_t failed, type is %T", fi.Sys()))
}
extFI := ExtendedFileInfo{ extFI := ExtendedFileInfo{
FileInfo: fi, FileInfo: fi,

View File

@ -92,14 +92,10 @@ func (h helpList) Swap(i, j int) {
// splitKeyValue splits at the first equals (=) sign. // splitKeyValue splits at the first equals (=) sign.
func splitKeyValue(s string) (key string, value string) { func splitKeyValue(s string) (key string, value string) {
data := strings.SplitN(s, "=", 2) key, value, _ = strings.Cut(s, "=")
key = strings.ToLower(strings.TrimSpace(data[0])) key = strings.ToLower(strings.TrimSpace(key))
if len(data) == 1 { value = strings.TrimSpace(value)
// no equals sign is treated as the empty value return key, value
return key, ""
}
return key, strings.TrimSpace(data[1])
} }
// Parse takes a slice of key=value pairs and returns an Options type. // Parse takes a slice of key=value pairs and returns an Options type.