unArchive function

void unArchive(
  1. File file,
  2. Directory dir,
  3. List<FormatField> fields, {
  4. bool useRelPath = true,
  5. Logger? logger,
  6. bool? isDirWritable,
})

unarchive filename to pathname,

extname: tar.gz, tgz, tar.

Implementation

void unArchive(
  File file,
  Directory dir,
  List<FormatField> fields, {
  bool useRelPath = true,
  Logger? logger,
  bool? isDirWritable,
}) {
  final name = 'unArchive';
  final extName = p.extension(file.path);

  final compressed = (extName.endsWith(r'gz')) ? true : false;
  final input =
      compressed ? file.openRead().transform(gzip.decoder) : file.openRead();

  final pathname = dir.path;
  TarReader.forEach(
    input,
    (tarEntry) async {
      var tarPath = tarEntry.name;
      if (p.isAbsolute(tarPath) && useRelPath) tarPath = pathderoot(tarPath);

      final location = p.normalize(p.join(pathname, tarPath));
      if (useRelPath && !p.isWithin(pathname, location)) {
        logger?.stderr('e, $name, $location, isNotWithin $pathname');
        return; // // same continue and for...in
      }

      if (tarEntry.type == TypeFlag.reg) {
        await File(location).create(recursive: true).then(
          (out) async {
            await tarEntry.contents.pipe(out.openWrite()).then(
              (_) {
                final line = Formatter(out, out.statSync(), '', name,
                    shows: fields, ok: true);
                logger?.stdout(line.toString());
              },
              onError: (e, s) {
                final line = Formatter(out, out.statSync(), e, name,
                    shows: fields, ok: false);
                logger?.stdout(line.toString());
                logger?.stderr('e, $name, $location, $e');
              },
            );
          },
          onError: (e, s) {
            logger?.stderr('e, $name, $location, $e');
          },
        );
      }
      if (tarEntry.type == TypeFlag.dir) {
        await Directory(location).create(recursive: true).then(
          (dir) {
            final line = Formatter(dir, dir.statSync(), '', name,
                shows: fields, ok: true);
            logger?.stdout(line.toString());
          },
          onError: (e, s) {
            logger?.stderr('e, $name, $location, $e');
          },
        );
      }
    }, // end action
  ).then((value) {
    logger?.trace('d, $name, TarReader.endForEach.');
    // unawaited(input.drain());
  });

  return;
}