copyRecursivelyWithProgress method

Future<void> copyRecursivelyWithProgress(
  1. Directory target,
  2. FileSystemEntityCopyProgressCb onProgress, {
  3. bool followLinks = true,
  4. LinkFactory linkFactory = Link.new,
  5. FileFactory fileFactory = File.new,
  6. DirectoryFactory dirFactory = Directory.new,
  7. Context? pathContext,
})

Copies all of the files in this directory to target.

This is similar to cp -R <from> <to>:

  • Symlinks are supported.
  • Existing files are over-written, if any.
  • If target is within this, throws ArgumentError.
  • If this and target are canonically the same, no operation occurs.

Implementation

Future<void> copyRecursivelyWithProgress(
  Directory target,
  FileSystemEntityCopyProgressCb onProgress, {
  bool followLinks = true,
  LinkFactory linkFactory = Link.new,
  FileFactory fileFactory = File.new,
  DirectoryFactory dirFactory = Directory.new,
  lib_path.Context? pathContext,
}) async {
  pathContext ??= lib_path.context;

  if (pathContext.canonicalize(path) ==
      pathContext.canonicalize(target.path)) {
    return;
  }

  if (pathContext.isWithin(path, target.path)) {
    throw ArgumentError("Cannot copy $path to ${target.path}");
  }

  await target.create(recursive: true);

  final totalBytes = await length();
  var copiedBytes = 0;

  await for (final file in list(recursive: true, followLinks: followLinks)) {
    final copyTo = pathContext.join(
      target.path,
      pathContext.relative(file.path, from: path),
    );

    if (file is Directory) {
      await dirFactory(copyTo).create(recursive: true);
    } else if (file is File) {
      var lastProgress = 0;
      await fileFactory(file.path).copyWithProgress(
        copyTo,
        (_, progress) {
          copiedBytes += progress - lastProgress;
          lastProgress = progress;
          onProgress(totalBytes, copiedBytes);
        },
      );
    } else if (file is Link) {
      final linkTarget = await file.target();
      await linkFactory(copyTo).create(linkTarget, recursive: true);
    }
  }
}