archive: fix reading an archive in the root of a remote
Opening an archive in the root of a remote, such as remote:file.zip, failed with "file does not exist" because the archive's leaf name was found with path.Base, which doesn't understand remote names. It is now found with fspath.Split.
This commit is contained in:
1 parent
6aed73d2d3
commit
e18da08372
2 files changed
+51
-2
No files matched your search
@@ -194,8 +194,12 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (outFs fs
|
||||
}
|
||||
// Path to the archive
|
||||
archiveRemote := remote[:len(foundArchive.remote)]
|
||||
// Remote is archive leaf name
|
||||
foundArchive.remote = path.Base(archiveRemote)
|
||||
// Remote is archive leaf name. This must understand remote
|
||||
// names as the archive may be in the root, e.g. "remote:file.zip"
|
||||
_, foundArchive.remote, err = fspath.Split(archiveRemote)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse archive path %q: %w", archiveRemote, err)
|
||||
}
|
||||
foundArchive.prefix = ""
|
||||
// Point remote to archive file
|
||||
remote = archiveRemote
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
_ "github.com/rclone/rclone/backend/alias"
|
||||
"github.com/rclone/rclone/backend/archive/archiver"
|
||||
_ "github.com/rclone/rclone/backend/local"
|
||||
"github.com/rclone/rclone/fs"
|
||||
@@ -323,6 +324,50 @@ func TestArchiveUncleanRoot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestArchiveInRemoteRoot checks that an archive in the root of a
|
||||
// remote, with no "/" between the remote name and the archive name, can
|
||||
// be read, as can a path within it.
|
||||
func TestArchiveInRemoteRoot(t *testing.T) {
|
||||
fstest.Initialise()
|
||||
ctx := context.Background()
|
||||
|
||||
var buf bytes.Buffer
|
||||
zw := zip.NewWriter(&buf)
|
||||
w, err := zw.Create("sub/a.txt")
|
||||
require.NoError(t, err)
|
||||
_, err = w.Write([]byte("data"))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, zw.Close())
|
||||
dir := t.TempDir()
|
||||
require.NoError(t, os.WriteFile(filepath.Join(dir, "test.zip"), buf.Bytes(), 0600))
|
||||
t.Chdir(dir)
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
remote string
|
||||
}{
|
||||
{name: "plain", remote: ":local:test.zip"},
|
||||
{name: "slash in remote name", remote: ":alias,remote='" + dir + "':test.zip"},
|
||||
} {
|
||||
for _, sub := range []struct {
|
||||
path string
|
||||
want string
|
||||
}{
|
||||
{path: "", want: "sub"},
|
||||
{path: "/sub", want: "a.txt"},
|
||||
} {
|
||||
t.Run(test.name+sub.path, func(t *testing.T) {
|
||||
f, err := cache.Get(ctx, ":archive:"+test.remote+sub.path)
|
||||
require.NoError(t, err)
|
||||
entries, err := f.List(ctx, "")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, entries, 1)
|
||||
assert.Equal(t, sub.want, entries[0].Remote())
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// escapingObject is an object whose remote is not where it was asked for.
|
||||
type escapingObject struct {
|
||||
fs.Object
|
||||
|
||||
Reference in new issue
Block a user