NewFs constructs an Fs from the path, container:path
(ctx context.Context, name, rpath string, m configmap.Mapper)
| 222 | |
| 223 | // NewFs constructs an Fs from the path, container:path |
| 224 | func NewFs(ctx context.Context, name, rpath string, m configmap.Mapper) (fs.Fs, error) { |
| 225 | // Parse config into Options struct |
| 226 | opt := new(Options) |
| 227 | err := configstruct.Set(m, opt) |
| 228 | if err != nil { |
| 229 | return nil, err |
| 230 | } |
| 231 | cipher, err := newCipherForConfig(opt) |
| 232 | if err != nil { |
| 233 | return nil, err |
| 234 | } |
| 235 | remote := opt.Remote |
| 236 | if strings.HasPrefix(remote, name+":") { |
| 237 | return nil, errors.New("can't point crypt remote at itself - check the value of the remote setting") |
| 238 | } |
| 239 | // Make sure to remove trailing . referring to the current dir |
| 240 | if path.Base(rpath) == "." { |
| 241 | rpath = strings.TrimSuffix(rpath, ".") |
| 242 | } |
| 243 | // Look for a file first |
| 244 | var wrappedFs fs.Fs |
| 245 | if rpath == "" { |
| 246 | wrappedFs, err = cache.Get(ctx, remote) |
| 247 | } else { |
| 248 | remotePath := fspath.JoinRootPath(remote, cipher.EncryptFileName(rpath)) |
| 249 | wrappedFs, err = cache.Get(ctx, remotePath) |
| 250 | // if that didn't produce a file, look for a directory |
| 251 | if err != fs.ErrorIsFile { |
| 252 | remotePath = fspath.JoinRootPath(remote, cipher.EncryptDirName(rpath)) |
| 253 | wrappedFs, err = cache.Get(ctx, remotePath) |
| 254 | } |
| 255 | } |
| 256 | if err != fs.ErrorIsFile && err != nil { |
| 257 | return nil, fmt.Errorf("failed to make remote %q to wrap: %w", remote, err) |
| 258 | } |
| 259 | f := &Fs{ |
| 260 | Fs: wrappedFs, |
| 261 | name: name, |
| 262 | root: rpath, |
| 263 | opt: *opt, |
| 264 | cipher: cipher, |
| 265 | } |
| 266 | cache.PinUntilFinalized(f.Fs, f) |
| 267 | // Correct root if definitely pointing to a file |
| 268 | if err == fs.ErrorIsFile { |
| 269 | f.root = path.Dir(f.root) |
| 270 | if f.root == "." || f.root == "/" { |
| 271 | f.root = "" |
| 272 | } |
| 273 | } |
| 274 | // the features here are ones we could support, and they are |
| 275 | // ANDed with the ones from wrappedFs |
| 276 | f.features = (&fs.Features{ |
| 277 | CaseInsensitive: !cipher.dirNameEncrypt || cipher.NameEncryptionMode() == NameEncryptionOff, |
| 278 | DuplicateFiles: true, |
| 279 | ReadMimeType: false, // MimeTypes not supported with crypt |
| 280 | WriteMimeType: false, |
| 281 | BucketBased: true, |
nothing calls this directly
no test coverage detected
searching dependent graphs…