Unverified Commit 981afe39 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] ensure build fails if asset files are missing (#54233)

Ensure build fails if asset files are missing and that stderr messages are forwarded through Gradle
parent 0a25309f
...@@ -190,6 +190,19 @@ Future<void> main() async { ...@@ -190,6 +190,19 @@ Future<void> main() async {
result); result);
}); });
await runProjectTest((FlutterProject project) async {
section('gradlew assembleDebug forwards stderr');
await project.introducePubspecError();
final ProcessResult result =
await project.resultOfGradleTask('assembleRelease');
if (result.exitCode == 0)
throw failure(
'Gradle did not exit with error as expected', result);
final String output = '${result.stdout}\n${result.stderr}';
if (!output.contains('No file or variants found for asset: lib/gallery/example_code.dart.'))
throw failure(output, result);
});
await runProjectTest((FlutterProject project) async { await runProjectTest((FlutterProject project) async {
section('flutter build apk on build script with error'); section('flutter build apk on build script with error');
await project.introduceError(); await project.introduceError();
......
...@@ -299,6 +299,20 @@ android { ...@@ -299,6 +299,20 @@ android {
await buildScript.writeAsString((await buildScript.readAsString()).replaceAll('buildTypes', 'builTypes')); await buildScript.writeAsString((await buildScript.readAsString()).replaceAll('buildTypes', 'builTypes'));
} }
Future<void> introducePubspecError() async {
final File pubspec = File(
path.join(parent.path, 'hello', 'pubspec.yaml')
);
final String contents = pubspec.readAsStringSync();
final String newContents = contents.replaceFirst('# The following section is specific to Flutter.\nflutter:\n', '''
flutter:
assets:
- lib/gallery/example_code.dart
''');
pubspec.writeAsStringSync(newContents);
}
Future<void> runGradleTask(String task, {List<String> options}) async { Future<void> runGradleTask(String task, {List<String> options}) async {
return _runGradleTask(workingDirectory: androidPath, task: task, options: options); return _runGradleTask(workingDirectory: androidPath, task: task, options: options);
} }
......
...@@ -881,6 +881,7 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -881,6 +881,7 @@ abstract class BaseFlutterTask extends DefaultTask {
ruleNames = targetPlatformValues.collect { "android_aot_bundle_${buildMode}_$it" } ruleNames = targetPlatformValues.collect { "android_aot_bundle_${buildMode}_$it" }
} }
project.exec { project.exec {
logging.captureStandardError LogLevel.ERROR
executable flutterExecutable.absolutePath executable flutterExecutable.absolutePath
workingDir sourceDir workingDir sourceDir
if (localEngine != null) { if (localEngine != null) {
......
...@@ -16,14 +16,19 @@ import 'icon_tree_shaker.dart'; ...@@ -16,14 +16,19 @@ import 'icon_tree_shaker.dart';
/// A helper function to copy an asset bundle into an [environment]'s output /// A helper function to copy an asset bundle into an [environment]'s output
/// directory. /// directory.
/// ///
/// Throws [Exception] if [AssetBundle.build] returns a non-zero exit code.
///
/// Returns a [Depfile] containing all assets used in the build. /// Returns a [Depfile] containing all assets used in the build.
Future<Depfile> copyAssets(Environment environment, Directory outputDirectory) async { Future<Depfile> copyAssets(Environment environment, Directory outputDirectory) async {
final File pubspecFile = environment.projectDir.childFile('pubspec.yaml'); final File pubspecFile = environment.projectDir.childFile('pubspec.yaml');
final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle();
await assetBundle.build( final int resultCode = await assetBundle.build(
manifestPath: pubspecFile.path, manifestPath: pubspecFile.path,
packagesPath: environment.projectDir.childFile('.packages').path, packagesPath: environment.projectDir.childFile('.packages').path,
); );
if (resultCode != 0) {
throw Exception('Failed to bundle asset files.');
}
final Pool pool = Pool(kMaxOpenFiles); final Pool pool = Pool(kMaxOpenFiles);
final List<File> inputs = <File>[ final List<File> inputs = <File>[
// An asset manifest with no assets would have zero inputs if not // An asset manifest with no assets would have zero inputs if not
......
...@@ -97,6 +97,26 @@ flutter: ...@@ -97,6 +97,26 @@ flutter:
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform, Platform: () => platform,
}); });
testUsingContext('Throws exception if pubspec contains missing files', () async {
fileSystem.file('pubspec.yaml')
..createSync()
..writeAsStringSync('''
name: example
flutter:
assets:
- assets/foo/bar2.png
''');
expect(() async => await const CopyAssets().build(environment),
throwsA(isA<Exception>()));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
Platform: () => platform,
});
} }
class MockArtifacts extends Mock implements Artifacts {} class MockArtifacts extends Mock implements Artifacts {}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment