diff --git a/fs/fspath/path.go b/fs/fspath/path.go index c32377f53..846a8bb81 100644 --- a/fs/fspath/path.go +++ b/fs/fspath/path.go @@ -36,9 +36,6 @@ var ( // remoteNameMatcher is a pattern to match an rclone remote name at the start of a config remoteNameMatcher = regexp.MustCompile(`^` + remoteNameRe + `(:$|,)`) - - // Function to check if string is a drive letter to be overriden in the tests - isDriveLetter = driveletter.IsDriveLetter ) // CheckConfigName returns an error if configName is invalid @@ -97,7 +94,7 @@ type Parsed struct { // An error may be returned if the remote name has invalid characters or the // parameters are invalid or the path is empty. func Parse(path string) (parsed Parsed, err error) { - parsed.Path = path + parsed.Path = filepath.ToSlash(path) if path == "" { return parsed, errCantBeEmpty } @@ -149,7 +146,7 @@ loop: prev = i + 1 if c == ':' { // If we parsed a drive letter, must be a local path - if isDriveLetter(parsed.Name) { + if driveletter.IsDriveLetter(parsed.Name) { parsed.Name = "" return parsed, nil } diff --git a/fs/fspath/path_test.go b/fs/fspath/path_test.go index 4319913b3..61c2ff66a 100644 --- a/fs/fspath/path_test.go +++ b/fs/fspath/path_test.go @@ -7,11 +7,9 @@ import ( "os" "path/filepath" "runtime" - "strings" "testing" "github.com/rclone/rclone/fs/config/configmap" - "github.com/rclone/rclone/fs/driveletter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -66,17 +64,12 @@ func TestCheckRemoteName(t *testing.T) { } func TestParse(t *testing.T) { - isDriveLetter = func(name string) bool { - return name == "C" - } - defer func() { - isDriveLetter = driveletter.IsDriveLetter - }() - for testNumber, test := range []struct { in string wantParsed Parsed wantErr error + win bool // only run these tests on Windows + noWin bool // only run these tests on !Windows }{ { in: "", @@ -96,24 +89,40 @@ func TestParse(t *testing.T) { ConfigString: "", Path: "/:", }, + }, { + in: "\\backslash:", + wantParsed: Parsed{ + ConfigString: "", + Path: "/backslash:", + }, + win: true, }, { in: "\\backslash:", wantParsed: Parsed{ ConfigString: "", Path: "\\backslash:", }, + noWin: true, }, { in: "/slash:", wantParsed: Parsed{ ConfigString: "", Path: "/slash:", }, + }, { + in: "with\\backslash:", + wantParsed: Parsed{ + ConfigString: "", + Path: "with/backslash:", + }, + win: true, }, { in: "with\\backslash:", wantParsed: Parsed{ ConfigString: "", Path: "with\\backslash:", }, + noWin: true, }, { in: "with/slash:", wantParsed: Parsed{ @@ -184,8 +193,39 @@ func TestParse(t *testing.T) { in: `C:\path\to\file`, wantParsed: Parsed{ Name: "", - Path: `C:\path\to\file`, + Path: `C:/path/to/file`, }, + win: true, + }, { + in: `C:\path\to\file`, + wantParsed: Parsed{ + Name: "C", + ConfigString: "C", + Path: `\path\to\file`, + }, + noWin: true, + }, { + in: `\path\to\file`, + wantParsed: Parsed{ + Name: "", + Path: `/path/to/file`, + }, + win: true, + }, { + in: `\path\to\file`, + wantParsed: Parsed{ + Name: "", + Path: `\path\to\file`, + }, + noWin: true, + }, { + in: `remote:\path\to\file`, + wantParsed: Parsed{ + Name: "remote", + ConfigString: "remote", + Path: `/path/to/file`, + }, + win: true, }, { in: `remote:\path\to\file`, wantParsed: Parsed{ @@ -193,6 +233,14 @@ func TestParse(t *testing.T) { ConfigString: "remote", Path: `\path\to\file`, }, + noWin: true, + }, { + in: `D:/path/to/file`, + wantParsed: Parsed{ + Name: "", + Path: `D:/path/to/file`, + }, + win: true, }, { in: `D:/path/to/file`, wantParsed: Parsed{ @@ -200,6 +248,7 @@ func TestParse(t *testing.T) { ConfigString: "D", Path: `/path/to/file`, }, + noWin: true, }, { in: `:backend,param1:/path/to/file`, wantParsed: Parsed{ @@ -307,9 +356,11 @@ func TestParse(t *testing.T) { }, } { gotParsed, gotErr := Parse(test.in) - // For non-local paths we convert \ into / on Windows - if runtime.GOOS == "windows" && test.wantParsed.Name != "" { - test.wantParsed.Path = strings.Replace(test.wantParsed.Path, `\`, `/`, -1) + if runtime.GOOS == "windows" && test.noWin { + continue + } + if runtime.GOOS != "windows" && test.win { + continue } assert.Equal(t, test.wantErr, gotErr, test.in) if test.wantErr == nil {