mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
109 lines
3.0 KiB
Dart
109 lines
3.0 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 'package:archive/archive.dart';
|
|
import 'package:path/path.dart' as path;
|
|
|
|
import 'asset.dart';
|
|
import 'base/process.dart';
|
|
|
|
abstract class ZipBuilder {
|
|
factory ZipBuilder() {
|
|
if (exitsHappy(<String>['which', 'zip'])) {
|
|
return new _ZipToolBuilder();
|
|
} else {
|
|
return new _ArchiveZipBuilder();
|
|
}
|
|
}
|
|
|
|
ZipBuilder._();
|
|
|
|
List<AssetBundleEntry> entries = <AssetBundleEntry>[];
|
|
|
|
void addEntry(AssetBundleEntry entry) => entries.add(entry);
|
|
|
|
void createZip(File outFile, Directory zipBuildDir);
|
|
}
|
|
|
|
class _ArchiveZipBuilder extends ZipBuilder {
|
|
_ArchiveZipBuilder() : super._();
|
|
|
|
@override
|
|
void createZip(File outFile, Directory zipBuildDir) {
|
|
Archive archive = new Archive();
|
|
|
|
for (AssetBundleEntry entry in entries) {
|
|
List<int> data = entry.contentsAsBytes();
|
|
archive.addFile(new ArchiveFile.noCompress(entry.archivePath, data.length, data));
|
|
}
|
|
|
|
List<int> zipData = new ZipEncoder().encode(archive);
|
|
outFile.writeAsBytesSync(zipData);
|
|
}
|
|
}
|
|
|
|
class _ZipToolBuilder extends ZipBuilder {
|
|
_ZipToolBuilder() : super._();
|
|
|
|
@override
|
|
void createZip(File outFile, Directory zipBuildDir) {
|
|
// If there are no assets, then create an empty zip file.
|
|
if (entries.isEmpty) {
|
|
List<int> zipData = new ZipEncoder().encode(new Archive());
|
|
outFile.writeAsBytesSync(zipData);
|
|
return;
|
|
}
|
|
|
|
if (outFile.existsSync())
|
|
outFile.deleteSync();
|
|
|
|
if (zipBuildDir.existsSync())
|
|
zipBuildDir.deleteSync(recursive: true);
|
|
zipBuildDir.createSync(recursive: true);
|
|
|
|
for (AssetBundleEntry entry in entries) {
|
|
List<int> data = entry.contentsAsBytes();
|
|
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
|
|
);
|
|
}
|
|
|
|
if (_getStoredNames().isNotEmpty) {
|
|
runCheckedSync(
|
|
<String>['zip', '-q', '-0', outFile.absolute.path]..addAll(_getStoredNames()),
|
|
workingDirectory: zipBuildDir.path
|
|
);
|
|
}
|
|
}
|
|
|
|
static const List<String> _kNoCompressFileExtensions = const <String>['.png', '.jpg'];
|
|
|
|
bool isAssetCompressed(AssetBundleEntry entry) {
|
|
return !_kNoCompressFileExtensions.any(
|
|
(String extension) => entry.archivePath.endsWith(extension)
|
|
);
|
|
}
|
|
|
|
Iterable<String> _getCompressedNames() {
|
|
return entries
|
|
.where(isAssetCompressed)
|
|
.map((AssetBundleEntry entry) => entry.archivePath);
|
|
}
|
|
|
|
Iterable<String> _getStoredNames() {
|
|
return entries
|
|
.where((AssetBundleEntry entry) => !isAssetCompressed(entry))
|
|
.map((AssetBundleEntry entry) => entry.archivePath);
|
|
}
|
|
}
|