Skip to content

Commit f9a4e35

Browse files
committed
Merge upstream changes
1 parent c940ac8 commit f9a4e35

File tree

18 files changed

+422
-94
lines changed

18 files changed

+422
-94
lines changed

pkgs/native_assets_builder/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
## 0.2.0-wip
22

3-
- **Breaking change** `NativeAssetsBuildRunner`s method now return an object
3+
- **Breaking change** `NativeAssetsBuildRunner`s methods now return an object
44
([#105](https://github.com/dart-lang/native/issues/105)).
5+
- **Breaking change** `NativeAssetsBuildRunner`s methods now return value now
6+
contains a list of errors instead of it throwing
7+
([#106](https://github.com/dart-lang/native/issues/106)).
58
- Use an `out/` sub directory for building native assets
69
([#98](https://github.com/dart-lang/native/issues/98)).
710
- Check asset ids on having having a package uri with the owning package

pkgs/native_assets_builder/lib/src/build_runner/build_planner.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import 'dart:io';
88
import 'package:graphs/graphs.dart' as graphs;
99
import 'package:package_config/package_config.dart';
1010

11+
import 'build_runner.dart';
12+
1113
class NativeAssetsBuildPlanner {
1214
final PackageGraph packageGraph;
1315
final List<Package> packagesWithNativeAssets;
@@ -42,29 +44,30 @@ class NativeAssetsBuildPlanner {
4244
);
4345
}
4446

45-
List<Package> plan() {
47+
({List<Package> packages, List<NativeAssetsBuilderError> errors}) plan() {
4648
final packageMap = {
4749
for (final package in packagesWithNativeAssets) package.name: package
4850
};
4951
final packagesToBuild = packageMap.keys.toSet();
5052
final stronglyConnectedComponents = packageGraph.computeStrongComponents();
5153
final result = <Package>[];
54+
final errors = <NativeAssetsBuilderError>[];
5255
for (final stronglyConnectedComponent in stronglyConnectedComponents) {
5356
final stronglyConnectedComponentWithNativeAssets = [
5457
for (final packageName in stronglyConnectedComponent)
5558
if (packagesToBuild.contains(packageName)) packageName
5659
];
5760
if (stronglyConnectedComponentWithNativeAssets.length > 1) {
58-
throw Exception(
61+
errors.add(NativeAssetsBuilderError(
5962
'Cyclic dependency for native asset builds in the following '
60-
'packages: $stronglyConnectedComponent.',
61-
);
63+
'packages: $stronglyConnectedComponentWithNativeAssets.',
64+
));
6265
} else if (stronglyConnectedComponentWithNativeAssets.length == 1) {
6366
result.add(
6467
packageMap[stronglyConnectedComponentWithNativeAssets.single]!);
6568
}
6669
}
67-
return result;
70+
return (packages: result, errors: errors);
6871
}
6972
}
7073

pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart

Lines changed: 173 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -55,40 +55,51 @@ class NativeAssetsBuildRunner {
5555
final plan = planner.plan();
5656
final assets = <Asset>[];
5757
final dependencies = <Uri>[];
58+
final errors = <NativeAssetsBuilderError>[];
5859
final metadata = <String, Metadata>{};
59-
for (final package in plan) {
60-
final dependencyMetadata = _metadataForPackage(
61-
packageGraph: planner.packageGraph,
62-
packageName: package.name,
63-
targetMetadata: metadata,
64-
);
65-
final config = await _cliConfig(
66-
packageRoot: packageLayout.packageRoot(package.name),
67-
target: target,
68-
buildMode: buildMode,
69-
linkMode: linkModePreference,
70-
buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
71-
dependencyMetadata: dependencyMetadata,
72-
cCompilerConfig: cCompilerConfig,
73-
targetIOSSdk: targetIOSSdk,
74-
targetAndroidNdkApi: targetAndroidNdkApi,
75-
);
76-
final (packageAssets, packageDependencies, packageMetadata) =
77-
await _buildPackageCached(
78-
config,
79-
packageLayout.packageConfigUri,
80-
workingDirectory,
81-
includeParentEnvironment,
82-
);
83-
assets.addAll(packageAssets);
84-
dependencies.addAll(packageDependencies);
85-
if (packageMetadata != null) {
86-
metadata[config.packageName] = packageMetadata;
60+
if (plan.errors.isNotEmpty) {
61+
errors.addAll(plan.errors);
62+
} else {
63+
for (final package in plan.packages) {
64+
final dependencyMetadata = _metadataForPackage(
65+
packageGraph: planner.packageGraph,
66+
packageName: package.name,
67+
targetMetadata: metadata,
68+
);
69+
final config = await _cliConfig(
70+
packageRoot: packageLayout.packageRoot(package.name),
71+
target: target,
72+
buildMode: buildMode,
73+
linkMode: linkModePreference,
74+
buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
75+
dependencyMetadata: dependencyMetadata,
76+
cCompilerConfig: cCompilerConfig,
77+
targetIOSSdk: targetIOSSdk,
78+
targetAndroidNdkApi: targetAndroidNdkApi,
79+
);
80+
final (
81+
packageAssets,
82+
packageDependencies,
83+
packageMetadata,
84+
packageErrors
85+
) = await _buildPackageCached(
86+
config,
87+
packageLayout.packageConfigUri,
88+
workingDirectory,
89+
includeParentEnvironment,
90+
);
91+
assets.addAll(packageAssets);
92+
dependencies.addAll(packageDependencies);
93+
errors.addAll(packageErrors);
94+
if (packageMetadata != null) {
95+
metadata[config.packageName] = packageMetadata;
96+
}
8797
}
8898
}
8999
return _BuildResultImpl(
90100
assets: assets,
91101
dependencies: dependencies..sort(_uriCompare),
102+
errors: errors,
92103
);
93104
}
94105

@@ -115,29 +126,37 @@ class NativeAssetsBuildRunner {
115126
);
116127
final plan = planner.plan();
117128
final assets = <Asset>[];
118-
for (final package in plan) {
119-
final config = await _cliConfigDryRun(
120-
packageName: package.name,
121-
packageRoot: packageLayout.packageRoot(package.name),
122-
targetOs: targetOs,
123-
linkMode: linkModePreference,
124-
buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
125-
);
126-
final (packageAssets, _, _) = await _buildPackage(
127-
config,
128-
packageLayout.packageConfigUri,
129-
workingDirectory,
130-
includeParentEnvironment,
131-
dryRun: true,
132-
);
133-
assets.addAll(packageAssets);
129+
final errors = <NativeAssetsBuilderError>[];
130+
if (plan.errors.isNotEmpty) {
131+
errors.addAll(plan.errors);
132+
} else {
133+
for (final package in plan.packages) {
134+
final config = await _cliConfigDryRun(
135+
packageName: package.name,
136+
packageRoot: packageLayout.packageRoot(package.name),
137+
targetOs: targetOs,
138+
linkMode: linkModePreference,
139+
buildParentDir: packageLayout.dartToolNativeAssetsBuilder,
140+
);
141+
final (packageAssets, _, _, packageErrors) = await _buildPackage(
142+
config,
143+
packageLayout.packageConfigUri,
144+
workingDirectory,
145+
includeParentEnvironment,
146+
dryRun: true,
147+
);
148+
assets.addAll(packageAssets);
149+
errors.addAll(packageErrors);
150+
}
134151
}
135152
return _DryRunResultImpl(
136153
assets: assets,
154+
errors: errors,
137155
);
138156
}
139157

140-
Future<(List<Asset>, List<Uri>, Metadata?)> _buildPackageCached(
158+
Future<(List<Asset>, List<Uri>, Metadata?, List<NativeAssetsBuilderError>)>
159+
_buildPackageCached(
141160
BuildConfig config,
142161
Uri packageConfigUri,
143162
Uri workingDirectory,
@@ -163,7 +182,7 @@ class NativeAssetsBuildRunner {
163182
final assets = buildOutput!.assets;
164183
final dependencies = buildOutput.dependencies.dependencies;
165184
final metadata = buildOutput.metadata;
166-
return (assets, dependencies, metadata);
185+
return (assets, dependencies, metadata, <NativeAssetsBuilderError>[]);
167186
}
168187

169188
return await _buildPackage(
@@ -175,7 +194,8 @@ class NativeAssetsBuildRunner {
175194
);
176195
}
177196

178-
Future<(List<Asset>, List<Uri>, Metadata?)> _buildPackage(
197+
Future<(List<Asset>, List<Uri>, Metadata?, List<NativeAssetsBuilderError>)>
198+
_buildPackage(
179199
BuildConfig config,
180200
Uri packageConfigUri,
181201
Uri workingDirectory,
@@ -193,25 +213,82 @@ class NativeAssetsBuildRunner {
193213
// Ensure we'll never read outdated build results.
194214
await buildOutputFile.delete();
195215
}
196-
await runProcess(
216+
final arguments = [
217+
'--packages=${packageConfigUri.toFilePath()}',
218+
buildDotDart.toFilePath(),
219+
'--config=${configFile.toFilePath()}',
220+
];
221+
final result = await runProcess(
197222
workingDirectory: workingDirectory,
198223
executable: dartExecutable,
199-
arguments: [
200-
'--packages=${packageConfigUri.toFilePath()}',
201-
buildDotDart.toFilePath(),
202-
'--config=${configFile.toFilePath()}',
203-
],
224+
arguments: arguments,
204225
logger: logger,
205226
includeParentEnvironment: includeParentEnvironment,
206-
expectedExitCode: 0,
207-
throwOnUnexpectedExitCode: true,
208227
);
209-
final buildOutput = await BuildOutput.readFromFile(outDir: outDir);
210-
final assets = buildOutput?.assets ?? [];
211-
validateAssetsPackage(assets, config.packageName);
212-
final dependencies = buildOutput?.dependencies.dependencies ?? [];
213-
final metadata = dryRun ? null : buildOutput?.metadata;
214-
return (assets, dependencies, metadata);
228+
final errors = <NativeAssetsBuilderError>[];
229+
if (result.exitCode != 0) {
230+
final printWorkingDir = workingDirectory != Directory.current.uri;
231+
final commandString = [
232+
if (printWorkingDir) '(cd ${workingDirectory.toFilePath()};',
233+
dartExecutable.toFilePath(),
234+
...arguments.map((a) => a.contains(' ') ? "'$a'" : a),
235+
if (printWorkingDir) ')',
236+
].join(' ');
237+
errors.add(NativeAssetsBuilderError(
238+
package: config.packageName,
239+
'''Building native assets failed.
240+
build.dart returned with exit code: ${result.exitCode}.
241+
To reproduce run:
242+
$commandString
243+
stderr:
244+
${result.stderr}
245+
stdout:
246+
${result.stdout}
247+
''',
248+
));
249+
}
250+
251+
try {
252+
final buildOutput = await BuildOutput.readFromFile(outDir: outDir);
253+
final assets = buildOutput?.assets ?? [];
254+
errors.addAll(validateAssetsPackage(assets, config.packageName));
255+
final dependencies = buildOutput?.dependencies.dependencies ?? [];
256+
final metadata = dryRun ? null : buildOutput?.metadata;
257+
return (assets, dependencies, metadata, errors);
258+
} on FormatException catch (e) {
259+
return (
260+
<Asset>[],
261+
<Uri>[],
262+
null,
263+
[
264+
NativeAssetsBuilderError(
265+
package: config.packageName,
266+
'''Building native assets failed.
267+
build_output.yaml contained a format error.
268+
${e.message}
269+
''',
270+
),
271+
],
272+
);
273+
// TODO(https://github.com/dart-lang/native/issues/109): Stop throwing
274+
// type errors in native_assets_cli, release a new version of that package
275+
// and then remove this.
276+
// ignore: avoid_catching_errors
277+
} on TypeError {
278+
return (
279+
<Asset>[],
280+
<Uri>[],
281+
null,
282+
[
283+
NativeAssetsBuilderError(
284+
package: config.packageName,
285+
'''Building native assets failed.
286+
build_output.yaml contained a format error.
287+
''',
288+
),
289+
],
290+
);
291+
}
215292
}
216293

217294
static Future<BuildConfig> _cliConfig({
@@ -292,33 +369,44 @@ class NativeAssetsBuildRunner {
292369
};
293370
}
294371

295-
void validateAssetsPackage(List<Asset> assets, String packageName) {
372+
List<NativeAssetsBuilderError> validateAssetsPackage(
373+
List<Asset> assets, String packageName) {
296374
final invalidAssetIds = assets
297375
.map((a) => a.name)
298376
.where((n) => !n.startsWith('package:$packageName/'))
299377
.toSet()
300378
.toList()
301379
..sort();
302-
if (invalidAssetIds.isNotEmpty) {
303-
throw FormatException(
304-
'`package:$packageName` declares the following assets which do not '
305-
'start with `package:$packageName/`: ${invalidAssetIds.join(', ')}.',
306-
);
307-
}
380+
return [
381+
if (invalidAssetIds.isNotEmpty)
382+
NativeAssetsBuilderError(
383+
'`package:$packageName` declares the following assets which do not '
384+
'start with `package:$packageName/`: ${invalidAssetIds.join(', ')}.',
385+
),
386+
];
308387
}
309388
}
310389

311390
/// The result from a [NativeAssetsBuildRunner.dryRun].
312391
abstract interface class DryRunResult {
313392
/// The native assets for all [Target]s for the build or dry run.
314393
List<Asset> get assets;
394+
395+
/// Any errors
396+
List<NativeAssetsBuilderError> get errors;
315397
}
316398

317399
final class _DryRunResultImpl implements DryRunResult {
318400
@override
319401
final List<Asset> assets;
320402

321-
_DryRunResultImpl({required this.assets});
403+
@override
404+
final List<NativeAssetsBuilderError> errors;
405+
406+
_DryRunResultImpl({
407+
required this.assets,
408+
required this.errors,
409+
});
322410
}
323411

324412
/// The result from a [NativeAssetsBuildRunner.build].
@@ -339,9 +427,25 @@ final class _BuildResultImpl implements BuildResult {
339427
@override
340428
final List<Uri> dependencies;
341429

430+
@override
431+
final List<NativeAssetsBuilderError> errors;
432+
342433
_BuildResultImpl({
343434
required this.assets,
344435
required this.dependencies,
436+
required this.errors,
437+
});
438+
}
439+
440+
final class NativeAssetsBuilderError {
441+
final String message;
442+
443+
/// The package that was being built that caused an error.
444+
final String? package;
445+
446+
NativeAssetsBuilderError(
447+
this.message, {
448+
this.package,
345449
});
346450
}
347451

0 commit comments

Comments
 (0)