fs: Add context to fs.Features.Fill & fs.Features.Mask #3257 #4685

This commit is contained in:
Nick Craig-Wood 2020-11-05 16:00:40 +00:00
parent d69b96a94c
commit 8b96933e58
38 changed files with 48 additions and 48 deletions

View File

@ -273,7 +273,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
CaseInsensitive: true,
ReadMimeType: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
// Renew the token in the background
f.tokenRenewer = oauthutil.NewRenew(f.String(), ts, func() error {

View File

@ -432,7 +432,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
BucketBasedRootOK: true,
SetTier: true,
GetTier: true,
}).Fill(f)
}).Fill(ctx, f)
var (
u *url.URL

View File

@ -438,7 +438,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
WriteMimeType: true,
BucketBased: true,
BucketBasedRootOK: true,
}).Fill(f)
}).Fill(ctx, f)
// Set the test flag if required
if opt.TestMode != "" {
testMode := strings.TrimSpace(opt.TestMode)

View File

@ -407,7 +407,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
CaseInsensitive: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
// If using an accessToken, set the Authorization header
@ -462,7 +462,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
return nil, err
}
f.features.Fill(&tempF)
f.features.Fill(ctx, &tempF)
// XXX: update the old f here instead of returning tempF, since
// `features` were already filled with functions having *f as a receiver.
// See https://github.com/rclone/rclone/issues/2182

View File

@ -512,7 +512,7 @@ func NewFs(ctx context.Context, name, rootPath string, m configmap.Mapper) (fs.F
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
DuplicateFiles: false, // storage doesn't permit this
}).Fill(f).Mask(wrappedFs).WrapsFs(f, wrappedFs)
}).Fill(ctx, f).Mask(ctx, wrappedFs).WrapsFs(f, wrappedFs)
// override only those features that use a temp fs and it doesn't support them
//f.features.ChangeNotify = f.ChangeNotify
if f.opt.TempWritePath != "" {

View File

@ -294,7 +294,7 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs,
BucketBased: true,
CanHaveEmptyDirectories: true,
ServerSideAcrossConfigs: true,
}).Fill(f).Mask(baseFs).WrapsFs(f, baseFs)
}).Fill(ctx, f).Mask(ctx, baseFs).WrapsFs(f, baseFs)
f.features.Disable("ListR") // Recursive listing may cause chunker skip files

View File

@ -199,7 +199,7 @@ func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs,
SetTier: true,
GetTier: true,
ServerSideAcrossConfigs: opt.ServerSideAcrossConfigs,
}).Fill(f).Mask(wrappedFs).WrapsFs(f, wrappedFs)
}).Fill(ctx, f).Mask(ctx, wrappedFs).WrapsFs(f, wrappedFs)
return f, err
}

View File

