mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 09:41:44 +08:00
rc: Add GetFsNamedFileOK to get an fs which could also be a file
This commit is contained in:
parent
5994fcfed8
commit
0b8689dc28
|
@ -5,27 +5,71 @@ package rc
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/cache"
|
"github.com/rclone/rclone/fs/cache"
|
||||||
"github.com/rclone/rclone/fs/config/configmap"
|
"github.com/rclone/rclone/fs/config/configmap"
|
||||||
|
"github.com/rclone/rclone/fs/filter"
|
||||||
|
"github.com/rclone/rclone/fs/fspath"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetFsNamed gets an fs.Fs named fsName either from the cache or creates it afresh
|
// getFsName gets an fs name from fsName either from the cache or direct
|
||||||
func GetFsNamed(ctx context.Context, in Params, fsName string) (f fs.Fs, err error) {
|
func getFsName(in Params, fsName string) (fsString string, err error) {
|
||||||
fsString, err := in.GetString(fsName)
|
fsString, err = in.GetString(fsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !IsErrParamInvalid(err) {
|
if !IsErrParamInvalid(err) {
|
||||||
return nil, err
|
return fsString, err
|
||||||
}
|
}
|
||||||
fsString, err = getConfigMap(in, fsName)
|
fsString, err = getConfigMap(in, fsName)
|
||||||
|
if err != nil {
|
||||||
|
return fsString, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fsString, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFsNamed gets an fs.Fs named fsName either from the cache or creates it afresh
|
||||||
|
func GetFsNamed(ctx context.Context, in Params, fsName string) (f fs.Fs, err error) {
|
||||||
|
fsString, err := getFsName(in, fsName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return cache.Get(ctx, fsString)
|
return cache.Get(ctx, fsString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFsNamedFileOK gets an fs.Fs named fsName either from the cache or creates it afresh
|
||||||
|
//
|
||||||
|
// If the fs.Fs points to a single file then it returns a new ctx with
|
||||||
|
// filters applied to make the listings return only that file.
|
||||||
|
func GetFsNamedFileOK(ctx context.Context, in Params, fsName string) (newCtx context.Context, f fs.Fs, err error) {
|
||||||
|
fsString, err := getFsName(in, fsName)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, nil, err
|
||||||
|
}
|
||||||
|
f, err = cache.Get(ctx, fsString)
|
||||||
|
if err == nil {
|
||||||
|
return ctx, f, nil
|
||||||
|
} else if !errors.Is(err, fs.ErrorIsFile) {
|
||||||
|
return ctx, nil, err
|
||||||
|
}
|
||||||
|
// f points to the directory above the file so find the remote name
|
||||||
|
_, fileName, err := fspath.Split(fsString)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, f, err
|
||||||
|
}
|
||||||
|
ctx, fi := filter.AddConfig(ctx)
|
||||||
|
if !fi.InActive() {
|
||||||
|
return ctx, f, fmt.Errorf("can't limit to single files when using filters: %q", fileName)
|
||||||
|
}
|
||||||
|
// Limit transfers to this file
|
||||||
|
err = fi.AddFile(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return ctx, f, fmt.Errorf("failed to limit to single file: %w", err)
|
||||||
|
}
|
||||||
|
return ctx, f, nil
|
||||||
|
}
|
||||||
|
|
||||||
// getConfigMap gets the config as a map from in and converts it to a
|
// getConfigMap gets the config as a map from in and converts it to a
|
||||||
// config string
|
// config string
|
||||||
//
|
//
|
||||||
|
|
|
@ -5,18 +5,26 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rclone/rclone/fs"
|
||||||
"github.com/rclone/rclone/fs/cache"
|
"github.com/rclone/rclone/fs/cache"
|
||||||
|
"github.com/rclone/rclone/fs/filter"
|
||||||
"github.com/rclone/rclone/fstest/mockfs"
|
"github.com/rclone/rclone/fstest/mockfs"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockNewFs(t *testing.T) func() {
|
func mockNewFs(t *testing.T) func() {
|
||||||
f, err := mockfs.NewFs(context.Background(), "mock", "mock", nil)
|
ctx := context.Background()
|
||||||
|
f, err := mockfs.NewFs(ctx, "/", "", nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
cache.Put("/", f)
|
cache.Put("/", f)
|
||||||
|
f, err = mockfs.NewFs(ctx, "mock", "/", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
cache.Put("mock:/", f)
|
cache.Put("mock:/", f)
|
||||||
cache.Put(":mock:/", f)
|
cache.Put(":mock:/", f)
|
||||||
|
f, err = mockfs.NewFs(ctx, "mock", "dir/file.txt", nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
cache.PutErr("mock:dir/file.txt", f, fs.ErrorIsFile)
|
||||||
return func() {
|
return func() {
|
||||||
cache.Clear()
|
cache.Clear()
|
||||||
}
|
}
|
||||||
|
@ -64,6 +72,40 @@ func TestGetFsNamedStruct(t *testing.T) {
|
||||||
assert.NotNil(t, f)
|
assert.NotNil(t, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetFsNamedFileOK(t *testing.T) {
|
||||||
|
defer mockNewFs(t)()
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
in := Params{
|
||||||
|
"potato": "/",
|
||||||
|
}
|
||||||
|
newCtx, f, err := GetFsNamedFileOK(ctx, in, "potato")
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.NotNil(t, f)
|
||||||
|
assert.Equal(t, ctx, newCtx)
|
||||||
|
|
||||||
|
in = Params{
|
||||||
|
"sausage": "/",
|
||||||
|
}
|
||||||
|
newCtx, f, err = GetFsNamedFileOK(ctx, in, "potato")
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, f)
|
||||||
|
assert.Equal(t, ctx, newCtx)
|
||||||
|
|
||||||
|
in = Params{
|
||||||
|
"potato": "mock:dir/file.txt",
|
||||||
|
}
|
||||||
|
newCtx, f, err = GetFsNamedFileOK(ctx, in, "potato")
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.NotNil(t, f)
|
||||||
|
assert.NotEqual(t, ctx, newCtx)
|
||||||
|
|
||||||
|
fi := filter.GetConfig(newCtx)
|
||||||
|
assert.False(t, fi.InActive())
|
||||||
|
assert.True(t, fi.IncludeRemote("file.txt"))
|
||||||
|
assert.False(t, fi.IncludeRemote("other.txt"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetConfigMap(t *testing.T) {
|
func TestGetConfigMap(t *testing.T) {
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
in Params
|
in Params
|
||||||
|
|
Loading…
Reference in New Issue
Block a user