Skip to content

Commit e022fea

Browse files
authored
[native_assets_*] Validator (#1507)
1 parent 05cdcbe commit e022fea

20 files changed

+830
-37
lines changed

pkgs/native_assets_builder/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## 0.8.3-wip
22

3-
- Nothing yet.
3+
- Added a validation step on the output of the build and link hooks.
44

55
## 0.8.2
66

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

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ class NativeAssetsBuildRunner {
209209
workingDirectory,
210210
includeParentEnvironment,
211211
resourceIdentifiers,
212+
packageLayout,
212213
);
213214
hookResult = hookResult.copyAdd(hookOutput, packageSuccess);
214215
metadata[config.packageName] = hookOutput.metadata;
@@ -300,6 +301,7 @@ class NativeAssetsBuildRunner {
300301
dependencyMetadata: dependencyMetadata,
301302
linkingEnabled: linkingEnabled,
302303
targetAndroidNdkApi: targetAndroidNdkApi,
304+
supportedAssetTypes: supportedAssetTypes,
303305
);
304306
}
305307
}
@@ -428,6 +430,7 @@ class NativeAssetsBuildRunner {
428430
includeParentEnvironment,
429431
null,
430432
hookKernelFile,
433+
packageLayout!,
431434
),
432435
);
433436
buildOutput = _expandArchsNativeCodeAssets(buildOutput);
@@ -466,6 +469,7 @@ class NativeAssetsBuildRunner {
466469
Uri workingDirectory,
467470
bool includeParentEnvironment,
468471
Uri? resources,
472+
PackageLayout packageLayout,
469473
) async {
470474
final outDir = config.outputDirectory;
471475
return await runUnderDirectoryLock(
@@ -514,6 +518,7 @@ class NativeAssetsBuildRunner {
514518
includeParentEnvironment,
515519
resources,
516520
hookKernelFile,
521+
packageLayout,
517522
);
518523
},
519524
);
@@ -527,6 +532,7 @@ class NativeAssetsBuildRunner {
527532
bool includeParentEnvironment,
528533
Uri? resources,
529534
File hookKernelFile,
535+
PackageLayout packageLayout,
530536
) async {
531537
final configFile = config.outputDirectory.resolve('../config.json');
532538
final configFileContents = config.toJsonString();
@@ -577,20 +583,25 @@ ${result.stdout}
577583
}
578584

