[pkg/ffi] Add dryRun to native_assets_builder

Adding it to this package means that launchers (flutter_tools) doesn't
have to do the same package graph traversal.

Notable difference with a build: no meta-data is passed through.

Change-Id: I30d8531e08095742bc8b5952bff919b9f85402ea
Cq-Include-Trybots: luci.dart.try:pkg-linux-debug-try,pkg-linux-release-try,pkg-mac-release-arm64-try,pkg-mac-release-try,pkg-win-release-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308881
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Hossein Yousefi <yousefi@google.com>
This commit is contained in:
Daco Harkes 2023-06-14 18:10:15 +00:00 committed by Commit Queue
parent 0abd362a3e
commit 0dfe563696
4 changed files with 145 additions and 4 deletions

2
DEPS
View file

@ -157,7 +157,7 @@ vars = {
"matcher_rev": "7e1011772566a8d1817c725a71f091e2791721c8",
"mime_rev": "24448401f621b9e154d165c900a3c8decd8a23f4",
"mockito_rev": "1d6064adf043d1fce013d2d205a3fdc655c90043",
"native_rev": "2de88135e25577d851c95b04af0ceb74b706f285",
"native_rev": "c80be905f7c35044aaad56369a19619453132c4e",
"package_config_rev": "203de2022af26b3ab2bcec18cc49614d9e502897",
"path_rev": "592505f67d0563f72c933c2ba100ea7d4f3cb873",
"pool_rev": "c6b1b2c22663c084a82c9bfe409c196fb38eea53",

View file

@ -86,6 +86,50 @@ class NativeAssetsBuildRunner {
return assetList;
}
/// [workingDirectory] is expected to contain `.dart_tool`.
///
/// This method is invoked by launchers such as dartdev (for `dart run`) and
/// flutter_tools (for `flutter run` and `flutter build`).
///
/// Completes the future with an error if the build fails.
Future<List<Asset>> dryRun({
required LinkModePreference linkModePreference,
required OS targetOs,
required Uri workingDirectory,
required bool includeParentEnvironment,
}) async {
assert(_metadata.isEmpty);
final packageLayout =
await PackageLayout.fromRootPackageRoot(workingDirectory);
final packagesWithNativeAssets =
await packageLayout.packagesWithNativeAssets;
final planner = await NativeAssetsBuildPlanner.fromRootPackageRoot(
rootPackageRoot: packageLayout.rootPackageRoot,
packagesWithNativeAssets: packagesWithNativeAssets,
dartExecutable: Uri.file(Platform.resolvedExecutable),
);
final plan = planner.plan();
final assetList = <Asset>[];
for (final package in plan) {
final config = await _cliConfigDryRun(
packageName: package.name,
packageRoot: packageLayout.packageRoot(package.name),
targetOs: targetOs,
linkMode: linkModePreference,
buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
);
final assets = await _buildPackage(
config,
packageLayout.packageConfigUri,
workingDirectory,
includeParentEnvironment,
dryRun: true,
);
assetList.addAll(assets);
}
return assetList;
}
Future<List<Asset>> _buildPackageCached(
BuildConfig config,
Uri packageConfigUri,
@ -119,6 +163,7 @@ class NativeAssetsBuildRunner {
packageConfigUri,
workingDirectory,
includeParentEnvironment,
dryRun: false,
);
}
@ -126,8 +171,9 @@ class NativeAssetsBuildRunner {
BuildConfig config,
Uri packageConfigUri,
Uri workingDirectory,
bool includeParentEnvironment,
) async {
bool includeParentEnvironment, {
required bool dryRun,
}) async {
final outDir = config.outDir;
final configFile = outDir.resolve('config.yaml');
final buildDotDart = config.packageRoot.resolve('build.dart');
@ -153,7 +199,9 @@ class NativeAssetsBuildRunner {
throwOnUnexpectedExitCode: true,
);
final buildOutput = await BuildOutput.readFromFile(outDir: outDir);
setMetadata(config.target, config.packageName, buildOutput?.metadata);
if (!dryRun) {
setMetadata(config.target, config.packageName, buildOutput?.metadata);
}
return buildOutput?.assets ?? [];
}
@ -208,6 +256,27 @@ class NativeAssetsBuildRunner {
);
}
static Future<BuildConfig> _cliConfigDryRun({
required String packageName,
required Uri packageRoot,
required OS targetOs,
required LinkModePreference linkMode,
required Uri buildParentDir,
}) async {
final String buildDirName = 'dry_run_${targetOs}_$linkMode';
final outDirUri = buildParentDir.resolve('$buildDirName/');
final outDir = Directory.fromUri(outDirUri);
if (!await outDir.exists()) {
await outDir.create(recursive: true);
}
return BuildConfig.dryRun(
outDir: outDirUri,
packageRoot: packageRoot,
targetOs: targetOs,
linkModePreference: linkMode,
);
}
DependencyMetadata? _metadataForPackage({
required PackageGraph packageGraph,
required String packageName,

View file

@ -0,0 +1,40 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:native_assets_cli/native_assets_cli.dart';
import 'package:test/test.dart';
import '../helpers.dart';
import 'helpers.dart';
const Timeout longTimeout = Timeout(Duration(minutes: 5));
void main(List<String> args) async {
test('dry_run', timeout: longTimeout, () async {
await inTempDir((tempUri) async {
await copyTestProjects(targetUri: tempUri);
final packageUri = tempUri.resolve('native_add/');
await runPubGet(
workingDirectory: packageUri,
logger: logger,
);
final dryRunAssets = (await dryRun(packageUri, logger, dartExecutable))
.where((element) => element.target == Target.current)
.toList();
final buildAssets = await build(packageUri, logger, dartExecutable);
expect(dryRunAssets.length, buildAssets.length);
for (int i = 0; i < dryRunAssets.length; i++) {
final dryRunAsset = dryRunAssets[0];
final buildAsset = buildAssets[0];
expect(dryRunAsset.linkMode, buildAsset.linkMode);
expect(dryRunAsset.name, buildAsset.name);
expect(dryRunAsset.target, buildAsset.target);
// The target folders are different, so the paths are different.
}
});
});
}

View file

@ -60,6 +60,38 @@ Future<List<Asset>> build(
return assets;
}
Future<List<Asset>> dryRun(
Uri packageUri,
Logger logger,
Uri dartExecutable, {
LinkModePreference linkModePreference = LinkModePreference.dynamic,
CCompilerConfig? cCompilerConfig,
bool includeParentEnvironment = true,
List<String>? capturedLogs,
}) async {
StreamSubscription<LogRecord>? subscription;
if (capturedLogs != null) {
subscription =
logger.onRecord.listen((event) => capturedLogs.add(event.message));
}
final assets = await NativeAssetsBuildRunner(
logger: logger,
dartExecutable: dartExecutable,
).dryRun(
linkModePreference: linkModePreference,
targetOs: Target.current.os,
workingDirectory: packageUri,
includeParentEnvironment: includeParentEnvironment,
);
if (subscription != null) {
await subscription.cancel();
}
return assets;
}
Future<void> expectAssetsExist(List<Asset> assets) async {
for (final asset in assets) {
final uri = (asset.path as AssetAbsolutePath).uri;