@ -953,7 +953,7 @@ func configTeamDrive(ctx context.Context, opt *Options, m configmap.Mapper, name
if !config.Confirm(false) {
return nil
}
f, err := newFs(name, "", m)
f, err := newFs(ctx, name, "", m)
if err != nil {
return errors.Wrap(err, "failed to make Fs to list teamdrives")
}
@ -1065,7 +1065,7 @@ func (f *Fs) setUploadCutoff(cs fs.SizeSuffix) (old fs.SizeSuffix, err error) {
//
// It constructs a valid Fs but doesn't attempt to figure out whether
// it is a file or a directory.
func newFs(name, path string, m configmap.Mapper) (*Fs, error) {
func newFs(ctx context.Context, name, path string, m configmap.Mapper) (*Fs, error) {
// Parse config into Options struct
opt := new(Options)
err := configstruct.Set(m, opt)
@ -1109,7 +1109,7 @@ func newFs(name, path string, m configmap.Mapper) (*Fs, error) {
WriteMimeType: true,
CanHaveEmptyDirectories: true,
ServerSideAcrossConfigs: opt.ServerSideAcrossConfigs,
}).Fill(f)
}).Fill(ctx, f)
// Create a new authorized Drive client.
f.client = oAuthClient
@ -1130,7 +1130,7 @@ func newFs(name, path string, m configmap.Mapper) (*Fs, error) {
// NewFs constructs an Fs from the path, container:path
func NewFs(ctx context.Context, name, path string, m configmap.Mapper) (fs.Fs, error) {
f, err := newFs(name, path, m)
f, err := newFs(ctx, name, path, m)
if err != nil {
return nil, err
}

View File

@ -414,7 +414,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.opt.SharedFolders = false
}
f.features.Fill(f)
f.features.Fill(ctx, f)
// If root starts with / then use the actual root
if strings.HasPrefix(root, "/") {

View File

@ -193,7 +193,7 @@ func NewFs(ctx context.Context, name string, root string, config configmap.Mappe
f.features = (&fs.Features{
DuplicateFiles: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
client := fshttp.NewClient(fs.Config)
@ -225,7 +225,7 @@ func NewFs(ctx context.Context, name string, root string, config configmap.Mappe
}
return nil, err
}
f.features.Fill(&tempF)
f.features.Fill(ctx, &tempF)
// XXX: update the old f here instead of returning tempF, since
// `features` were already filled with functions having *f as a receiver.
// See https://github.com/rclone/rclone/issues/2182

View File

@ -339,7 +339,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs
}
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
// Make a connection and pool it to return errors early
c, err := f.getFtpConnection()
if err != nil {

View File

@ -441,7 +441,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
WriteMimeType: true,
BucketBased: true,
BucketBasedRootOK: true,
}).Fill(f)
}).Fill(ctx, f)
// Create a new authorized Drive client.
f.client = oAuthClient

View File

@ -279,7 +279,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
f.features = (&fs.Features{
ReadMimeType: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
_, _, pattern := patterns.match(f.root, "", true)

View File

@ -219,7 +219,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
if isFile {
return f, fs.ErrorIsFile
}

View File

@ -720,7 +720,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
CanHaveEmptyDirectories: true,
ReadMimeType: true,
WriteMimeType: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
if opt.TrashedOnly { // we cannot support showing Trashed Files when using ListR right now
f.features.ListR = nil

View File

@ -287,7 +287,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (ff fs.Fs
DuplicateFiles: false,
BucketBased: false,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
for _, m := range mounts {
if opt.MountID != "" {
if m.Id == opt.MountID {

View File

@ -245,7 +245,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
CanHaveEmptyDirectories: true,
IsLocal: true,
SlowHash: true,
}).Fill(f)
}).Fill(ctx, f)
if opt.FollowSymlinks {
f.lstat = os.Stat
}

View File

@ -332,7 +332,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
// Can copy/move across mailru configs (almost, thus true here), but
// only when they share common account (this is checked in Copy/Move).
ServerSideAcrossConfigs: true,
}).Fill(f)
}).Fill(ctx, f)
// Override few config settings and create a client
clientConfig := *fs.Config

View File

@ -233,7 +233,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
DuplicateFiles: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
// Find the root node and check if it is a file or not
_, err = f.findRoot(false)

View File

@ -241,7 +241,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
WriteMimeType: true,
BucketBased: true,
BucketBasedRootOK: true,
}).Fill(f)
}).Fill(ctx, f)
if f.rootBucket != "" && f.rootDirectory != "" {
od := buckets.getObjectData(f.rootBucket, f.rootDirectory)
if od != nil {

View File

@ -633,7 +633,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
ReadMimeType: true,
CanHaveEmptyDirectories: true,
ServerSideAcrossConfigs: opt.ServerSideAcrossConfigs,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
// Renew the token in the background

View File

@ -216,7 +216,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
CaseInsensitive: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
// Find the current root
err = f.dirCache.FindRoot(ctx, false)

View File

@ -304,7 +304,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
CaseInsensitive: false,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
// Renew the token in the background

View File

@ -266,7 +266,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
CaseInsensitive: true,
CanHaveEmptyDirectories: true,
ReadMimeType: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
// Renew the token in the background
@ -302,7 +302,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
return nil, err
}
f.features.Fill(&tempF)
f.features.Fill(ctx, &tempF)
// XXX: update the old f here instead of returning tempF, since
// `features` were already filled with functions having *f as a receiver.
// See https://github.com/rclone/rclone/issues/2182

View File

@ -95,7 +95,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (f fs.Fs,
DuplicateFiles: true,
ReadMimeType: true,
CanHaveEmptyDirectories: true,
}).Fill(p)
}).Fill(ctx, p)
p.dirCache = dircache.New(root, "0", p)
// Find the current root
err = p.dirCache.FindRoot(ctx, false)

View File