579585
try {
580-
final buildOutput = HookOutputImpl.readFromFile(
581-
file: config.outputFile) ??
586+
final output = HookOutputImpl.readFromFile(file: config.outputFile) ??
582587
(config.outputFileV1_1_0 == null
583588
? null
584589
: HookOutputImpl.readFromFile(file: config.outputFileV1_1_0!)) ??
585590
HookOutputImpl();
586-
// The link.dart can pipe through assets from other packages.
587-
if (hook == Hook.build) {
588-
success &= validateAssetsPackage(
589-
buildOutput.assets,
590-
config.packageName,
591-
);
591+
592+
final validateResult = await validate(
593+
config,
594+
output,
595+
packageLayout,
596+
);
597+
success &= validateResult.success;
598+
if (!validateResult.success) {
599+
logger.severe('package:${config.packageName}` has invalid output.');
600+
}
601+
for (final error in validateResult.errors) {
602+
logger.severe('- $error');
592603
}
593-
return (buildOutput, success);
604+
return (output, success);
594605
} on FormatException catch (e) {
595606
logger.severe('''
596607
Building native assets for package:${config.packageName} failed.
@@ -793,22 +804,32 @@ ${compileResult.stdout}
793804
};
794805
}
795806

796-
bool validateAssetsPackage(Iterable<AssetImpl> assets, String packageName) {
797-
final invalidAssetIds = assets
798-
.map((a) => a.id)
799-
.where((id) => !id.startsWith('package:$packageName/'))
800-
.toSet()
801-
.toList()
802-
..sort();
803-
if (invalidAssetIds.isNotEmpty) {
804-
logger.severe(
805-
'`package:$packageName` declares the following assets which do not '
806-
'start with `package:$packageName/`: ${invalidAssetIds.join(', ')}.',
807-
);
808-
return false;
809-
} else {
810-
return true;
807+
Future<ValidateResult> validate(
808+
HookConfigImpl config,
809+
HookOutputImpl output,
810+
PackageLayout packageLayout,
811+
) async {
812+
var (errors: errors, success: success) = config is BuildConfigImpl
813+
? await validateBuild(config, output)
814+
: await validateLink(config as LinkConfigImpl, output);
815+
816+
if (config is BuildConfigImpl) {
817+
final packagesWithLink =
818+
(await packageLayout.packagesWithAssets(Hook.link))
819+
.map((p) => p.name);
820+
for (final targetPackage in output.assetsForLinking.keys) {
821+
if (!packagesWithLink.contains(targetPackage)) {
822+
for (final asset in output.assetsForLinking[targetPackage]!) {
823+
success &= false;
824+
errors.add(
825+
'Asset "${asset.id}" is sent to package "$targetPackage" for'
826+
' linking, but that package does not have a link hook.',
827+
);
828+
}
829+
}
830+
}
811831
}
832+
return (errors: errors, success: success);
812833
}
813834

814835
Future<(List<Package> plan, PackageGraph? dependencyGraph, bool success)>

pkgs/native_assets_builder/test/build_runner/build_runner_asset_id_test.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ void main() async {
3232
expect(result.success, false);
3333
expect(
3434
fullLog,
35-
contains(
36-
'`package:wrong_namespace_asset` declares the following assets '
37-
'which do not start with `package:wrong_namespace_asset/`:',
38-
),
35+
contains('does not start with "package:wrong_namespace_asset/"'),
3936
);
4037
}
4138
});

pkgs/native_assets_builder/test/build_runner/helpers.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Future<BuildResult> build(
4747
int? targetAndroidNdkApi,
4848
Target? target,
4949
bool linkingEnabled = false,
50+
Iterable<String>? supportedAssetTypes,
5051
}) async =>
5152
await runWithLog(capturedLogs, () async {
5253
final result = await NativeAssetsBuildRunner(
@@ -66,6 +67,7 @@ Future<BuildResult> build(
6667
targetMacOSVersion: targetMacOSVersion,
6768
targetAndroidNdkApi: targetAndroidNdkApi,
6869
linkingEnabled: linkingEnabled,
70+
supportedAssetTypes: supportedAssetTypes,
6971
);
7072

7173
if (result.success) {
@@ -94,6 +96,7 @@ Future<LinkResult> link(
9496
int? targetMacOSVersion,
9597
int? targetAndroidNdkApi,
9698
Target? target,
99+
Iterable<String>? supportedAssetTypes,
97100
}) async =>
98101
await runWithLog(capturedLogs, () async {
99102
final result = await NativeAssetsBuildRunner(
@@ -113,6 +116,7 @@ Future<LinkResult> link(
113116
targetIOSVersion: targetIOSVersion,
114117
targetMacOSVersion: targetMacOSVersion,
115118
targetAndroidNdkApi: targetAndroidNdkApi,
119+
supportedAssetTypes: supportedAssetTypes,
116120
);
117121

118122
if (result.success) {
@@ -138,6 +142,7 @@ Future<(BuildResult, LinkResult)> buildAndLink(
138142
int? targetAndroidNdkApi,
139143
Target? target,
140144
Uri? resourceIdentifiers,
145+
Iterable<String>? supportedAssetTypes,
141146
}) async =>
142147
await runWithLog(capturedLogs, () async {
143148
final buildRunner = NativeAssetsBuildRunner(
@@ -158,6 +163,7 @@ Future<(BuildResult, LinkResult)> buildAndLink(
158163
targetMacOSVersion: targetMacOSVersion,
159164
targetAndroidNdkApi: targetAndroidNdkApi,
160165
linkingEnabled: true,
166+
supportedAssetTypes: supportedAssetTypes,
161167
);
162168

163169
if (!buildResult.success) {
@@ -183,6 +189,7 @@ Future<(BuildResult, LinkResult)> buildAndLink(
183189
targetIOSVersion: targetIOSVersion,
184190
targetMacOSVersion: targetMacOSVersion,
185191
targetAndroidNdkApi: targetAndroidNdkApi,
192+
supportedAssetTypes: supportedAssetTypes,
186193
);
187194

188195
if (linkResult.success) {
@@ -221,6 +228,7 @@ Future<BuildDryRunResult> buildDryRun(
221228
List<String>? capturedLogs,
222229
PackageLayout? packageLayout,
223230
required bool linkingEnabled,
231+
Iterable<String>? supportedAssetTypes,
224232
}) async =>
225233
runWithLog(capturedLogs, () async {
226234
final result = await NativeAssetsBuildRunner(
@@ -233,6 +241,7 @@ Future<BuildDryRunResult> buildDryRun(
233241
includeParentEnvironment: includeParentEnvironment,
234242
packageLayout: packageLayout,
235243
linkingEnabled: linkingEnabled,
244+
supportedAssetTypes: supportedAssetTypes,
236245
);
237246
return result;
238247
});
@@ -247,6 +256,7 @@ Future<LinkDryRunResult> linkDryRun(
247256
List<String>? capturedLogs,
248257
PackageLayout? packageLayout,
249258
required BuildDryRunResult buildDryRunResult,
259+
Iterable<String>? supportedAssetTypes,
250260
}) async =>
251261
runWithLog(capturedLogs, () async {
252262
final result = await NativeAssetsBuildRunner(
@@ -259,6 +269,7 @@ Future<LinkDryRunResult> linkDryRun(
259269
includeParentEnvironment: includeParentEnvironment,
260270
packageLayout: packageLayout,
261271
buildDryRunResult: buildDryRunResult,
272+
supportedAssetTypes: supportedAssetTypes,
262273
);
263274
return result;
264275
});

pkgs/native_assets_builder/test/build_runner/link_dry_run_test.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'helpers.dart';
1212
const Timeout longTimeout = Timeout(Duration(minutes: 5));
1313

1414
void main() async {
15+
const supportedAssetTypes = [DataAsset.type];
16+
1517
test(
1618
'simple_link linking',
1719
timeout: longTimeout,
@@ -31,6 +33,7 @@ void main() async {
3133
logger,
3234
dartExecutable,
3335
linkingEnabled: true,
36+
supportedAssetTypes: supportedAssetTypes,
3437
);
3538
expect(buildResult.assets.length, 0);
3639

@@ -39,6 +42,7 @@ void main() async {
3942
logger,
4043
dartExecutable,
4144
buildDryRunResult: buildResult,
45+
supportedAssetTypes: supportedAssetTypes,
4246
);
4347
expect(linkResult.assets.length, 2);
4448
});
@@ -81,6 +85,7 @@ void main() async {
8185
logger,
8286
dartExecutable,
8387
linkingEnabled: true,
88+
supportedAssetTypes: supportedAssetTypes,
8489
);
8590
expect(buildResult.success, true);
8691
expect(
@@ -95,6 +100,7 @@ void main() async {
95100
logger,
96101
dartExecutable,
97102
buildDryRunResult: buildResult,
103+
supportedAssetTypes: supportedAssetTypes,
98104
);
99105
expect(linkResult.success, true);
100106

pkgs/native_assets_builder/test/build_runner/link_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import 'helpers.dart';
1414
const Timeout longTimeout = Timeout(Duration(minutes: 5));
1515

1616
void main() async {
17+
const supportedAssetTypes = [DataAsset.type];
18+
1719
test(
1820
'simple_link linking',
1921
timeout: longTimeout,
@@ -33,6 +35,7 @@ void main() async {
3335
logger,
3436
dartExecutable,
3537
linkingEnabled: true,
38+
supportedAssetTypes: supportedAssetTypes,
3639
);
3740
expect(buildResult.assets.length, 0);
3841

@@ -41,6 +44,7 @@ void main() async {
4144
logger,
4245
dartExecutable,
4346
buildResult: buildResult,
47+
supportedAssetTypes: supportedAssetTypes,
4448
);
4549
expect(linkResult.assets.length, 2);
4650

@@ -49,6 +53,7 @@ void main() async {
4953
logger,
5054
dartExecutable,
5155
linkingEnabled: false,
56+
supportedAssetTypes: supportedAssetTypes,
5257
);
5358
expect(buildNoLinkResult.assets.length, 4);
5459
});
@@ -91,6 +96,7 @@ void main() async {
9196
logger,
9297
dartExecutable,
9398
linkingEnabled: true,
99+
supportedAssetTypes: supportedAssetTypes,
94100
);
95101
expect(buildResult.success, true);
96102
expect(
@@ -105,6 +111,7 @@ void main() async {
105111
logger,
106112
dartExecutable,
107113
buildResult: buildResult,
114+
supportedAssetTypes: supportedAssetTypes,
108115
);
109116
expect(linkResult.success, true);
110117

@@ -129,6 +136,7 @@ void main() async {
129136
logger,
130137
dartExecutable,
131138
linkingEnabled: true,
139+
supportedAssetTypes: supportedAssetTypes,
132140
);
133141
expect(buildResult.assets.length, 0);
134142
expect(buildResult.assetsForLinking.length, 0);
@@ -140,6 +148,7 @@ void main() async {
140148
dartExecutable,
141149
buildResult: buildResult,
142150
capturedLogs: logMessages,
151+
supportedAssetTypes: supportedAssetTypes,
143152
);
144153
expect(linkResult.assets.length, 0);
145154
expect(
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:logging/logging.dart';
6+
import 'package:test/test.dart';
7+
8+
import '../helpers.dart';
9+
import 'helpers.dart';
10+
11+
const Timeout longTimeout = Timeout(Duration(minutes: 5));
12+
13+
void main() async {
14+
test('wrong linker', timeout: longTimeout, () async {
15+
await inTempDir((tempUri) async {
16+
await copyTestProjects(targetUri: tempUri);
17+
final packageUri = tempUri.resolve('wrong_linker/');
18+
19+
await runPubGet(
20+
workingDirectory: packageUri,
21+
logger: logger,
22+
);
23+
24+
{
25+
final logMessages = <String>[];
26+
final result = await build(
27+
packageUri,
28+
createCapturingLogger(logMessages, level: Level.SEVERE),
29+
dartExecutable,
30+
);
31+
final fullLog = logMessages.join('\n');
32+
expect(result.success, false);
33+
expect(
34+
fullLog,
35+
contains('but that package does not have a link hook'),
36+
);
37+
}
38+
});
39+
});
40+
}

pkgs/native_assets_builder/test_data/manifest.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,7 @@
111111
- wrong_build_output_3/pubspec.yaml
112112
- wrong_build_output/hook/build.dart
113113
- wrong_build_output/pubspec.yaml
114+
- wrong_linker/hook/build.dart
115+
- wrong_linker/pubspec.yaml
114116
- wrong_namespace_asset/hook/build.dart
115117
- wrong_namespace_asset/pubspec.yaml

0 commit comments

Comments
 (0)