Unverified Commit da23eae3 authored by Daco Harkes's avatar Daco Harkes Committed by GitHub

[native assets] Tool exit on build failure (#137995)

If the native assets feature is enabled, and the `build.dart` invocation fails, the `flutter build` and `flutter run` should abort.

Closes: https://github.com/flutter/flutter/issues/137910
parent 5a6a3224
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:native_assets_builder/native_assets_builder.dart' show BuildResult; import 'package:native_assets_builder/native_assets_builder.dart'
show BuildResult, DryRunResult;
import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode; import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode;
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
...@@ -48,13 +49,14 @@ Future<Iterable<Asset>> dryRunNativeAssetsIOSInternal( ...@@ -48,13 +49,14 @@ Future<Iterable<Asset>> dryRunNativeAssetsIOSInternal(
) async { ) async {
const OS targetOS = OS.iOS; const OS targetOS = OS.iOS;
globals.logger.printTrace('Dry running native assets for $targetOS.'); globals.logger.printTrace('Dry running native assets for $targetOS.');
final List<Asset> nativeAssets = (await buildRunner.dryRun( final DryRunResult dryRunResult = await buildRunner.dryRun(
linkModePreference: LinkModePreference.dynamic, linkModePreference: LinkModePreference.dynamic,
targetOS: targetOS, targetOS: targetOS,
workingDirectory: projectUri, workingDirectory: projectUri,
includeParentEnvironment: true, includeParentEnvironment: true,
)) );
.assets; ensureNativeAssetsBuildSucceed(dryRunResult);
final List<Asset> nativeAssets = dryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets); ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.'); globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Iterable<Asset> assetTargetLocations = _assetTargetLocations(nativeAssets).values; final Iterable<Asset> assetTargetLocations = _assetTargetLocations(nativeAssets).values;
...@@ -97,6 +99,7 @@ Future<List<Uri>> buildNativeAssetsIOS({ ...@@ -97,6 +99,7 @@ Future<List<Uri>> buildNativeAssetsIOS({
includeParentEnvironment: true, includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig, cCompilerConfig: await buildRunner.cCompilerConfig,
); );
ensureNativeAssetsBuildSucceed(result);
nativeAssets.addAll(result.assets); nativeAssets.addAll(result.assets);
dependencies.addAll(result.dependencies); dependencies.addAll(result.dependencies);
} }
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:native_assets_builder/native_assets_builder.dart' show BuildResult; import 'package:native_assets_builder/native_assets_builder.dart'
show BuildResult, DryRunResult;
import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode; import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode;
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli; import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
...@@ -43,13 +44,14 @@ Future<Iterable<Asset>> dryRunNativeAssetsMacOSInternal( ...@@ -43,13 +44,14 @@ Future<Iterable<Asset>> dryRunNativeAssetsMacOSInternal(
final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS);
globals.logger.printTrace('Dry running native assets for $targetOS.'); globals.logger.printTrace('Dry running native assets for $targetOS.');
final List<Asset> nativeAssets = (await buildRunner.dryRun( final DryRunResult dryRunResult = await buildRunner.dryRun(
linkModePreference: LinkModePreference.dynamic, linkModePreference: LinkModePreference.dynamic,
targetOS: targetOS, targetOS: targetOS,
workingDirectory: projectUri, workingDirectory: projectUri,
includeParentEnvironment: true, includeParentEnvironment: true,
)) );
.assets; ensureNativeAssetsBuildSucceed(dryRunResult);
final List<Asset> nativeAssets = dryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets); ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.'); globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Uri? absolutePath = flutterTester ? buildUri : null; final Uri? absolutePath = flutterTester ? buildUri : null;
...@@ -97,6 +99,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsMacOS({ ...@@ -97,6 +99,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsMacOS({
includeParentEnvironment: true, includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig, cCompilerConfig: await buildRunner.cCompilerConfig,
); );
ensureNativeAssetsBuildSucceed(result);
nativeAssets.addAll(result.assets); nativeAssets.addAll(result.assets);
dependencies.addAll(result.dependencies); dependencies.addAll(result.dependencies);
} }
......
...@@ -487,13 +487,15 @@ Future<Iterable<Asset>> dryRunNativeAssetsSingleArchitectureInternal( ...@@ -487,13 +487,15 @@ Future<Iterable<Asset>> dryRunNativeAssetsSingleArchitectureInternal(
final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS); final Uri buildUri = nativeAssetsBuildUri(projectUri, targetOS);
globals.logger.printTrace('Dry running native assets for $targetOS.'); globals.logger.printTrace('Dry running native assets for $targetOS.');
final List<Asset> nativeAssets = (await buildRunner.dryRun(
final DryRunResult dryRunResult = await buildRunner.dryRun(
linkModePreference: LinkModePreference.dynamic, linkModePreference: LinkModePreference.dynamic,
targetOS: targetOS, targetOS: targetOS,
workingDirectory: projectUri, workingDirectory: projectUri,
includeParentEnvironment: true, includeParentEnvironment: true,
)) );
.assets; ensureNativeAssetsBuildSucceed(dryRunResult);
final List<Asset> nativeAssets = dryRunResult.assets;
ensureNoLinkModeStatic(nativeAssets); ensureNoLinkModeStatic(nativeAssets);
globals.logger.printTrace('Dry running native assets for $targetOS done.'); globals.logger.printTrace('Dry running native assets for $targetOS done.');
final Uri? absolutePath = flutterTester ? buildUri : null; final Uri? absolutePath = flutterTester ? buildUri : null;
...@@ -549,6 +551,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsSingleA ...@@ -549,6 +551,7 @@ Future<(Uri? nativeAssetsYaml, List<Uri> dependencies)> buildNativeAssetsSingleA
includeParentEnvironment: true, includeParentEnvironment: true,
cCompilerConfig: await buildRunner.cCompilerConfig, cCompilerConfig: await buildRunner.cCompilerConfig,
); );
ensureNativeAssetsBuildSucceed(result);
final List<Asset> nativeAssets = result.assets; final List<Asset> nativeAssets = result.assets;
final Set<Uri> dependencies = result.dependencies.toSet(); final Set<Uri> dependencies = result.dependencies.toSet();
ensureNoLinkModeStatic(nativeAssets); ensureNoLinkModeStatic(nativeAssets);
...@@ -655,3 +658,11 @@ Future<void> _copyNativeAssetsSingleArchitecture( ...@@ -655,3 +658,11 @@ Future<void> _copyNativeAssetsSingleArchitecture(
globals.logger.printTrace('Copying native assets done.'); globals.logger.printTrace('Copying native assets done.');
} }
} }
void ensureNativeAssetsBuildSucceed(DryRunResult result) {
if (!result.success) {
throwToolExit(
'Building native assets failed. See the logs for more details.',
);
}
}
...@@ -285,4 +285,64 @@ void main() { ...@@ -285,4 +285,64 @@ void main() {
exists, exists,
); );
}); });
testUsingContext('Native assets dry run error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => dryRunNativeAssetsIOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
dryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => buildNativeAssetsIOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64],
environmentType: EnvironmentType.simulator,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
} }
...@@ -360,6 +360,65 @@ void main() { ...@@ -360,6 +360,65 @@ void main() {
); );
}); });
testUsingContext('Native assets dry run error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => dryRunNativeAssetsLinux(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
dryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => buildNativeAssetsLinux(
targetPlatform: TargetPlatform.linux_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order // This logic is mocked in the other tests to avoid having test order
// randomization causing issues with what processes are invoked. // randomization causing issues with what processes are invoked.
// Exercise the parsing of the process output in this separate test. // Exercise the parsing of the process output in this separate test.
......
...@@ -365,6 +365,67 @@ void main() { ...@@ -365,6 +365,67 @@ void main() {
); );
}); });
testUsingContext('Native assets dry run error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => dryRunNativeAssetsMacOS(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
dryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => buildNativeAssetsMacOS(
darwinArchs: <DarwinArch>[DarwinArch.arm64],
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order // This logic is mocked in the other tests to avoid having test order
// randomization causing issues with what processes are invoked. // randomization causing issues with what processes are invoked.
// Exercise the parsing of the process output in this separate test. // Exercise the parsing of the process output in this separate test.
......
...@@ -325,6 +325,67 @@ void main() { ...@@ -325,6 +325,67 @@ void main() {
); );
}); });
testUsingContext('Native assets dry run error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => dryRunNativeAssetsWindows(
projectUri: projectUri,
fileSystem: fileSystem,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
dryRunResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
testUsingContext('Native assets build error', overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isNativeAssetsEnabled: true),
ProcessManager: () => FakeProcessManager.empty(),
}, () async {
final File packageConfig =
environment.projectDir.childFile('.dart_tool/package_config.json');
await packageConfig.parent.create();
await packageConfig.create();
expect(
() => buildNativeAssetsWindows(
targetPlatform: TargetPlatform.windows_x64,
projectUri: projectUri,
buildMode: BuildMode.debug,
fileSystem: fileSystem,
yamlParentDirectory: environment.buildDir.uri,
buildRunner: FakeNativeAssetsBuildRunner(
packagesWithNativeAssetsResult: <Package>[
Package('bar', projectUri),
],
buildResult: const FakeNativeAssetsBuilderResult(
success: false,
),
),
),
throwsToolExit(
message:
'Building native assets failed. See the logs for more details.',
),
);
});
// This logic is mocked in the other tests to avoid having test order // This logic is mocked in the other tests to avoid having test order
// randomization causing issues with what processes are invoked. // randomization causing issues with what processes are invoked.
// Exercise the parsing of the process output in this separate test. // Exercise the parsing of the process output in this separate test.
......
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