mirror of
https://github.com/flutter/flutter
synced 2024-10-13 03:32:55 +00:00
Add gradle wrapper to project template (#10928)
This commit is contained in:
parent
d97b13b5fd
commit
c5999c74c0
1
bin/internal/gradle_wrapper.version
Normal file
1
bin/internal/gradle_wrapper.version
Normal file
|
@ -0,0 +1 @@
|
|||
0b5c1398d1d04ac245a310de98825cb7b3278e2a
|
|
@ -71,10 +71,11 @@ void ensureDirectoryExists(String filePath) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Recursively copies `srcDir` to `destDir`.
|
||||
/// Recursively copies `srcDir` to `destDir`, invoking [onFileCopied] if
|
||||
/// specified for each source/destination file pair.
|
||||
///
|
||||
/// Creates `destDir` if needed.
|
||||
void copyDirectorySync(Directory srcDir, Directory destDir) {
|
||||
void copyDirectorySync(Directory srcDir, Directory destDir, [void onFileCopied(File srcFile, File destFile)]) {
|
||||
if (!srcDir.existsSync())
|
||||
throw new Exception('Source directory "${srcDir.path}" does not exist, nothing to copy');
|
||||
|
||||
|
@ -86,6 +87,7 @@ void copyDirectorySync(Directory srcDir, Directory destDir) {
|
|||
if (entity is File) {
|
||||
final File newFile = destDir.fileSystem.file(newPath);
|
||||
newFile.writeAsBytesSync(entity.readAsBytesSync());
|
||||
onFileCopied?.call(entity, newFile);
|
||||
} else if (entity is Directory) {
|
||||
copyDirectorySync(
|
||||
entity, destDir.fileSystem.directory(newPath));
|
||||
|
|
|
@ -47,6 +47,8 @@ abstract class OperatingSystemUtils {
|
|||
|
||||
void unzip(File file, Directory targetDirectory);
|
||||
|
||||
void unpack(File gzippedTarFile, Directory targetDirectory);
|
||||
|
||||
/// Returns a pretty name string for the current operating system.
|
||||
///
|
||||
/// If available, the detailed version of the OS is included.
|
||||
|
@ -97,6 +99,12 @@ class _PosixUtils extends OperatingSystemUtils {
|
|||
runSync(<String>['unzip', '-o', '-q', file.path, '-d', targetDirectory.path]);
|
||||
}
|
||||
|
||||
// tar -xzf tarball -C dest
|
||||
@override
|
||||
void unpack(File gzippedTarFile, Directory targetDirectory) {
|
||||
runSync(<String>['tar', '-xzf', gzippedTarFile.path, '-C', targetDirectory.path]);
|
||||
}
|
||||
|
||||
@override
|
||||
File makePipe(String path) {
|
||||
runSync(<String>['mkfifo', path]);
|
||||
|
@ -167,7 +175,18 @@ class _WindowsUtils extends OperatingSystemUtils {
|
|||
@override
|
||||
void unzip(File file, Directory targetDirectory) {
|
||||
final Archive archive = new ZipDecoder().decodeBytes(file.readAsBytesSync());
|
||||
_unpackArchive(archive, targetDirectory);
|
||||
}
|
||||
|
||||
@override
|
||||
void unpack(File gzippedTarFile, Directory targetDirectory) {
|
||||
final Archive archive = new TarDecoder().decodeBytes(
|
||||
new GZipDecoder().decodeBytes(gzippedTarFile.readAsBytesSync()),
|
||||
);
|
||||
_unpackArchive(archive, targetDirectory);
|
||||
}
|
||||
|
||||
void _unpackArchive(Archive archive, Directory targetDirectory) {
|
||||
for (ArchiveFile archiveFile in archive.files) {
|
||||
// The archive package doesn't correctly set isFile.
|
||||
if (!archiveFile.isFile || archiveFile.name.endsWith('/'))
|
||||
|
|
|
@ -17,9 +17,19 @@ import 'globals.dart';
|
|||
/// A wrapper around the `bin/cache/` directory.
|
||||
class Cache {
|
||||
/// [rootOverride] is configurable for testing.
|
||||
Cache({ Directory rootOverride }) : _rootOverride = rootOverride;
|
||||
/// [artifacts] is configurable for testing.
|
||||
Cache({ Directory rootOverride, List<CachedArtifact> artifacts }) : _rootOverride = rootOverride {
|
||||
if (artifacts == null) {
|
||||
_artifacts.add(new MaterialFonts(this));
|
||||
_artifacts.add(new FlutterEngine(this));
|
||||
_artifacts.add(new GradleWrapper(this));
|
||||
} else {
|
||||
_artifacts.addAll(artifacts);
|
||||
}
|
||||
}
|
||||
|
||||
final Directory _rootOverride;
|
||||
final List<CachedArtifact> _artifacts = <CachedArtifact>[];
|
||||
|
||||
// Initialized by FlutterCommandRunner on startup.
|
||||
static String flutterRoot;
|
||||
|
@ -155,16 +165,9 @@ class Cache {
|
|||
return fs.file(fs.path.join(getRoot().path, '$artifactName.stamp'));
|
||||
}
|
||||
|
||||
bool isUpToDate() {
|
||||
final MaterialFonts materialFonts = new MaterialFonts(cache);
|
||||
final FlutterEngine engine = new FlutterEngine(cache);
|
||||
bool isUpToDate() => _artifacts.every((CachedArtifact artifact) => artifact.isUpToDate());
|
||||
|
||||
return materialFonts.isUpToDate() && engine.isUpToDate();
|
||||
}
|
||||
|
||||
Future<String> getThirdPartyFile(String urlStr, String serviceName, {
|
||||
bool unzip: false
|
||||
}) async {
|
||||
Future<String> getThirdPartyFile(String urlStr, String serviceName) async {
|
||||
final Uri url = Uri.parse(urlStr);
|
||||
final Directory thirdPartyDir = getArtifactDirectory('third_party');
|
||||
|
||||
|
@ -175,7 +178,7 @@ class Cache {
|
|||
final File cachedFile = fs.file(fs.path.join(serviceDir.path, url.pathSegments.last));
|
||||
if (!cachedFile.existsSync()) {
|
||||
try {
|
||||
await _downloadFileToCache(url, cachedFile, unzip);
|
||||
await _downloadFile(url, cachedFile);
|
||||
} catch (e) {
|
||||
printError('Failed to fetch third-party artifact $url: $e');
|
||||
rethrow;
|
||||
|
@ -188,77 +191,65 @@ class Cache {
|
|||
Future<Null> updateAll() async {
|
||||
if (!_lockEnabled)
|
||||
return null;
|
||||
final MaterialFonts materialFonts = new MaterialFonts(cache);
|
||||
if (!materialFonts.isUpToDate())
|
||||
await materialFonts.download();
|
||||
|
||||
final FlutterEngine engine = new FlutterEngine(cache);
|
||||
if (!engine.isUpToDate())
|
||||
await engine.download();
|
||||
}
|
||||
|
||||
/// Download a file from the given url and write it to the cache.
|
||||
/// If [unzip] is true, treat the url as a zip file, and unzip it to the
|
||||
/// directory given.
|
||||
static Future<Null> _downloadFileToCache(Uri url, FileSystemEntity location, bool unzip) async {
|
||||
if (!location.parent.existsSync())
|
||||
location.parent.createSync(recursive: true);
|
||||
|
||||
final List<int> fileBytes = await fetchUrl(url);
|
||||
if (unzip) {
|
||||
if (location is Directory && !location.existsSync())
|
||||
location.createSync(recursive: true);
|
||||
|
||||
final File tempFile = fs.file(fs.path.join(fs.systemTempDirectory.path, '${url.toString().hashCode}.zip'));
|
||||
tempFile.writeAsBytesSync(fileBytes, flush: true);
|
||||
os.unzip(tempFile, location);
|
||||
tempFile.deleteSync();
|
||||
} else {
|
||||
final File file = location;
|
||||
file.writeAsBytesSync(fileBytes, flush: true);
|
||||
for (CachedArtifact artifact in _artifacts) {
|
||||
if (!artifact.isUpToDate())
|
||||
await artifact.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MaterialFonts {
|
||||
MaterialFonts(this.cache);
|
||||
|
||||
static const String kName = 'material_fonts';
|
||||
/// An artifact managed by the cache.
|
||||
abstract class CachedArtifact {
|
||||
CachedArtifact(this.name, this.cache);
|
||||
|
||||
final String name;
|
||||
final Cache cache;
|
||||
|
||||
Directory get location => cache.getArtifactDirectory(name);
|
||||
String get version => cache.getVersionFor(name);
|
||||
|
||||
bool isUpToDate() {
|
||||
if (!cache.getArtifactDirectory(kName).existsSync())
|
||||
if (!location.existsSync())
|
||||
return false;
|
||||
return cache.getVersionFor(kName) == cache.getStampFor(kName);
|
||||
if (version != cache.getStampFor(name))
|
||||
return false;
|
||||
return isUpToDateInner();
|
||||
}
|
||||
|
||||
Future<Null> download() {
|
||||
Future<Null> update() async {
|
||||
if (location.existsSync())
|
||||
location.deleteSync(recursive: true);
|
||||
location.createSync(recursive: true);
|
||||
return updateInner().then<Null>((_) {
|
||||
cache.setStampFor(name, version);
|
||||
});
|
||||
}
|
||||
|
||||
/// Hook method for extra checks for being up-to-date.
|
||||
bool isUpToDateInner() => true;
|
||||
|
||||
/// Template method to perform artifact update.
|
||||
Future<Null> updateInner();
|
||||
}
|
||||
|
||||
/// A cached artifact containing fonts used for Material Design.
|
||||
class MaterialFonts extends CachedArtifact {
|
||||
MaterialFonts(Cache cache): super('material_fonts', cache);
|
||||
|
||||
@override
|
||||
Future<Null> updateInner() {
|
||||
final Status status = logger.startProgress('Downloading Material fonts...', expectSlowOperation: true);
|
||||
|
||||
final Directory fontsDir = cache.getArtifactDirectory(kName);
|
||||
if (fontsDir.existsSync())
|
||||
fontsDir.deleteSync(recursive: true);
|
||||
|
||||
return Cache._downloadFileToCache(
|
||||
Uri.parse(cache.getVersionFor(kName)), fontsDir, true
|
||||
).then<Null>((Null value) {
|
||||
cache.setStampFor(kName, cache.getVersionFor(kName));
|
||||
return _downloadZipArchive(Uri.parse(version), location).then<Null>((_) {
|
||||
status.stop();
|
||||
}).whenComplete(status.cancel);
|
||||
}
|
||||
}
|
||||
|
||||
class FlutterEngine {
|
||||
/// A cached artifact containing the Flutter engine binaries.
|
||||
class FlutterEngine extends CachedArtifact {
|
||||
FlutterEngine(Cache cache): super('engine', cache);
|
||||
|
||||
FlutterEngine(this.cache);
|
||||
|
||||
static const String kName = 'engine';
|
||||
static const String kSkyEngine = 'sky_engine';
|
||||
|
||||
final Cache cache;
|
||||
|
||||
List<String> _getPackageDirs() => const <String>[kSkyEngine];
|
||||
List<String> _getPackageDirs() => const <String>['sky_engine'];
|
||||
|
||||
// Return a list of (cache directory path, download URL path) tuples.
|
||||
List<List<String>> _getBinaryDirs() {
|
||||
|
@ -320,7 +311,8 @@ class FlutterEngine {
|
|||
<String>['ios-release', 'ios-release/artifacts.zip'],
|
||||
];
|
||||
|
||||
bool isUpToDate() {
|
||||
@override
|
||||
bool isUpToDateInner() {
|
||||
final Directory pkgDir = cache.getCacheDir('pkg');
|
||||
for (String pkgName in _getPackageDirs()) {
|
||||
final String pkgPath = fs.path.join(pkgDir.path, pkgName);
|
||||
|
@ -328,19 +320,17 @@ class FlutterEngine {
|
|||
return false;
|
||||
}
|
||||
|
||||
final Directory engineDir = cache.getArtifactDirectory(kName);
|
||||
for (List<String> toolsDir in _getBinaryDirs()) {
|
||||
final Directory dir = fs.directory(fs.path.join(engineDir.path, toolsDir[0]));
|
||||
final Directory dir = fs.directory(fs.path.join(location.path, toolsDir[0]));
|
||||
if (!dir.existsSync())
|
||||
return false;
|
||||
}
|
||||
|
||||
return cache.getVersionFor(kName) == cache.getStampFor(kName);
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<Null> download() async {
|
||||
final String engineVersion = cache.getVersionFor(kName);
|
||||
final String url = 'https://storage.googleapis.com/flutter_infra/flutter/$engineVersion/';
|
||||
@override
|
||||
Future<Null> updateInner() async {
|
||||
final String url = 'https://storage.googleapis.com/flutter_infra/flutter/$version/';
|
||||
|
||||
final Directory pkgDir = cache.getCacheDir('pkg');
|
||||
for (String pkgName in _getPackageDirs()) {
|
||||
|
@ -351,14 +341,10 @@ class FlutterEngine {
|
|||
await _downloadItem('Downloading package $pkgName...', url + pkgName + '.zip', pkgDir);
|
||||
}
|
||||
|
||||
final Directory engineDir = cache.getArtifactDirectory(kName);
|
||||
if (engineDir.existsSync())
|
||||
engineDir.deleteSync(recursive: true);
|
||||
|
||||
for (List<String> toolsDir in _getBinaryDirs()) {
|
||||
final String cacheDir = toolsDir[0];
|
||||
final String urlPath = toolsDir[1];
|
||||
final Directory dir = fs.directory(fs.path.join(engineDir.path, cacheDir));
|
||||
final Directory dir = fs.directory(fs.path.join(location.path, cacheDir));
|
||||
await _downloadItem('Downloading $cacheDir tools...', url + urlPath, dir);
|
||||
|
||||
_makeFilesExecutable(dir);
|
||||
|
@ -370,8 +356,6 @@ class FlutterEngine {
|
|||
os.unzip(frameworkZip, framework);
|
||||
}
|
||||
}
|
||||
|
||||
cache.setStampFor(kName, cache.getVersionFor(kName));
|
||||
}
|
||||
|
||||
void _makeFilesExecutable(Directory dir) {
|
||||
|
@ -386,8 +370,68 @@ class FlutterEngine {
|
|||
|
||||
Future<Null> _downloadItem(String message, String url, Directory dest) {
|
||||
final Status status = logger.startProgress(message, expectSlowOperation: true);
|
||||
return Cache._downloadFileToCache(Uri.parse(url), dest, true).then<Null>((Null value) {
|
||||
return _downloadZipArchive(Uri.parse(url), dest).then<Null>((_) {
|
||||
status.stop();
|
||||
}).whenComplete(status.cancel);
|
||||
}
|
||||
}
|
||||
|
||||
/// A cached artifact containing Gradle Wrapper scripts and binaries.
|
||||
class GradleWrapper extends CachedArtifact {
|
||||
GradleWrapper(Cache cache): super('gradle_wrapper', cache);
|
||||
|
||||
@override
|
||||
Future<Null> updateInner() async {
|
||||
final Status status = logger.startProgress('Downloading Gradle Wrapper...', expectSlowOperation: true);
|
||||
|
||||
final String url = 'https://android.googlesource.com'
|
||||
'/platform/tools/base/+archive/$version/templates/gradle/wrapper.tgz';
|
||||
await _downloadZippedTarball(Uri.parse(url), location).then<Null>((_) {
|
||||
// Delete property file, allowing templates to provide it.
|
||||
fs.file(fs.path.join(location.path, 'gradle', 'wrapper', 'gradle-wrapper.properties')).deleteSync();
|
||||
status.stop();
|
||||
}).whenComplete(status.cancel);
|
||||
}
|
||||
}
|
||||
|
||||
/// Download a file from the given [url] and write it to [location].
|
||||
Future<Null> _downloadFile(Uri url, File location) async {
|
||||
_ensureExists(location.parent);
|
||||
final List<int> fileBytes = await fetchUrl(url);
|
||||
location.writeAsBytesSync(fileBytes, flush: true);
|
||||
}
|
||||
|
||||
/// Download a zip archive from the given [url] and unzip it to [location].
|
||||
Future<Null> _downloadZipArchive(Uri url, Directory location) {
|
||||
return _withTemporaryFile('download.zip', (File tempFile) async {
|
||||
await _downloadFile(url, tempFile);
|
||||
_ensureExists(location);
|
||||
os.unzip(tempFile, location);
|
||||
});
|
||||
}
|
||||
|
||||
/// Download a gzipped tarball from the given [url] and unpack it to [location].
|
||||
Future<Null> _downloadZippedTarball(Uri url, Directory location) {
|
||||
return _withTemporaryFile('download.tgz', (File tempFile) async {
|
||||
await _downloadFile(url, tempFile);
|
||||
_ensureExists(location);
|
||||
os.unpack(tempFile, location);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a file with the given name in a new temporary directory, invoke
|
||||
/// [onTemporaryFile] with the file as argument, then delete the temporary
|
||||
/// directory.
|
||||
Future<Null> _withTemporaryFile(String name, Future<Null> onTemporaryFile(File file)) async {
|
||||
final Directory tempDir = fs.systemTempDirectory.createTempSync();
|
||||
final File tempFile = fs.file(fs.path.join(tempDir.path, name));
|
||||
await onTemporaryFile(tempFile).whenComplete(() {
|
||||
tempDir.delete(recursive: true);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create the given [directory] and parents, as necessary.
|
||||
void _ensureExists(Directory directory) {
|
||||
if (!directory.existsSync())
|
||||
directory.createSync(recursive: true);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import '../android/android_sdk.dart' as android_sdk;
|
|||
import '../android/gradle.dart' as gradle;
|
||||
import '../base/common.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/os.dart';
|
||||
import '../base/utils.dart';
|
||||
import '../build_info.dart';
|
||||
import '../cache.dart';
|
||||
|
@ -167,6 +168,10 @@ class CreateCommand extends FlutterCommand {
|
|||
}
|
||||
|
||||
generatedCount += _renderTemplate('create', appPath, templateContext);
|
||||
generatedCount += _injectGradleWrapper(appPath);
|
||||
if (appPath != dirPath) {
|
||||
generatedCount += _injectGradleWrapper(dirPath);
|
||||
}
|
||||
if (argResults['with-driver-test']) {
|
||||
final String testPath = fs.path.join(appPath, 'test_driver');
|
||||
generatedCount += _renderTemplate('driver', testPath, templateContext);
|
||||
|
@ -272,6 +277,22 @@ To edit platform code in an IDE see https://flutter.io/platform-plugins/#edit-co
|
|||
final Template template = new Template.fromName(templateName);
|
||||
return template.render(fs.directory(dirPath), context, overwriteExisting: false);
|
||||
}
|
||||
|
||||
int _injectGradleWrapper(String projectDir) {
|
||||
int filesCreated = 0;
|
||||
copyDirectorySync(
|
||||
cache.getArtifactDirectory('gradle_wrapper'),
|
||||
fs.directory(fs.path.join(projectDir, 'android')),
|
||||
(File sourceFile, File destinationFile) {
|
||||
filesCreated++;
|
||||
final String modes = sourceFile.statSync().modeString();
|
||||
if (modes != null && modes.contains('x')) {
|
||||
os.makeExecutable(destinationFile);
|
||||
}
|
||||
},
|
||||
);
|
||||
return filesCreated;
|
||||
}
|
||||
}
|
||||
|
||||
String _createAndroidIdentifier(String organization, String name) {
|
||||
|
|
|
@ -69,20 +69,18 @@ Future<Null> parseServiceConfigs(
|
|||
|
||||
if (jars != null && serviceConfig['jars'] is Iterable) {
|
||||
for (String jar in serviceConfig['jars'])
|
||||
jars.add(fs.file(await getServiceFromUrl(jar, serviceRoot, service, unzip: false)));
|
||||
jars.add(fs.file(await getServiceFromUrl(jar, serviceRoot, service)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> getServiceFromUrl(
|
||||
String url, String rootDir, String serviceName, { bool unzip: false }
|
||||
) async {
|
||||
Future<String> getServiceFromUrl(String url, String rootDir, String serviceName) async {
|
||||
if (url.startsWith("android-sdk:") && androidSdk != null) {
|
||||
// It's something shipped in the standard android SDK.
|
||||
return url.replaceAll('android-sdk:', '${androidSdk.directory}/');
|
||||
} else if (url.startsWith("http")) {
|
||||
// It's a regular file to download.
|
||||
return await cache.getThirdPartyFile(url, serviceName, unzip: unzip);
|
||||
return await cache.getThirdPartyFile(url, serviceName);
|
||||
} else {
|
||||
// Assume url is a path relative to the service's root dir.
|
||||
return fs.path.join(rootDir, url);
|
||||
|
|
|
@ -4,7 +4,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,3 @@ subprojects {
|
|||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.14.1'
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.2-4'
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,3 @@ subprojects {
|
|||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.14.1'
|
||||
}
|
||||
|
|
|
@ -7,7 +7,3 @@
|
|||
/build
|
||||
/captures
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
/gradle
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||
classpath 'com.android.tools.build:gradle:2.3.3'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,3 @@
|
|||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
|
||||
/gradle
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#Fri Jun 23 08:50:38 CEST 2017
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
|
@ -48,6 +48,34 @@ void main() {
|
|||
Platform: () => new FakePlatform()..environment = <String, String>{'FLUTTER_ALREADY_LOCKED': 'true'},
|
||||
});
|
||||
});
|
||||
group('Cache', () {
|
||||
test('should not be up to date, if some cached artifact is not', () {
|
||||
final CachedArtifact artifact1 = new MockCachedArtifact();
|
||||
final CachedArtifact artifact2 = new MockCachedArtifact();
|
||||
when(artifact1.isUpToDate()).thenReturn(true);
|
||||
when(artifact2.isUpToDate()).thenReturn(false);
|
||||
final Cache cache = new Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
||||
expect(cache.isUpToDate(), isFalse);
|
||||
});
|
||||
test('should be up to date, if all cached artifacts are', () {
|
||||
final CachedArtifact artifact1 = new MockCachedArtifact();
|
||||
final CachedArtifact artifact2 = new MockCachedArtifact();
|
||||
when(artifact1.isUpToDate()).thenReturn(true);
|
||||
when(artifact2.isUpToDate()).thenReturn(true);
|
||||
final Cache cache = new Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
||||
expect(cache.isUpToDate(), isTrue);
|
||||
});
|
||||
test('should update cached artifacts which are not up to date', () async {
|
||||
final CachedArtifact artifact1 = new MockCachedArtifact();
|
||||
final CachedArtifact artifact2 = new MockCachedArtifact();
|
||||
when(artifact1.isUpToDate()).thenReturn(true);
|
||||
when(artifact2.isUpToDate()).thenReturn(false);
|
||||
final Cache cache = new Cache(artifacts: <CachedArtifact>[artifact1, artifact2]);
|
||||
await cache.updateAll();
|
||||
verifyNever(artifact1.update());
|
||||
verify(artifact2.update());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockFileSystem extends MemoryFileSystem {
|
||||
|
@ -65,3 +93,4 @@ class MockFile extends Mock implements File {
|
|||
}
|
||||
|
||||
class MockRandomAccessFile extends Mock implements RandomAccessFile {}
|
||||
class MockCachedArtifact extends Mock implements CachedArtifact {}
|
||||
|
|
Loading…
Reference in a new issue