flutter/packages/flutter_tools/lib/src/zip.dart
2016-03-03 15:18:32 -08:00

123 lines
3.3 KiB
Dart

// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'dart:convert' show UTF8;
import 'package:archive/archive.dart';
import 'package:path/path.dart' as path;
import 'base/process.dart';
abstract class ZipBuilder {
factory ZipBuilder() {
if (exitsHappy(<String>['which', 'zip'])) {
return new _ZipToolBuilder();
} else {
return new _ArchiveZipBuilder();
}
}
ZipBuilder._();
List<ZipEntry> entries = <ZipEntry>[];
void addEntry(ZipEntry entry) => entries.add(entry);
void createZip(File outFile, Directory zipBuildDir);
}
class ZipEntry {
ZipEntry.fromFile(this.archivePath, File file) {
this._file = file;
}
ZipEntry.fromString(this.archivePath, String contents) {
this._contents = contents;
}
final String archivePath;
File _file;
String _contents;
bool get isStringEntry => _contents != null;
}
class _ArchiveZipBuilder extends ZipBuilder {
_ArchiveZipBuilder() : super._();
void createZip(File outFile, Directory zipBuildDir) {
Archive archive = new Archive();
for (ZipEntry entry in entries) {
if (entry.isStringEntry) {
List<int> data = UTF8.encode(entry._contents);
archive.addFile(new ArchiveFile.noCompress(entry.archivePath, data.length, data));
} else {
List<int> data = entry._file.readAsBytesSync();
archive.addFile(new ArchiveFile(entry.archivePath, data.length, data));
}
}
List<int> zipData = new ZipEncoder().encode(archive);
outFile.writeAsBytesSync(zipData);
}
}
class _ZipToolBuilder extends ZipBuilder {
_ZipToolBuilder() : super._();
void createZip(File outFile, Directory zipBuildDir) {
if (outFile.existsSync())
outFile.deleteSync();
if (zipBuildDir.existsSync())
zipBuildDir.deleteSync(recursive: true);
zipBuildDir.createSync(recursive: true);
for (ZipEntry entry in entries) {
if (entry.isStringEntry) {
List<int> data = UTF8.encode(entry._contents);
File file = new File(path.join(zipBuildDir.path, entry.archivePath));
file.parent.createSync(recursive: true);
file.writeAsBytesSync(data);
} else {
List<int> data = entry._file.readAsBytesSync();
File file = new File(path.join(zipBuildDir.path, entry.archivePath));
file.parent.createSync(recursive: true);
file.writeAsBytesSync(data);
}
}
if (_getCompressedNames().isNotEmpty) {
runCheckedSync(
<String>['zip', '-q', outFile.absolute.path]..addAll(_getCompressedNames()),
workingDirectory: zipBuildDir.path,
truncateCommand: true
);
}
if (_getStoredNames().isNotEmpty) {
runCheckedSync(
<String>['zip', '-q', '-0', outFile.absolute.path]..addAll(_getStoredNames()),
workingDirectory: zipBuildDir.path,
truncateCommand: true
);
}
}
Iterable<String> _getCompressedNames() {
return entries
.where((ZipEntry entry) => !entry.isStringEntry)
.map((ZipEntry entry) => entry.archivePath);
}
Iterable<String> _getStoredNames() {
return entries
.where((ZipEntry entry) => entry.isStringEntry)
.map((ZipEntry entry) => entry.archivePath);
}
}