| 1261 | } |
| 1262 | |
| 1263 | func (b *bisyncTest) copyFile(ctx context.Context, src, dst, asName string) (err error) { |
| 1264 | fs.Debugf(nil, "copyFile %q to %q as %q", src, dst, asName) |
| 1265 | var fsrc, fdst fs.Fs |
| 1266 | var srcPath, srcFile, dstPath, dstFile string |
| 1267 | src = b.replaceHex(src) |
| 1268 | dst = b.replaceHex(dst) |
| 1269 | |
| 1270 | switch fsrc, err = fs.NewFs(ctx, src); err { // intentionally using NewFs here to avoid dircaching the parent |
| 1271 | case fs.ErrorIsFile: |
| 1272 | // ok |
| 1273 | case nil: |
| 1274 | return errors.New("source must be a file") |
| 1275 | default: |
| 1276 | return err |
| 1277 | } |
| 1278 | |
| 1279 | if _, srcPath, err = fspath.SplitFs(src); err != nil { |
| 1280 | return err |
| 1281 | } |
| 1282 | srcFile = path.Base(srcPath) |
| 1283 | |
| 1284 | if dstPath, dstFile, err = fspath.Split(dst); err != nil { |
| 1285 | return err |
| 1286 | } |
| 1287 | if dstPath == "" { |
| 1288 | return errors.New("invalid destination") |
| 1289 | } |
| 1290 | if dstFile != "" { |
| 1291 | dstPath = dst // force directory |
| 1292 | } |
| 1293 | if fdst, err = fs.NewFs(ctx, dstPath); err != nil { // intentionally using NewFs here to avoid dircaching the parent |
| 1294 | return err |
| 1295 | } |
| 1296 | |
| 1297 | if asName != "" { |
| 1298 | dstFile = asName |
| 1299 | } else { |
| 1300 | dstFile = srcFile |
| 1301 | } |
| 1302 | |
| 1303 | fctx, fi := filter.AddConfig(ctx) |
| 1304 | if err := fi.AddFile(srcFile); err != nil { |
| 1305 | return err |
| 1306 | } |
| 1307 | fs.Debugf(nil, "operations.CopyFile %q to %q as %q", srcFile, fdst.String(), dstFile) |
| 1308 | return operations.CopyFile(fctx, fdst, fsrc, dstFile, srcFile) |
| 1309 | } |
| 1310 | |
| 1311 | // listSubdirs is equivalent to `rclone lsf -R [--dirs-only]` |
| 1312 | func (b *bisyncTest) listSubdirs(ctx context.Context, remote string, DirsOnly bool) error { |