@ -357,7 +357,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
BucketBased: true,
BucketBasedRootOK: true,
SlowModTime: true,
}).Fill(f)
}).Fill(ctx, f)
if f.rootBucket != "" && f.rootDirectory != "" {
// Check to see if the object exists

View File

@ -1620,7 +1620,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
SetTier: true,
GetTier: true,
SlowModTime: true,
}).Fill(f)
}).Fill(ctx, f)
if f.rootBucket != "" && f.rootDirectory != "" {
// Check to see if the object exists
encodedDirectory := f.opt.Enc.FromStandardPath(f.rootDirectory)

View File

@ -203,7 +203,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
BucketBased: opt.LibraryName == "",
}).Fill(f)
}).Fill(ctx, f)
serverInfo, err := f.getServerInfo(ctx)
if err != nil {

View File

@ -609,7 +609,7 @@ func NewFsWithConnection(ctx context.Context, f *Fs, name string, root string, m
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
SlowHash: true,
}).Fill(f)
}).Fill(ctx, f)
// Make a connection and pool it to return errors early
c, err := f.getSftpConnection()
if err != nil {

View File

@ -452,7 +452,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
CaseInsensitive: true,
CanHaveEmptyDirectories: true,
ReadMimeType: false,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
f.fillBufferTokens()
@ -517,7 +517,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
return nil, err
}
f.features.Fill(&tempF)
f.features.Fill(ctx, &tempF)
// XXX: update the old f here instead of returning tempF, since
// `features` were already filled with functions having *f as a receiver.
// See https://github.com/rclone/rclone/issues/2182

View File

@ -416,7 +416,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
f.features = (&fs.Features{
CaseInsensitive: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetSigner(f.getAuth) // use signing hook to get the auth
f.srv.SetErrorHandler(errorHandler)

View File

@ -448,7 +448,7 @@ func NewFsWithConnection(ctx context.Context, opt *Options, name, root string, c
BucketBased: true,
BucketBasedRootOK: true,
SlowModTime: true,
}).Fill(f)
}).Fill(ctx, f)
if f.rootContainer != "" && f.rootDirectory != "" {
// Check to see if the object exists - ignoring directory markers
var info swift.Object

View File

@ -217,7 +217,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (_ fs.Fs,
f.features = (&fs.Features{
BucketBased: true,
BucketBasedRootOK: true,
}).Fill(f)
}).Fill(ctx, f)
project, err := f.connect(ctx)
if err != nil {

View File

@ -833,9 +833,9 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
BucketBased: true,
SetTier: true,
GetTier: true,
}).Fill(f)
}).Fill(ctx, f)
for _, f := range upstreams {
features = features.Mask(f) // Mask all upstream fs
features = features.Mask(ctx, f) // Mask all upstream fs
}
// Enable ListR when upstreams either support ListR or is local

View File

@ -342,7 +342,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
}
f.features = (&fs.Features{
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
if opt.User != "" || opt.Pass != "" {
f.srv.SetUserPass(opt.User, opt.Pass)
} else if opt.BearerToken != "" {

View File

@ -276,7 +276,7 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
ReadMimeType: true,
WriteMimeType: true,
CanHaveEmptyDirectories: true,
}).Fill(f)
}).Fill(ctx, f)
f.srv.SetErrorHandler(errorHandler)
// Check to see if the object exists and is a file

View File

@ -715,7 +715,7 @@ func (ft *Features) DisableList(list []string) *Features {
// Fill fills in the function pointers in the Features struct from the
// optional interfaces. It returns the original updated Features
// struct passed in.
func (ft *Features) Fill(f Fs) *Features {
func (ft *Features) Fill(ctx context.Context, f Fs) *Features {
if do, ok := f.(Purger); ok {
ft.Purge = do.Purge
}
@ -783,7 +783,7 @@ func (ft *Features) Fill(f Fs) *Features {
// Fs AND the one passed in will be advertised. Any features which
// aren't in both will be set to false/nil, except for UnWrap/Wrap which
// will be left untouched.
func (ft *Features) Mask(f Fs) *Features {
func (ft *Features) Mask(ctx context.Context, f Fs) *Features {
mask := f.Features()
ft.CaseInsensitive = ft.CaseInsensitive && mask.CaseInsensitive
ft.DuplicateFiles = ft.DuplicateFiles && mask.DuplicateFiles

View File

@ -389,7 +389,7 @@ func Run(t *testing.T, opt *Opt) {
if opt.SkipFsCheckWrap {
t.Skip("Skipping FsCheckWrap on this Fs")
}
ft := new(fs.Features).Fill(remote)
ft := new(fs.Features).Fill(ctx, remote)
if ft.UnWrap == nil {
t.Skip("Not a wrapping Fs")
}
@ -1584,7 +1584,7 @@ func Run(t *testing.T, opt *Opt) {
if opt.SkipObjectCheckWrap {
t.Skip("Skipping FsCheckWrap on this Fs")
}
ft := new(fs.Features).Fill(remote)
ft := new(fs.Features).Fill(ctx, remote)
if ft.UnWrap == nil {
t.Skip("Not a wrapping Fs")
}