diff --git a/pkgs/native_assets_builder/test_data/wrong_build_output_3/hook/build.dart b/pkgs/native_assets_builder/test_data/wrong_build_output_3/hook/build.dart index 454d60801..1e697f7ab 100644 --- a/pkgs/native_assets_builder/test_data/wrong_build_output_3/hook/build.dart +++ b/pkgs/native_assets_builder/test_data/wrong_build_output_3/hook/build.dart @@ -22,5 +22,5 @@ const _rightContents = '''{ "encodedAssets": [], "dependencies": [], "metadata": {}, - "version": "1.6.0" + "version": "1.7.0" }'''; diff --git a/pkgs/native_assets_cli/lib/src/code_assets/config.dart b/pkgs/native_assets_cli/lib/src/code_assets/config.dart index f7a790439..b6d5ddd66 100644 --- a/pkgs/native_assets_cli/lib/src/code_assets/config.dart +++ b/pkgs/native_assets_cli/lib/src/code_assets/config.dart @@ -68,14 +68,22 @@ class CodeConfig { factory CodeConfig.fromJson(Map json) { final dryRun = json.getOptional(_dryRunConfigKey) ?? false; - final linkModePreference = - LinkModePreference.fromString(json.string(_linkModePreferenceKey)); + final linkModePreference = LinkModePreference.fromString( + json.code?.optionalString(_linkModePreferenceKey) ?? + json.string(_linkModePreferenceKey), + ); final targetArchitecture = dryRun ? null - : Architecture.fromString(json.string(_targetArchitectureKey, - validValues: Architecture.values.map((a) => a.name))); - final targetOS = OS.fromString(json.string(_targetOSConfigKey)); - final cCompiler = switch (json.optionalMap(_compilerKey)) { + : Architecture.fromString(json.code?.optionalString( + _targetArchitectureKey, + validValues: Architecture.values.map((a) => a.name)) ?? + json.string(_targetArchitectureKey, + validValues: Architecture.values.map((a) => a.name))); + final targetOS = OS.fromString( + json.code?.optionalString(_targetOSConfigKey) ?? + json.string(_targetOSConfigKey)); + final cCompiler = switch (json.code?.optionalMap(_compilerKey) ?? + json.optionalMap(_compilerKey)) { final Map map => CCompilerConfig.fromJson(map), null => null }; @@ -151,8 +159,12 @@ class IOSConfig { _targetVersion = targetVersion; IOSConfig.fromJson(Map json) - : _targetVersion = json.optionalInt(_targetIOSVersionKey), - _targetSdk = switch (json.optionalString(_targetIOSSdkKey)) { + : _targetVersion = + json.code?.optionalMap(_iosKey)?.optionalInt(_targetVersionKey) ?? + json.optionalInt(_targetIOSVersionKeyDeprecated), + _targetSdk = switch ( + json.code?.optionalMap(_iosKey)?.optionalString(_targetSdkKey) ?? + json.optionalString(_targetIOSSdkKeyDeprecated)) { null => null, String e => IOSSdk.fromString(e) }; @@ -176,7 +188,10 @@ class AndroidConfig { }) : _targetNdkApi = targetNdkApi; AndroidConfig.fromJson(Map json) - : _targetNdkApi = json.optionalInt(_targetAndroidNdkApiKey); + : _targetNdkApi = json.code + ?.optionalMap(_androidKey) + ?.optionalInt(_targetNdkApiKey) ?? + json.optionalInt(_targetAndroidNdkApiKeyDeprecated); } extension AndroidConfigSyntactic on AndroidConfig { @@ -195,7 +210,9 @@ class MacOSConfig { }) : _targetVersion = targetVersion; MacOSConfig.fromJson(Map json) - : _targetVersion = json.optionalInt(_targetMacOSVersionKey); + : _targetVersion = + json.code?.optionalMap(_macosKey)?.optionalInt(_targetVersionKey) ?? + json.optionalInt(_targetMacOSVersionKeyDeprecated); } extension MacOSConfigSyntactic on MacOSConfig { @@ -258,22 +275,45 @@ extension CodeAssetBuildInputBuilder on HookConfigBuilder { }) { if (targetArchitecture != null) { json[_targetArchitectureKey] = targetArchitecture.toString(); + json.setNested([_configKey, _codeKey, _targetArchitectureKey], + targetArchitecture.toString()); } json[_targetOSConfigKey] = targetOS.toString(); + json.setNested( + [_configKey, _codeKey, _targetOSConfigKey], targetOS.toString()); json[_linkModePreferenceKey] = linkModePreference.toString(); + json.setNested([_configKey, _codeKey, _linkModePreferenceKey], + linkModePreference.toString()); if (cCompiler != null) { json[_compilerKey] = cCompiler.toJson(); + json.setNested([_configKey, _codeKey, _compilerKey], cCompiler.toJson()); } // Note, using ?. instead of !. makes missing data be a semantic error // rather than a syntactic error to be caught in the validation. if (targetOS == OS.android) { - json[_targetAndroidNdkApiKey] = android?.targetNdkApi; + json[_targetAndroidNdkApiKeyDeprecated] = android?.targetNdkApi; + json.setNested( + [_configKey, _codeKey, _androidKey, _targetNdkApiKey], + android?.targetNdkApi, + ); } else if (targetOS == OS.iOS) { - json[_targetIOSSdkKey] = iOS?.targetSdk.toString(); - json[_targetIOSVersionKey] = iOS?.targetVersion; + json[_targetIOSSdkKeyDeprecated] = iOS?.targetSdk.toString(); + json[_targetIOSVersionKeyDeprecated] = iOS?.targetVersion; + json.setNested( + [_configKey, _codeKey, _iosKey, _targetSdkKey], + iOS?.targetSdk.toString(), + ); + json.setNested( + [_configKey, _codeKey, _iosKey, _targetVersionKey], + iOS?.targetVersion, + ); } else if (targetOS == OS.macOS) { - json[_targetMacOSVersionKey] = macOS?.targetVersion; + json[_targetMacOSVersionKeyDeprecated] = macOS?.targetVersion; + json.setNested( + [_configKey, _codeKey, _macosKey, _targetVersionKey], + macOS?.targetVersion, + ); } } } @@ -298,11 +338,25 @@ extension CodeAssetLinkOutput on LinkOutputAssets { const String _compilerKey = 'c_compiler'; const String _linkModePreferenceKey = 'link_mode_preference'; -const String _targetAndroidNdkApiKey = 'target_android_ndk_api'; +const String _targetNdkApiKey = 'target_ndk_api'; +const String _targetAndroidNdkApiKeyDeprecated = 'target_android_ndk_api'; const String _targetArchitectureKey = 'target_architecture'; -const String _targetIOSSdkKey = 'target_ios_sdk'; -const String _targetIOSVersionKey = 'target_ios_version'; -const String _targetMacOSVersionKey = 'target_macos_version'; +const String _targetSdkKey = 'target_sdk'; +const String _targetIOSSdkKeyDeprecated = 'target_ios_sdk'; +const String _targetVersionKey = 'target_version'; +const String _targetIOSVersionKeyDeprecated = 'target_ios_version'; +const String _targetMacOSVersionKeyDeprecated = 'target_macos_version'; const String _targetOSConfigKey = 'target_os'; const _dryRunConfigKey = 'dry_run'; + +const _configKey = 'config'; +const _codeKey = 'code'; +const _androidKey = 'android'; +const _iosKey = 'ios'; +const _macosKey = 'macos'; + +extension on Map { + Map? get code => + optionalMap(_configKey)?.optionalMap(_codeKey); +} diff --git a/pkgs/native_assets_cli/lib/src/config.dart b/pkgs/native_assets_cli/lib/src/config.dart index a9ec3324d..c6eea6310 100644 --- a/pkgs/native_assets_cli/lib/src/config.dart +++ b/pkgs/native_assets_cli/lib/src/config.dart @@ -104,18 +104,9 @@ sealed class HookInputBuilder { /// [BuildInput] being built with this [BuildInputBuilder]. It is therefore /// assumed the output directory has not been set yet. String computeChecksum() { - if (json.containsKey(_outDirInputKey) || - json.containsKey(_outDirSharedInputKey) || - json.containsKey(_assetsKey)) { - // The bundling tools would first calculate the checksum, create an output - // directory and then call [setupHookInput]. - // The output directory should not depend on the assets passed in for - // linking. - throw StateError('The checksum should be generated before setting ' - 'up the hook configuration'); - } + final config = json[_configKey]; final hash = sha256 - .convert(const JsonEncoder().fuse(const Utf8Encoder()).convert(json)) + .convert(const JsonEncoder().fuse(const Utf8Encoder()).convert(config)) .toString() // 256 bit hashes lead to 64 hex character strings. // To avoid overflowing file paths limits, only use 32. @@ -137,6 +128,8 @@ const _packageRootInputKey = 'package_root'; const _supportedAssetTypesKey = 'supported_asset_types'; const _buildAssetTypesKey = 'build_asset_types'; +const _configKey = 'config'; + final class BuildInput extends HookInput { final Map metadata; @@ -179,6 +172,7 @@ final class HookConfigBuilder { }) { json[_buildAssetTypesKey] = buildAssetTypes; json[_supportedAssetTypesKey] = buildAssetTypes; + json.setNested([_configKey, _buildAssetTypesKey], buildAssetTypes); } } @@ -193,6 +187,7 @@ extension BuildConfigBuilderSetup on BuildConfigBuilder { }) { json[_dryRunConfigKey] = dryRun; json[_linkingEnabledKey] = linkingEnabled; + json.setNested([_configKey, _linkingEnabledKey], linkingEnabled); // TODO: Bump min-SDK constraint to 3.7 and remove once stable. if (!dryRun) { @@ -583,7 +578,7 @@ extension type EncodedAssetLinkOutputBuilder._(LinkOutputBuilder _builder) { /// /// We'll never bump the major version. Removing old keys from the input and /// output is done via modifying [latestParsableVersion]. -final latestVersion = Version(1, 6, 0); +final latestVersion = Version(1, 7, 0); /// The parser can deal with inputs and outputs down to this version. /// @@ -607,7 +602,10 @@ final class HookConfig { final List buildAssetTypes; HookConfig(this.json) - : buildAssetTypes = json.optionalStringList(_buildAssetTypesKey) ?? + : buildAssetTypes = json + .optionalMap(_configKey) + ?.optionalStringList(_buildAssetTypesKey) ?? + json.optionalStringList(_buildAssetTypesKey) ?? json.optionalStringList(_supportedAssetTypesKey) ?? const []; } @@ -627,5 +625,7 @@ final class BuildConfig extends HookConfig { BuildConfig(super.json) // ignore: deprecated_member_use_from_same_package : dryRun = json.getOptional(_dryRunConfigKey) ?? false, - linkingEnabled = json.get(_linkingEnabledKey); + linkingEnabled = + json.optionalMap(_configKey)?.optionalBool(_linkingEnabledKey) ?? + json.get(_linkingEnabledKey); } diff --git a/pkgs/native_assets_cli/lib/src/json_utils.dart b/pkgs/native_assets_cli/lib/src/json_utils.dart index c267b86c7..4533697f3 100644 --- a/pkgs/native_assets_cli/lib/src/json_utils.dart +++ b/pkgs/native_assets_cli/lib/src/json_utils.dart @@ -16,7 +16,15 @@ extension MapJsonUtils on Map { return value; } - String? optionalString(String key) => getOptional(key); + String? optionalString(String key, {Iterable? validValues}) { + final value = getOptional(key); + if (value == null) return null; + if (validValues != null && !validValues.contains(value)) { + throw FormatException('Json "$key" had value $value but expected one of ' + '${validValues.join(',')}'); + } + return value; + } bool? optionalBool(String key) => getOptional(key); core.int int(String key) => get(key); @@ -62,6 +70,14 @@ extension MapJsonUtils on Map { 'Unexpected value \'$value\' for key \'.$key\' in input file. ' 'Expected a $T?.'); } + + void setNested(List nestedMapKeys, Object? value) { + var map = this; + for (final key in nestedMapKeys.sublist(0, nestedMapKeys.length - 1)) { + map = (map[key] ??= {}) as Map; + } + map[nestedMapKeys.last] = value; + } } extension ListJsonUtils on List { diff --git a/pkgs/native_assets_cli/test/build_config_test.dart b/pkgs/native_assets_cli/test/build_config_test.dart index 497d8e466..815f6d41f 100644 --- a/pkgs/native_assets_cli/test/build_config_test.dart +++ b/pkgs/native_assets_cli/test/build_config_test.dart @@ -56,6 +56,10 @@ void main() async { final expectedInputJson = { 'build_asset_types': ['my-asset-type'], 'build_mode': 'release', + 'config': { + 'build_asset_types': ['my-asset-type'], + 'linking_enabled': false, + }, 'dependency_metadata': { 'bar': { 'key': 'value', @@ -108,6 +112,10 @@ void main() async { final expectedInputJson = { 'build_asset_types': ['my-asset-type'], + 'config': { + 'build_asset_types': ['my-asset-type'], + 'linking_enabled': true, + }, 'dependency_metadata': {}, 'dry_run': true, 'linking_enabled': true, diff --git a/pkgs/native_assets_cli/test/build_output_test.dart b/pkgs/native_assets_cli/test/build_output_test.dart index 58b73b2f5..39d4cd481 100644 --- a/pkgs/native_assets_cli/test/build_output_test.dart +++ b/pkgs/native_assets_cli/test/build_output_test.dart @@ -49,7 +49,7 @@ void main() { // The JSON format of the build output. { - 'version': '1.6.0', + 'version': '1.7.0', 'dependencies': ['path0', 'path1', 'path2'], 'metadata': { 'meta-a': 'meta-b', diff --git a/pkgs/native_assets_cli/test/checksum_test.dart b/pkgs/native_assets_cli/test/checksum_test.dart index 534254b8a..9d5b66ef9 100644 --- a/pkgs/native_assets_cli/test/checksum_test.dart +++ b/pkgs/native_assets_cli/test/checksum_test.dart @@ -2,8 +2,6 @@ // 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 'dart:convert'; - import 'package:native_assets_cli/code_assets_builder.dart'; import 'package:native_assets_cli/data_assets_builder.dart'; import 'package:test/test.dart'; @@ -13,40 +11,73 @@ import 'helpers.dart'; void main() { test('checksum', () async { // metadata, cc, link vs build, metadata, haslink - final inputs = []; + final checksums = []; + final inputs = {}; - for (final dryRun in [true, false]) { - for (final linking in [true, false]) { - for (final assetType in [CodeAsset.type, DataAsset.type]) { + for (final hook in ['build', 'link']) { + for (final linking in [true, if (hook == 'build') false]) { + for (final assetTypes in [ + [CodeAsset.type], + [CodeAsset.type, DataAsset.type], + [DataAsset.type], + ]) { for (final os in [ - OS.linux, - if (assetType == CodeAsset.type) OS.macOS, + OS.android, + if (assetTypes.contains(CodeAsset.type)) OS.iOS, + if (assetTypes.contains(CodeAsset.type)) OS.macOS, ]) { for (final architecture in [ Architecture.arm64, - if (assetType == CodeAsset.type) Architecture.x64, + if (assetTypes.contains(CodeAsset.type)) Architecture.x64, ]) { - final builder = BuildInputBuilder() - ..config.setupBuild( - dryRun: dryRun, - linkingEnabled: linking, - ); - builder.config.setupShared(buildAssetTypes: [assetType]); - if (assetType == CodeAsset.type) { - builder.config.setupCode( - targetArchitecture: architecture, - targetOS: os, - macOS: os == OS.macOS - ? MacOSConfig(targetVersion: defaultMacOSVersion) - : null, - linkModePreference: LinkModePreference.dynamic, - ); + for (final targetVersion in [ + if (os == OS.android) 30, + if (os == OS.iOS) flutteriOSHighestBestEffort, + if (os == OS.iOS) flutteriOSHighestSupported, + if (os == OS.macOS) defaultMacOSVersion, + ]) { + for (final iOSSdk in [ + if (architecture == Architecture.arm64 && os == OS.iOS) + IOSSdk.iPhoneOS, + IOSSdk.iPhoneSimulator, + ]) { + final builder = BuildInputBuilder(); + if (hook == 'build') { + builder.config.setupBuild( + dryRun: false, // no embedders will pass true anymore + linkingEnabled: linking, + ); + } + builder.config.setupShared(buildAssetTypes: assetTypes); + if (assetTypes.contains(CodeAsset.type)) { + builder.config.setupCode( + targetArchitecture: architecture, + targetOS: os, + android: os == OS.android + ? AndroidConfig(targetNdkApi: targetVersion) + : null, + macOS: os == OS.macOS + ? MacOSConfig(targetVersion: targetVersion) + : null, + iOS: os == OS.iOS + ? IOSConfig( + targetVersion: targetVersion, + targetSdk: iOSSdk, + ) + : null, + linkModePreference: LinkModePreference.dynamic, + ); + } + final checksum = builder.computeChecksum(); + checksums.add(checksum); + + if (inputs[checksum] != null) { + expect(builder.json['config'], inputs[checksum]); + } + inputs[checksum] = builder.json['config']; + } } - inputs.add( - const JsonEncoder.withIndent(' ').convert(builder.json), - ); - checksums.add(builder.computeChecksum()); } } } @@ -61,26 +92,69 @@ void main() { // needing to update this list). final expectedChecksums = [ - '079353bf7f09a5a78aad5dfb74d160ce', - '3f77f197abd56950f6878720f40f1d78', - '95afb0b082567b75143a5a3fe23ded7f', - '20a82fc01786d82ec2e70c81e384ca53', - '9b4a6923ab07618074631e9ee8ea5451', - '1ba05dccc6b7d760f2c085dfb3b3e9be', - '86ca6c0d669baa2f0d29b81aa9db65d9', - 'ad261f0ea9c06e69eaf9870161da902f', - '4973835d48a96917eb2b4fe3266c60f4', - '1c4bddfe0111033df5fd1903123a759b', - '07d32fc26a66558589bd2ef3d243a1bf', - '6237121ffae0bb44b6489913f859e595', - '5ab1d45dc1b8365df17dc13bfe725e3e', - 'efff82f6321e8f2ad2d83f7b87890d12', - '9939ebdbc70de2750b26857ccdf7a308', - '2ac3ed117b93db3686b51c8d3da6947d', - '47d6a16f82e7dc71156af0578e1cde4c', - '07eaf868dd64ef1ffd717111d7a73263', - '5df468122615987a0daa4da40c3f4e07', - '0e551c890758631dfc1dd549d8278fc8', + '24ccf8d332a8c8d55e476dc3c6bc583b', + '7f36bc59f947abd6af6cee575138e754', + 'd0aba834036fead9bab453d527eae4ed', + '1ceb39975433d22ece4a862af5ebc13e', + '92a29907211743f4dfa05214efca2f5b', + '43579d544a56d1c2f41324690122e16f', + 'd88c23a4c520275ed03e9b8edee48674', + '2765b39d6a39e71712109588acf05c03', + '66a6f953369ef21ee2576e4e3fde3ad3', + '611a7687747e116ddcc7e50d8ac079d4', + 'c92a32ed941614b8343197d1d42fa27e', + '7498ff7cbb07d9d2dd127377b30f26fa', + '5c0a592096625690802ac0671f4034e0', + '65e125ee71ea5fe4bc79d54003cab931', + '790b552e75a98b90a77455da90c1ea87', + '98fba8ecfc7dd07c798503dfc87da0bb', + '7784fdf4afe8b22c017c5d3f7983777b', + 'eff20a22ed0e429fa20c1458a2c1f0b8', + 'c4b179cfd16d663ae58bd1a06618d23b', + 'd31c785c41b9d852aef30251a46bf214', + 'a89fc3d8de5647d6825b47592e5dd7b5', + 'f13c6adb12346391761a9e0fcfa37568', + '887b0c294956ffe456687778a80913f7', + 'c0cb2fe6ed8f7bc27d0fb166a139c31e', + 'c51f6b56cd8083e2e6d9d5db2997c7fd', + '9ccb0b5e6f39d3655f7ef2cb1b3f02b7', + '440a909a495e1445cc89392176fceec8', + '99e61d87aaaba64b91cedffcb50c521b', + 'f0150c4470ef8e9917d1f500b60f0a8b', + 'bce703d4756f1345959d99f371f70be7', + 'c24f96a671ac4320163ba6ad01e08c22', + '4813128ab93a41cf6a2ba92e1ac87bd8', + '6b8f417d14bdc9cdda90122dc2e16ca4', + '306ae22675d94f717eb58db9bfd7ac14', + 'b4c4531503bd3f814367e78081f183f2', + 'c5903374f46c510508f9d6314ac82c2d', + 'd5bf990a551941d29309dbdd26c0cdf1', + 'e773863012e1cea85b39134357c12c45', + '36eb9110b66f57866c565495fa145f02', + 'b527b041d448d9d3938391348b2b296d', + '9f9a66ee78bdec8e4dab4a63029dbde3', + '0376b13decbf88bc0901b7c853f76bb0', + '527bbf58f698036f78b5519553186d0f', + '8e937a8834d9fcb697b5a3c80ac04dd0', + '4358d31df880c53face01c18945fa14b', + '518e6a0bed957d3e5e88a18a44532ca2', + '614152ce8d7b591916d78838711b75f9', + '0f89f3db1d379ec581b4e896f5060d0a', + 'f7a554031e353366b157d5af0a774bf8', + 'a96c3052f878d4d08585b640ea77970e', + '7c3f0134505f73c91825ea837f1e885e', + '575b6bd07de1a3fdb150b7626526bd47', + 'ecdfaaa2f4bc2708375e6e6a980578a8', + '06c509e166c7fa7d8ac8c56806da53ba', + 'dfb39e5ac164e4f269fb7e9ae084a2a4', + '1b3cbac826b58a001e3ed7539f55f652', + '6fbc5b8630c3d27abf3a810051dd9271', + '43025538d82ed0492a5928aefb0767ab', + '0172735fa45b76ec9f8c3a0416608721', + '547dfca0aa25ffa8e68ae1218c19b339', + '19e984d77d877f7d5a20eb8fe523bee6', + '5f644023cc187fe71f01daccc9bdbe76', + 'bbdaf85e3a026c0bd87a56e7102a6beb', ]; printOnFailure('final expectedChecksums = ['); printOnFailure(checksums.map((e) => " '$e',").join('\n')); @@ -90,3 +164,6 @@ void main() { } }); } + +const flutteriOSHighestBestEffort = 16; +const flutteriOSHighestSupported = 17; diff --git a/pkgs/native_assets_cli/test/code_assets/config_test.dart b/pkgs/native_assets_cli/test/code_assets/config_test.dart index 5f0859a64..85fa79b41 100644 --- a/pkgs/native_assets_cli/test/code_assets/config_test.dart +++ b/pkgs/native_assets_cli/test/code_assets/config_test.dart @@ -58,30 +58,93 @@ void main() async { expect(codeConfig.cCompiler, null); } - void expectCorrectCodeConfig( - Map json, CodeConfig codeConfig) { - { - 'build_asset_types': [CodeAsset.type], - 'link_mode_preference': 'prefer-static', - 'target_android_ndk_api': 30, - 'target_architecture': 'arm64', - 'c_compiler': { - 'ar': fakeAr.toFilePath(), - 'ld': fakeLd.toFilePath(), - 'cc': fakeClang.toFilePath(), - 'env_script': fakeVcVars.toFilePath(), - 'env_script_arguments': ['arg0', 'arg1'], - }, - }.forEach((k, v) { - expect(json[k], v); - }); + // Full JSON to see where the config sits in the full JSON. + // When removing the non-hierarchical JSON, we can change this test to only + // check the nested key. + Map inputJson({ + String hookType = 'build', + bool includeDeprecated = true, + OS targetOS = OS.android, + }) => + { + if (hookType == 'link') + 'assets': [ + { + 'architecture': 'riscv64', + 'file': 'not there', + 'id': 'package:my_package/name', + 'link_mode': {'type': 'dynamic_loading_bundle'}, + 'os': 'android', + 'type': 'native_code' + } + ], + if (includeDeprecated) 'build_asset_types': [CodeAsset.type], + if (includeDeprecated) 'build_mode': 'release', + 'config': { + 'build_asset_types': ['native_code'], + if (hookType == 'build') 'linking_enabled': false, + 'code': { + 'target_architecture': 'arm64', + 'target_os': targetOS.name, + 'link_mode_preference': 'prefer-static', + 'c_compiler': { + 'ar': fakeAr.toFilePath(), + 'ld': fakeLd.toFilePath(), + 'cc': fakeClang.toFilePath(), + 'env_script': fakeVcVars.toFilePath(), + 'env_script_arguments': ['arg0', 'arg1'], + }, + if (targetOS == OS.android) 'android': {'target_ndk_api': 30}, + if (targetOS == OS.macOS) 'macos': {'target_version': 13}, + if (targetOS == OS.iOS) + 'ios': { + 'target_sdk': 'iphoneos', + 'target_version': 13, + }, + }, + }, + if (includeDeprecated) + 'c_compiler': { + 'ar': fakeAr.toFilePath(), + 'ld': fakeLd.toFilePath(), + 'cc': fakeClang.toFilePath(), + 'env_script': fakeVcVars.toFilePath(), + 'env_script_arguments': ['arg0', 'arg1'], + }, + if (hookType == 'build' && includeDeprecated) 'dry_run': false, + if (hookType == 'build' && includeDeprecated) 'linking_enabled': false, + if (includeDeprecated) 'link_mode_preference': 'prefer-static', + 'out_dir_shared': outputDirectoryShared.toFilePath(), + 'out_dir': outDirUri.toFilePath(), + 'package_name': packageName, + 'package_root': packageRootUri.toFilePath(), + if (includeDeprecated) 'supported_asset_types': [CodeAsset.type], + if (includeDeprecated && targetOS == OS.android) + 'target_android_ndk_api': 30, + if (includeDeprecated) 'target_architecture': 'arm64', + if (includeDeprecated) 'target_os': targetOS.name, + 'version': '1.7.0', + }; - expect(codeConfig.targetArchitecture, Architecture.arm64); - expect(codeConfig.android.targetNdkApi, 30); - expect(codeConfig.linkModePreference, LinkModePreference.preferStatic); - expect(codeConfig.cCompiler?.compiler, fakeClang); - expect(codeConfig.cCompiler?.linker, fakeLd); - expect(codeConfig.cCompiler?.archiver, fakeAr); + void expectCorrectCodeConfig( + CodeConfig codeCondig, { + OS targetOS = OS.android, + }) { + expect(codeCondig.targetArchitecture, Architecture.arm64); + if (targetOS == OS.android) { + expect(codeCondig.android.targetNdkApi, 30); + } + if (targetOS == OS.macOS) { + expect(codeCondig.macOS.targetVersion, 13); + } + if (targetOS == OS.iOS) { + expect(codeCondig.iOS.targetVersion, 13); + expect(codeCondig.iOS.targetSdk, IOSSdk.iPhoneOS); + } + expect(codeCondig.linkModePreference, LinkModePreference.preferStatic); + expect(codeCondig.cCompiler?.compiler, fakeClang); + expect(codeCondig.cCompiler?.linker, fakeLd); + expect(codeCondig.cCompiler?.archiver, fakeAr); } test('BuildInput.config.code (dry-run)', () { @@ -135,7 +198,26 @@ void main() async { ), ); final input = BuildInput(inputBuilder.json); - expectCorrectCodeConfig(input.json, input.config.code); + expect(input.json, inputJson()); + expectCorrectCodeConfig(input.config.code); + }); + + test('BuildInput from json without deprecated keys', () { + for (final targetOS in [OS.android, OS.iOS, OS.macOS]) { + final input = BuildInput(inputJson( + includeDeprecated: false, + targetOS: targetOS, + )); + expect(input.packageName, packageName); + expect(input.packageRoot, packageRootUri); + expect(input.outputDirectory, outDirUri); + expect(input.outputDirectoryShared, outputDirectoryShared); + expect(input.config.linkingEnabled, false); + // ignore: deprecated_member_use_from_same_package + expect(input.config.dryRun, false); + expect(input.config.buildAssetTypes, [CodeAsset.type]); + expectCorrectCodeConfig(input.config.code, targetOS: targetOS); + } }); test('LinkInput.{code,codeAssets}', () { @@ -165,10 +247,27 @@ void main() async { ), ); final input = LinkInput(inputBuilder.json); - expectCorrectCodeConfig(input.json, input.config.code); + expect(input.json, inputJson(hookType: 'link')); + expectCorrectCodeConfig(input.config.code); expect(input.assets.encodedAssets, assets); }); + test('LinkInput from json without deprecated keys', () { + for (final targetOS in [OS.android, OS.iOS, OS.macOS]) { + final input = LinkInput(inputJson( + includeDeprecated: false, + targetOS: targetOS, + hookType: 'link', + )); + expect(input.packageName, packageName); + expect(input.packageRoot, packageRootUri); + expect(input.outputDirectory, outDirUri); + expect(input.outputDirectoryShared, outputDirectoryShared); + expect(input.config.buildAssetTypes, [CodeAsset.type]); + expectCorrectCodeConfig(input.config.code, targetOS: targetOS); + } + }); + test('BuildInput.config.code: invalid architecture', () { final input = { 'dry_run': false, diff --git a/pkgs/native_assets_cli/test/link_config_test.dart b/pkgs/native_assets_cli/test/link_config_test.dart index 2d951f82c..acc9e430e 100644 --- a/pkgs/native_assets_cli/test/link_config_test.dart +++ b/pkgs/native_assets_cli/test/link_config_test.dart @@ -47,6 +47,9 @@ void main() async { 'assets': [for (final asset in assets) asset.toJson()], 'build_asset_types': ['asset-type-1', 'asset-type-2'], 'build_mode': 'release', + 'config': { + 'build_asset_types': ['asset-type-1', 'asset-type-2'], + }, 'out_dir_shared': outputDirectoryShared.toFilePath(), 'out_dir': outDirUri.toFilePath(), 'package_name': packageName, diff --git a/pkgs/native_assets_cli/test/link_output_test.dart b/pkgs/native_assets_cli/test/link_output_test.dart index 34de1c2b9..9bd28313d 100644 --- a/pkgs/native_assets_cli/test/link_output_test.dart +++ b/pkgs/native_assets_cli/test/link_output_test.dart @@ -35,7 +35,7 @@ void main() { // The JSON format of the link output. { - 'version': '1.6.0', + 'version': '1.7.0', 'dependencies': ['path0', 'path1', 'path2'], 'assets': [ {'a-0': 'v-0', 'type': 'my-asset-type'},