archive method
archive source path
archiveFile: to archive file.archiveType: to archive type.useRelPath: use relative path If true else use deroot absolute path.
final excludes = [r'.**'];
final source = '.';
final action = BasicPathAction(source, excludes:excludes);
final toArchive = File(expandTilde('~/Downloads/ft.tgz'));
action.archive(toArchive, ArchiveType.tgz);
Implementation
Stream<Es> archive(File archiveFile, ArchiveType archiveType,
[bool useRelPath = true]) {
final action = PathAction.archive.name, chk = 'validator';
argErr ??= validator();
if (argErr!.isNotEmpty) throw ArgumentError.value(argErr, action, chk);
final srcPath = (type == FileSystemEntityType.directory)
? Directory(path).absolute.path
: path;
final fields = fieldsFromOptions(fmtFields);
final fseType = FileSystemEntityType.file;
final stream = scEntity.stream;
final fStream =
stream.where((event) => event.fs.type == fseType).asBroadcastStream();
final tarEntryController = StreamController<TarEntry>(sync: true);
late StreamSubscription subs;
subs = fStream.listen(
(event) {
final (entity, stat, extra) = event.asRecord;
final oldPath = entity.isAbsolute ? entity.path : entity.absolute.path;
// keep the original, use useRelPath
var newPath = oldPath;
if (useRelPath) {
if (type == FileSystemEntityType.directory) {
newPath = oldPath.substring(srcPath.length + 1);
} else {
newPath = p.basename(path);
}
}
if (newPath == archiveFile.path) return; // same continue and for...in
var ok = false;
newPath = separatorToForwardSlash(newPath);
try {
tarEntryController.add(
TarEntry(
TarHeader(
name: newPath,
modified: stat.modified,
mode: stat.mode,
size: stat.size),
File(entity.path).openRead(),
),
);
ok = true;
} catch (e, s) {
logger.stderr('e, $action, data, secure ${entity.path}');
scEntity.addError(e, s);
}
final line =
Formatter(entity, stat, extra, action, shows: fields, ok: ok);
logger.stdout(line.toString());
},
cancelOnError: cancelOnError,
onDone: () {
logger.trace('d, $action, done.');
final outputStream = archiveFile.openWrite();
final tStream = (archiveType == ArchiveType.tgz)
? tarEntryController.stream
.transform(tarWriter)
.transform(gzip.encoder)
: tarEntryController.stream;
final pipe = (archiveType == ArchiveType.tgz)
? tStream.pipe(outputStream)
: tStream.pipe(tarWritingSink(outputStream));
pipe.then(
(_) => unawaited(outputStream.close()),
onError: (e, s) =>
logger.stderr('e, $action, done, pipe tarwrite, $e\n$s'),
);
tarEntryController.close();
},
onError: (e, s) {
if (cancelOnError) {
tarEntryController.close();
exitCode = ExitCodeExt.error.code;
subs.cancel();
}
logger
..trace('d, $action, cancelOnError:$cancelOnError')
..stderr('e, $action, error. $e')
..stderr(kIsDebug ? '$s' : '');
}, // onError
);
return fStream;
}