buildTransferTar function

Uint8List buildTransferTar(
  1. Transferable transferable,
  2. String destination, {
  3. int mode = kDefaultTransferMode,
})

Builds an in-memory tar archive from transferable and returns the raw bytes ready to be uploaded via PUT /containers/{id}/archive?path=/.

The archive contains a single entry (or multiple entries for a directory) with destination as the path within the archive and mode as the Unix permission bits.

Parameters:

  • transferable — the content to pack. Must be a BytesTransferable or a PathTransferable whose FileSystemEntity exists.
  • destination — the path of the entry inside the tar archive. This becomes the absolute path inside the container when extracted at /.
  • mode — Unix permission bits. Defaults to 0x1A4 (0o644, owner-read/write, group-read, other-read).

Throws ArgumentError when transferable is a PathTransferable whose path neither exists as a file nor as a directory.

Implementation

Uint8List buildTransferTar(
  Transferable transferable,
  String destination, {
  int mode = kDefaultTransferMode,
}) {
  final archive = Archive();

  switch (transferable) {
    case BytesTransferable(:final bytes):
      final entry = ArchiveFile(destination, bytes.length, bytes);
      entry.mode = mode;
      archive.addFile(entry);
    case PathTransferable(:final path):
      final entity = path;
      if (entity is File && entity.existsSync()) {
        final bytes = entity.readAsBytesSync();
        final entry = ArchiveFile(destination, bytes.length, bytes);
        entry.mode = mode;
        archive.addFile(entry);
      } else if (entity is Directory && entity.existsSync()) {
        final dirName = entity.path.split(RegExp(r'[/\\]')).last;
        final base = destination.endsWith('/') ? destination : '$destination/';
        for (final file in entity.listSync(recursive: true).whereType<File>()) {
          final relative = file.path.substring(entity.path.length);
          final entryName = '$base$dirName$relative'.replaceAll('\\', '/');
          final bytes = file.readAsBytesSync();
          final entry = ArchiveFile(entryName, bytes.length, bytes);
          entry.mode = mode;
          archive.addFile(entry);
        }
      } else {
        throw ArgumentError(
          'Path ${entity.path} is neither a file nor directory',
        );
      }
  }

  return Uint8List.fromList(TarEncoder().encode(archive));
}