diff --git a/pkgs/code_assets/doc/schema/hook/shared_definitions.generated.schema.json b/pkgs/code_assets/doc/schema/hook/shared_definitions.generated.schema.json index 8c4d7eaba..868774917 100644 --- a/pkgs/code_assets/doc/schema/hook/shared_definitions.generated.schema.json +++ b/pkgs/code_assets/doc/schema/hook/shared_definitions.generated.schema.json @@ -13,6 +13,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/BuildInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/BuildInput" } ] }, @@ -26,6 +29,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/BuildOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/BuildOutput" } ] }, @@ -36,6 +42,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/HookInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/HookInput" } ] }, @@ -46,6 +55,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/HookOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/HookOutput" } ] }, @@ -59,6 +71,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/LinkInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/LinkInput" } ] }, @@ -72,6 +87,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/LinkOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/LinkOutput" } ] } diff --git a/pkgs/code_assets/doc/schema/hook/shared_definitions.schema.json b/pkgs/code_assets/doc/schema/hook/shared_definitions.schema.json new file mode 100644 index 000000000..032ada0fc --- /dev/null +++ b/pkgs/code_assets/doc/schema/hook/shared_definitions.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "title": "package:code_assets party:sdk shared definitions", + "definitions": { + "BuildInput": {}, + "BuildOutput": {}, + "HookInput": { + "properties": { + "config": { + "properties": { + "code": { + "$comment": "Future SDKs will no longer provide 'code', 'extensions.code_config' instead.", + "deprecated": true + } + } + } + } + }, + "HookOutput": {}, + "LinkInput": {}, + "LinkOutput": {} + } +} diff --git a/pkgs/code_assets/doc/schema/sdk/shared_definitions.generated.schema.json b/pkgs/code_assets/doc/schema/sdk/shared_definitions.generated.schema.json index ec815925f..8c66c9091 100644 --- a/pkgs/code_assets/doc/schema/sdk/shared_definitions.generated.schema.json +++ b/pkgs/code_assets/doc/schema/sdk/shared_definitions.generated.schema.json @@ -13,6 +13,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/BuildInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/BuildInput" } ] }, @@ -26,6 +29,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/BuildOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/BuildOutput" } ] }, @@ -36,6 +42,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/HookInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/HookInput" } ] }, @@ -46,6 +55,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/HookOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/HookOutput" } ] }, @@ -59,6 +71,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/LinkInput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/LinkInput" } ] }, @@ -72,6 +87,9 @@ }, { "$ref": "../shared/shared_definitions.generated.schema.json#/definitions/LinkOutput" + }, + { + "$ref": "shared_definitions.schema.json#/definitions/LinkOutput" } ] } diff --git a/pkgs/code_assets/doc/schema/sdk/shared_definitions.schema.json b/pkgs/code_assets/doc/schema/sdk/shared_definitions.schema.json new file mode 100644 index 000000000..229524230 --- /dev/null +++ b/pkgs/code_assets/doc/schema/sdk/shared_definitions.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "title": "package:code_assets party:sdk shared definitions", + "definitions": { + "BuildInput": {}, + "BuildOutput": {}, + "HookInput": { + "properties": { + "config": { + "properties": { + "code": { + "$comment": "Old hooks still read 'code' so provide both 'code' and 'extensions.code_config'." + } + } + } + } + }, + "HookOutput": {}, + "LinkInput": {}, + "LinkOutput": {} + } +} diff --git a/pkgs/code_assets/doc/schema/shared/shared_definitions.schema.json b/pkgs/code_assets/doc/schema/shared/shared_definitions.schema.json index e461b49d4..11a332bce 100644 --- a/pkgs/code_assets/doc/schema/shared/shared_definitions.schema.json +++ b/pkgs/code_assets/doc/schema/shared/shared_definitions.schema.json @@ -255,6 +255,17 @@ "properties": { "code": { "$ref": "#/definitions/CodeConfig" + }, + "extensions": { + "$ref": "#/definitions/ConfigExtensions" + } + } + }, + "ConfigExtensions": { + "type": "object", + "properties": { + "code_assets": { + "$ref": "#/definitions/CodeConfig" } } }, diff --git a/pkgs/code_assets/test/data/build_input_android.json b/pkgs/code_assets/test/data/build_input_android.json index 232caf701..7b14b3a95 100644 --- a/pkgs/code_assets/test/data/build_input_android.json +++ b/pkgs/code_assets/test/data/build_input_android.json @@ -17,6 +17,21 @@ "target_architecture": "arm", "target_os": "android" }, + "extensions": { + "code_assets": { + "android": { + "target_ndk_api": 21 + }, + "c_compiler": { + "ar": "/Users/dacoharkes/Library/Android/sdk/ndk/28.0.12674087/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar", + "cc": "/Users/dacoharkes/Library/Android/sdk/ndk/28.0.12674087/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang", + "ld": "/Users/dacoharkes/Library/Android/sdk/ndk/28.0.12674087/toolchains/llvm/prebuilt/darwin-x86_64/bin/ld.lld" + }, + "link_mode_preference": "dynamic", + "target_architecture": "arm", + "target_os": "android" + } + }, "linking_enabled": true }, "out_dir": "/Users/dacoharkes/src/dacoharkes/playground/my_package/example/.dart_tool/native_assets_builder/my_package/c540d75d10834674921701cd6c3c7c15/out/", diff --git a/pkgs/code_assets/test/data/build_input_ios.json b/pkgs/code_assets/test/data/build_input_ios.json index dd42f33fa..fcc32022f 100644 --- a/pkgs/code_assets/test/data/build_input_ios.json +++ b/pkgs/code_assets/test/data/build_input_ios.json @@ -18,6 +18,22 @@ "target_architecture": "arm64", "target_os": "ios" }, + "extensions": { + "code_assets": { + "c_compiler": { + "ar": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar", + "cc": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang", + "ld": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" + }, + "ios": { + "target_sdk": "iphonesimulator", + "target_version": 12 + }, + "link_mode_preference": "dynamic", + "target_architecture": "arm64", + "target_os": "ios" + } + }, "linking_enabled": false }, "out_dir": "/Users/dacoharkes/src/dacoharkes/playground/my_package/example/.dart_tool/native_assets_builder/my_package/51d66b45a7c440edc44bf124509a5dda/out/", diff --git a/pkgs/code_assets/test/data/build_input_linux.json b/pkgs/code_assets/test/data/build_input_linux.json index 3e2114801..a99e49bf3 100644 --- a/pkgs/code_assets/test/data/build_input_linux.json +++ b/pkgs/code_assets/test/data/build_input_linux.json @@ -14,6 +14,18 @@ "target_architecture": "x64", "target_os": "linux" }, + "extensions": { + "code_assets": { + "c_compiler": { + "ar": "/usr/lib/llvm-16/bin/llvm-ar", + "cc": "/usr/lib/llvm-16/bin/clang", + "ld": "/usr/lib/llvm-16/bin/ld.lld" + }, + "link_mode_preference": "dynamic", + "target_architecture": "x64", + "target_os": "linux" + } + }, "linking_enabled": false }, "out_dir": "/usr/local/google/home/dacoharkes/src/dacoharkes/playground/my_package/example/.dart_tool/native_assets_builder/my_package/79cc7fbaec53b1465c3e388e6848234b/out/", diff --git a/pkgs/code_assets/test/data/build_input_macos.json b/pkgs/code_assets/test/data/build_input_macos.json index 304d09a01..eec9ebd5b 100644 --- a/pkgs/code_assets/test/data/build_input_macos.json +++ b/pkgs/code_assets/test/data/build_input_macos.json @@ -17,6 +17,21 @@ "target_architecture": "arm64", "target_os": "macos" }, + "extensions": { + "code_assets": { + "c_compiler": { + "ar": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar", + "cc": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang", + "ld": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" + }, + "link_mode_preference": "dynamic", + "macos": { + "target_version": 13 + }, + "target_architecture": "arm64", + "target_os": "macos" + } + }, "linking_enabled": false }, "dependency_metadata": { diff --git a/pkgs/code_assets/test/data/build_input_windows.json b/pkgs/code_assets/test/data/build_input_windows.json index 37444cfd2..52dd31f95 100644 --- a/pkgs/code_assets/test/data/build_input_windows.json +++ b/pkgs/code_assets/test/data/build_input_windows.json @@ -22,6 +22,26 @@ "target_architecture": "x64", "target_os": "windows" }, + "extensions": { + "code_assets": { + "c_compiler": { + "ar": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.35.32215\\bin\\Hostx64\\x64\\lib.exe", + "cc": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.35.32215\\bin\\Hostx64\\x64\\cl.exe", + "env_script": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat", + "env_script_arguments": [], + "ld": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\MSVC\\14.35.32215\\bin\\Hostx64\\x64\\link.exe", + "windows": { + "developer_command_prompt": { + "arguments": [], + "script": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" + } + } + }, + "link_mode_preference": "dynamic", + "target_architecture": "x64", + "target_os": "windows" + } + }, "linking_enabled": false }, "out_dir": "C:\\src\\dacoharkes\\playground\\my_package\\example\\.dart_tool\\native_assets_builder\\my_package\\190c04c47dc2f9eb26d2411b1968b2cf\\out\\", diff --git a/pkgs/code_assets/test/data/link_input_macos.json b/pkgs/code_assets/test/data/link_input_macos.json index 4722b6acf..1f25eef10 100644 --- a/pkgs/code_assets/test/data/link_input_macos.json +++ b/pkgs/code_assets/test/data/link_input_macos.json @@ -28,6 +28,21 @@ }, "target_architecture": "arm64", "target_os": "macos" + }, + "extensions": { + "code_assets": { + "c_compiler": { + "ar": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar", + "cc": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang", + "ld": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" + }, + "link_mode_preference": "dynamic", + "macos": { + "target_version": 13 + }, + "target_architecture": "arm64", + "target_os": "macos" + } } }, "out_dir": "/Users/dacoharkes/src/dacoharkes/playground/my_package/example/.dart_tool/native_assets_builder/my_package/ca4e7d3d4e7b8912cbd24d9e8a6cecdc/out/", diff --git a/pkgs/code_assets/test/schema/schema_test.dart b/pkgs/code_assets/test/schema/schema_test.dart index d74fb7ef8..2288831e9 100644 --- a/pkgs/code_assets/test/schema/schema_test.dart +++ b/pkgs/code_assets/test/schema/schema_test.dart @@ -96,21 +96,25 @@ FieldsFunction _codeFields(AllTestData allTestData) { ]; return <(List, void Function(ValidationResults result))>[ - if (inputOrOutput == InputOrOutput.input) ...[ - (['config', 'code', 'c_compiler'], expectOptionalFieldMissing), - (['config', 'code', 'c_compiler', 'ar'], expectRequiredFieldMissing), - (['config', 'code', 'c_compiler', 'cc'], expectRequiredFieldMissing), - (['config', 'code', 'c_compiler', 'ld'], expectRequiredFieldMissing), - (['config', 'code', 'macos'], expectRequiredFieldMissing), - ( - ['config', 'code', 'macos', 'target_version'], - expectRequiredFieldMissing, - ), - if (hook == Hook.link) ...[ - for (final field in requiredCodeAssetFields) - (['assets', 0, ...field], expectRequiredFieldMissing), + for (final codeConfigPath in [ + ['config', 'code'], + ['config', 'extensions', 'code_assets'], + ]) + if (inputOrOutput == InputOrOutput.input) ...[ + ([...codeConfigPath, 'c_compiler'], expectOptionalFieldMissing), + ([...codeConfigPath, 'c_compiler', 'ar'], expectRequiredFieldMissing), + ([...codeConfigPath, 'c_compiler', 'cc'], expectRequiredFieldMissing), + ([...codeConfigPath, 'c_compiler', 'ld'], expectRequiredFieldMissing), + ([...codeConfigPath, 'macos'], expectRequiredFieldMissing), + ( + [...codeConfigPath, 'macos', 'target_version'], + expectRequiredFieldMissing, + ), + if (hook == Hook.link) ...[ + for (final field in requiredCodeAssetFields) + (['assets', 0, ...field], expectRequiredFieldMissing), + ], ], - ], if (inputOrOutput == InputOrOutput.output) ...[ for (final field in requiredCodeAssetFields) (['assets', 0, ...field], expectRequiredFieldMissing), @@ -147,43 +151,55 @@ _codeFieldsWindows({ required Hook hook, required Party party, }) => <(List, void Function(ValidationResults result))>[ - if (inputOrOutput == InputOrOutput.input && hook == Hook.build) ...[ - ( - ['config', 'code', 'c_compiler', 'env_script'], - expectOptionalFieldMissing, - ), - ( - ['config', 'code', 'c_compiler', 'env_script_arguments'], - expectOptionalFieldMissing, - ), - (['config', 'code', 'c_compiler', 'windows'], expectRequiredFieldMissing), - ( - ['config', 'code', 'c_compiler', 'windows', 'developer_command_prompt'], - expectOptionalFieldMissing, - ), - ( - [ - 'config', - 'code', - 'c_compiler', - 'windows', - 'developer_command_prompt', - 'script', - ], - expectRequiredFieldMissing, - ), - ( - [ - 'config', - 'code', - 'c_compiler', - 'windows', - 'developer_command_prompt', - 'arguments', - ], - expectRequiredFieldMissing, - ), - ], + if (inputOrOutput == InputOrOutput.input && hook == Hook.build) + for (final codeConfigPath in [ + ['config', 'code'], + ['config', 'extensions', 'code_assets'], + ]) ...[ + ( + [...codeConfigPath, 'c_compiler', 'env_script'], + expectOptionalFieldMissing, + ), + ( + [...codeConfigPath, 'c_compiler', 'env_script_arguments'], + expectOptionalFieldMissing, + ), + ( + [...codeConfigPath, 'c_compiler', 'windows'], + expectRequiredFieldMissing, + ), + ( + [ + ...codeConfigPath, + 'c_compiler', + 'windows', + 'developer_command_prompt', + ], + expectOptionalFieldMissing, + ), + ( + [ + 'config', + 'code', + 'c_compiler', + 'windows', + 'developer_command_prompt', + 'script', + ], + expectRequiredFieldMissing, + ), + ( + [ + 'config', + 'code', + 'c_compiler', + 'windows', + 'developer_command_prompt', + 'arguments', + ], + expectRequiredFieldMissing, + ), + ], ]; List<(List, void Function(ValidationResults result))> _codeFieldsIOS({ @@ -191,11 +207,18 @@ List<(List, void Function(ValidationResults result))> _codeFieldsIOS({ required Hook hook, required Party party, }) => <(List, void Function(ValidationResults result))>[ - if (inputOrOutput == InputOrOutput.input && hook == Hook.build) ...[ - (['config', 'code', 'ios'], expectRequiredFieldMissing), - (['config', 'code', 'ios', 'target_sdk'], expectRequiredFieldMissing), - (['config', 'code', 'ios', 'target_version'], expectRequiredFieldMissing), - ], + if (inputOrOutput == InputOrOutput.input && hook == Hook.build) + for (final codeConfigPath in [ + ['config', 'code'], + ['config', 'extensions', 'code_assets'], + ]) ...[ + ([...codeConfigPath, 'ios'], expectRequiredFieldMissing), + ([...codeConfigPath, 'ios', 'target_sdk'], expectRequiredFieldMissing), + ( + [...codeConfigPath, 'ios', 'target_version'], + expectRequiredFieldMissing, + ), + ], ]; List<(List, void Function(ValidationResults result))> @@ -204,11 +227,15 @@ _codeFieldsAndroid({ required Hook hook, required Party party, }) => <(List, void Function(ValidationResults result))>[ - if (inputOrOutput == InputOrOutput.input && hook == Hook.build) ...[ - (['config', 'code', 'android'], expectRequiredFieldMissing), - ( - ['config', 'code', 'android', 'target_ndk_api'], - expectRequiredFieldMissing, - ), - ], + if (inputOrOutput == InputOrOutput.input && hook == Hook.build) + for (final codeConfigPath in [ + ['config', 'code'], + ['config', 'extensions', 'code_assets'], + ]) ...[ + ([...codeConfigPath, 'android'], expectRequiredFieldMissing), + ( + [...codeConfigPath, 'android', 'target_ndk_api'], + expectRequiredFieldMissing, + ), + ], ]; diff --git a/pkgs/hook/doc/schema/shared/shared_definitions.schema.json b/pkgs/hook/doc/schema/shared/shared_definitions.schema.json index a4a1cbfe5..78970aa35 100644 --- a/pkgs/hook/doc/schema/shared/shared_definitions.schema.json +++ b/pkgs/hook/doc/schema/shared/shared_definitions.schema.json @@ -89,12 +89,19 @@ "items": { "type": "string" } + }, + "extensions": { + "$ref": "#/definitions/ConfigExtensions" } }, "required": [ "build_asset_types" ] }, + "ConfigExtensions": { + "type": "object", + "additionalProperties": true + }, "HookInput": { "type": "object", "properties": { diff --git a/pkgs/hook/tool/generate_schemas.dart b/pkgs/hook/tool/generate_schemas.dart index 600c1835c..f44ac8285 100644 --- a/pkgs/hook/tool/generate_schemas.dart +++ b/pkgs/hook/tool/generate_schemas.dart @@ -114,7 +114,7 @@ void generateSharedDefinitions() { r'$ref': '../shared/shared_definitions${package == 'hook' ? '' : '.generated'}.schema.json#/definitions/${definitionName(hook, inputOrOutput)}', }, - if (package == 'hook' && party != Party.shared) + if (package != 'data_assets' && party != Party.shared) { r'$ref': 'shared_definitions.schema.json#/definitions/${definitionName(hook, inputOrOutput)}', diff --git a/pkgs/hook/tool/generate_syntax.dart b/pkgs/hook/tool/generate_syntax.dart index c4744f951..92efb9050 100644 --- a/pkgs/hook/tool/generate_syntax.dart +++ b/pkgs/hook/tool/generate_syntax.dart @@ -40,6 +40,7 @@ void main(List args) { publicSetters: [ 'BuildOutput', 'Config', + 'ConfigExtensions', 'HookInput', 'HookOutput', 'LinkOutput', @@ -56,6 +57,7 @@ void main(List args) { 'DeveloperCommandPrompt', 'CodeConfig', 'Config', + 'ConfigExtensions', 'IOSCodeConfig', 'LinkMode', 'DynamicLoadingBundleLinkMode', 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 fe56aeaaa..3c76abccc 100644 --- a/pkgs/native_assets_cli/lib/src/code_assets/config.dart +++ b/pkgs/native_assets_cli/lib/src/code_assets/config.dart @@ -42,7 +42,9 @@ class CodeConfig { final syntax.CodeConfig _syntax; CodeConfig._fromJson(Map json, List path) - : _syntax = syntax.Config.fromJson(json, path: path).code!; + : _syntax = + syntax.Config.fromJson(json, path: path).extensions?.codeAssets ?? + syntax.Config.fromJson(json, path: path).code!; /// The architecture the code code asset should be built for. /// @@ -191,9 +193,7 @@ extension CodeAssetBuildInputBuilder on HookConfigBuilder { IOSCodeConfig? iOS, MacOSCodeConfig? macOS, }) { - syntax.Config.fromJson( - hook_syntax.HookInput.fromJson(builder.json).config.json, - ).code = syntax.CodeConfig( + final codeConfig = syntax.CodeConfig( linkModePreference: linkModePreference.toSyntax(), targetArchitecture: targetArchitecture.toSyntax(), targetOs: targetOS.toSyntax(), @@ -202,6 +202,11 @@ extension CodeAssetBuildInputBuilder on HookConfigBuilder { iOS: iOS?.toSyntax(), macOS: macOS?.toSyntax(), ); + final baseHookConfig = hook_syntax.HookInput.fromJson(builder.json).config; + baseHookConfig.extensions ??= {}; + final hookConfig = syntax.Config.fromJson(baseHookConfig.json); + hookConfig.extensions!.codeAssets = codeConfig; + hookConfig.code = codeConfig; // old location } } diff --git a/pkgs/native_assets_cli/lib/src/code_assets/syntax.g.dart b/pkgs/native_assets_cli/lib/src/code_assets/syntax.g.dart index ffdd922bd..07111922f 100644 --- a/pkgs/native_assets_cli/lib/src/code_assets/syntax.g.dart +++ b/pkgs/native_assets_cli/lib/src/code_assets/syntax.g.dart @@ -620,8 +620,11 @@ class Config { Config.fromJson(this.json, {this.path = const []}); - Config({required CodeConfig? code}) : json = {}, path = const [] { + Config({required CodeConfig? code, required ConfigExtensions? extensions}) + : json = {}, + path = const [] { this.code = code; + this.extensions = extensions; json.sortOnKey(); } @@ -644,12 +647,72 @@ class Config { return code?.validate() ?? []; } - List validate() => [..._validateCode()]; + ConfigExtensions? get extensions { + final jsonValue = _reader.optionalMap('extensions'); + if (jsonValue == null) return null; + return ConfigExtensions.fromJson(jsonValue, path: [...path, 'extensions']); + } + + set extensions(ConfigExtensions? value) { + json.setOrRemove('extensions', value?.json); + json.sortOnKey(); + } + + List _validateExtensions() { + final mapErrors = _reader.validate?>('extensions'); + if (mapErrors.isNotEmpty) { + return mapErrors; + } + return extensions?.validate() ?? []; + } + + List validate() => [..._validateCode(), ..._validateExtensions()]; @override String toString() => 'Config($json)'; } +class ConfigExtensions { + final Map json; + + final List path; + + JsonReader get _reader => JsonReader(json, path); + + ConfigExtensions.fromJson(this.json, {this.path = const []}); + + ConfigExtensions({required CodeConfig? codeAssets}) + : json = {}, + path = const [] { + this.codeAssets = codeAssets; + json.sortOnKey(); + } + + CodeConfig? get codeAssets { + final jsonValue = _reader.optionalMap('code_assets'); + if (jsonValue == null) return null; + return CodeConfig.fromJson(jsonValue, path: [...path, 'code_assets']); + } + + set codeAssets(CodeConfig? value) { + json.setOrRemove('code_assets', value?.json); + json.sortOnKey(); + } + + List _validateCodeAssets() { + final mapErrors = _reader.validate?>('code_assets'); + if (mapErrors.isNotEmpty) { + return mapErrors; + } + return codeAssets?.validate() ?? []; + } + + List validate() => [..._validateCodeAssets()]; + + @override + String toString() => 'ConfigExtensions($json)'; +} + class IOSCodeConfig { final Map json; diff --git a/pkgs/native_assets_cli/lib/src/hook/syntax.g.dart b/pkgs/native_assets_cli/lib/src/hook/syntax.g.dart index 6f2390bb2..c1b025214 100644 --- a/pkgs/native_assets_cli/lib/src/hook/syntax.g.dart +++ b/pkgs/native_assets_cli/lib/src/hook/syntax.g.dart @@ -41,8 +41,11 @@ class Asset { class BuildConfig extends Config { BuildConfig.fromJson(super.json, {super.path}) : super.fromJson(); - BuildConfig({required super.buildAssetTypes, required bool linkingEnabled}) - : super() { + BuildConfig({ + required super.buildAssetTypes, + required super.extensions, + required bool linkingEnabled, + }) : super() { _linkingEnabled = linkingEnabled; json.sortOnKey(); } @@ -281,8 +284,13 @@ class Config { Config.fromJson(this.json, {this.path = const []}); - Config({required List buildAssetTypes}) : json = {}, path = const [] { + Config({ + required List buildAssetTypes, + required Map? extensions, + }) : json = {}, + path = const [] { this.buildAssetTypes = buildAssetTypes; + this.extensions = extensions; json.sortOnKey(); } @@ -296,7 +304,20 @@ class Config { List _validateBuildAssetTypes() => _reader.validateStringList('build_asset_types'); - List validate() => [..._validateBuildAssetTypes()]; + Map? get extensions => _reader.optionalMap('extensions'); + + set extensions(Map? value) { + json.setOrRemove('extensions', value); + json.sortOnKey(); + } + + List _validateExtensions() => + _reader.validateOptionalMap('extensions'); + + List validate() => [ + ..._validateBuildAssetTypes(), + ..._validateExtensions(), + ]; @override String toString() => 'Config($json)'; diff --git a/pkgs/native_assets_cli/test/checksum_test.dart b/pkgs/native_assets_cli/test/checksum_test.dart index b0c64bfb5..0060a099e 100644 --- a/pkgs/native_assets_cli/test/checksum_test.dart +++ b/pkgs/native_assets_cli/test/checksum_test.dart @@ -95,68 +95,68 @@ void main() { // needing to update this list). final expectedChecksums = [ - '373d25ca3201cf61ff42048b5fe67c24', - '76c914f249d8e0dec9ea88eedd796737', - '03846a8382cf6f5052f82f9917562e70', - 'b219b76aa364c90168b4a1e57372c7a0', - '61288538db9d98b280f5c27dc094aeb8', - 'fde745d50ebcc6d16d312fdc493a30c5', - '65444c11c83a84e63b974e3643a10da7', - 'aaee85324a2b2ddc9d641c4cef1780a9', - '9cbb27c2c60e6336985f7083715eeb15', - '2898b73da7fd05f28b066ab212aff277', - '7b823719e472096087c6dc6ed16c1322', - 'f11f9e90c3611524429786301a345763', - '1939726b2173808f28e1de412165f541', - 'a56d14a636b307825d9dca40531ebbe4', - '6c9f6b3254a394727bef590cc9bcf7c2', - '2ed14db4ec08a01cdd293a91201b668b', - 'c6558f264707b7cec3ba59a213a51a07', - 'b9bdf9933922c88f1f858565aed2f9b2', - '04b4dd22c9917cea4d0876d3a4a7c076', - '89b4df38c0750b959e3b91556b5340c5', + '94c285a130d88664be8f21c1d6ef34cd', + '57721cad5c11285edb0016515541e2d5', + 'd9b5d713b0b6a18c67d5e490cdbd074f', + 'db5406082ee570220c97eb1f123e718c', + 'b78638ece1b0a543d09318d48aa9a6c8', + 'ca297a62f6b0dfcf2823528ae4dfd08e', + '264c307b448f3f9304b1ccab6ec60075', + 'b4a04739d33b007f4058492d3df94955', + 'ec48ca9f46c95620b209837d710e46d4', + 'faa7c97c28a4fc4b4856e7a27f34d717', + 'cb775af7eb5733a85226089f6fb5a8c6', + '6d815c7d59f04707891ede5a23136787', + '0231d5d5a4def1870ea81b316c0f232b', + 'b87236e226c6338dccff134e9ee971f9', + '6e7b17bf18d55557e0eed5d2050e4401', + 'e393e7d58700da05843a5cf8db102fde', + 'd3080b3502953a53cb63a5509bba1eee', + 'a27bf133693f18dee751b7f9661725ad', + '93a1f07ea89f1b9f57a23bb7aed77c7e', + '6f802ed01d66cb9529540387ec26d4bc', 'a648f38bcc571d5800d549fa9146c161', - '9d6255bb88e0c174cfd73326374653fb', - '3a5c1e777cb824b9df6e8812db7f014f', - '569bbc36d2252ad007e86bbbc91cab4a', - '85f5f97cd1b4c42f88e77d23bf9337d2', - 'db76cd3ef567bc0a20a805d7ff78c89b', - '81861002f1a66a0d0edbd8191a550b9d', - '4b5e64761e6a8aaafc489ed0d627caa5', - '6e493366b0ff7e397134fcc004840b61', - 'fcdb6b85f369b18ce0bf6e71dfed9711', - '6505fb7e18c7572486d4bceb9267c829', - '2f208ebb3f2a86fadf16f30d6eb83c60', - '8a1a8a1378f0205cf82b39d6d9ef0c06', - '3d9a25a9a4724ef6b9c4098117d476ea', - '427caa5594959f686108440aae237d23', - '3b1fd713e83549612ec6813fc21d406d', - '35e34c04cb001ef1df0a91debe4ec876', - '1d44781858b032eab6081840a33cb992', - '0dec96f613afa0481e7359069060cc3d', - '1a2b62ccd83da975b42752c5a136d104', - 'e132b66dbb18e36e85dfa0c817a74590', + 'e7a0bed5b00346177a24ced2860136bb', + '14b0fcffdc10411a0119641a04e84f24', + '3a9112376cfba8ed524306533e0ba64c', + '87ba90976f0ac1720ac9ae3ab3e04ed6', + 'ebcc2a8b819d79ea3bd9ba8669c49286', + '1441b71d0db6c1fa226a013605716bcb', + 'e1946bf4587c22123e97ef19d2c63050', + '83acde5a35b0cde1a861082d1ffd0097', + 'fd6bc0ef963c6d65ef616779f203dc0f', + '5b5a62e841327b1afdda64dba0f8a3e2', + 'c64865e81ee7e701a2a52ea344998693', + '050ad3d2db8581feed77c17c22564789', + '118569cd7c4c12baa4eaea9c70dc2dd3', + '5e38c88dcdec92bf701d170f10cb0063', + 'dd330565f2ff2a2d7bb2a480cfc25b12', + '8e36a6f17eb303799056f0aa1737a1fe', + '40035559d1a93b3ebe7d2986b2c99aea', + '786716ef01b49293cf3493b22fcb2518', + '9f8655c03f8f2f0bc27ae6917390f4e1', + '3139d774dcddfba7705072397a59b9fe', '59bc110e371c5e9c8b04f6453d09584d', - '8ee9d30cc420cd9212348d2c4222c6ee', - '70e422b86e227f740b9a72980d0d12d8', - 'fc6fbfe32afac158157cb02dde609e52', - '5dec2c2e2ff5ba0403ae6ff7d7ae5b3b', - '116057a6e64e3aaf95cdbd70dd056bce', - '07b4c2e72d4a3c2cb684edff2037bd38', - '91c7ff44c0d157514eba5f01ac960dd9', - 'c5b859d9d1d59cd46368ebbabb78902f', - '8b94ecb5699de5730c8545abafe30c11', - '936624d135da96cdfc0dd7b038909521', - 'b158baa7fc7a12252592f02e672e31a7', - '47514c281f37a35ba6b70090dadf787d', - '0de0ab1c36a35279d6f7fc2a1d69174f', - 'dc97054090baaaf646f73d11c9142293', - '153aa59e1a9dc2667a69c1388ef2dca9', - '5d4c049a66acc31f54d2a99d2b8ecf98', - '36f450524b4ab720c243c3daf54ff283', - '8d701a6f5446d10c1f965eece8cf4b8a', - 'd7e29713d72316e019e0f512f91b432d', - '19be742ac2c24d9764de06aba70a31eb', + 'f3c6c5de6568f639d67e03b07818acc6', + '59b5e3250d97b1cfe15ad65198882e7c', + '6bc2d951c8f99290a94b9a865476c512', + '6aa6ede0d3f0be509a7ee30121403d2c', + '80b03895e3dd0e4e4697558bf57a354d', + '03de9929411b19bb1c840c7188e2bddb', + 'c1179c3e37c5936c915747bdaa9bc180', + '86c530550aea1db7f07501eecd5461ab', + 'a7911874e29e9696bba7dceeaef99a78', + '9cd55f6b3c45ecb8563c476bc88052a8', + 'b05ed1e42541d90f2ef3b4180921fc67', + '229db175097f0ea52b6f2a995a526dff', + 'd2a66fc795288cc2e5d68d4ed7286fd0', + 'be81bebbf4c55f9deb56a73d25cc2750', + 'c2be87cc81c5a1276c454d67d00238e0', + '4ff44ba1c783becaa20f5810fb02f9d1', + 'ed210e050e2907f66a0e420d143be823', + '3d768c496687797c2f141cbc9af0d641', + 'e9a36b9242d1f5b5eddb7fd084903264', + '645460d5ebb3374201eba75e5545d0d2', 'bbdaf85e3a026c0bd87a56e7102a6beb', ]; printOnFailure('final expectedChecksums = ['); 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 6ae789260..4a3c8e96c 100644 --- a/pkgs/native_assets_cli/test/code_assets/config_test.dart +++ b/pkgs/native_assets_cli/test/code_assets/config_test.dart @@ -52,51 +52,55 @@ void main() async { String hookType = 'build', bool includeDeprecated = false, 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', - }, - ], - '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(), - if (includeDeprecated) 'env_script': fakeVcVars.toFilePath(), - if (includeDeprecated) 'env_script_arguments': ['arg0', 'arg1'], - 'windows': { - 'developer_command_prompt': { - 'arguments': ['arg0', 'arg1'], - 'script': fakeVcVars.toFilePath(), - }, + }) { + final codeConfig = { + 'target_architecture': 'arm64', + 'target_os': targetOS.name, + 'link_mode_preference': 'prefer_static', + 'c_compiler': { + 'ar': fakeAr.toFilePath(), + 'ld': fakeLd.toFilePath(), + 'cc': fakeClang.toFilePath(), + if (includeDeprecated) 'env_script': fakeVcVars.toFilePath(), + if (includeDeprecated) 'env_script_arguments': ['arg0', 'arg1'], + 'windows': { + 'developer_command_prompt': { + 'arguments': ['arg0', 'arg1'], + 'script': fakeVcVars.toFilePath(), }, }, - 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}, }, - }, - 'out_dir_shared': outputDirectoryShared.toFilePath(), - 'out_dir': outDirUri.toFilePath(), - 'out_file': outFile.toFilePath(), - 'package_name': packageName, - 'package_root': packageRootUri.toFilePath(), - 'version': '1.9.0', - }; + 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}, + }; + return { + 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', + }, + ], + 'config': { + 'code': codeConfig, + 'build_asset_types': ['native_code'], + 'extensions': {'code_assets': codeConfig}, + if (hookType == 'build') 'linking_enabled': false, + }, + 'out_dir_shared': outputDirectoryShared.toFilePath(), + 'out_dir': outDirUri.toFilePath(), + 'out_file': outFile.toFilePath(), + 'package_name': packageName, + 'package_root': packageRootUri.toFilePath(), + 'version': '1.9.0', + }; + } void expectCorrectCodeConfig( CodeConfig codeCondig, { @@ -239,6 +243,28 @@ void main() async { test('LinkInput.config.code.target_os invalid type', () { final input = inputJson(hookType: 'link'); + traverseJson>(input, [ + 'config', + 'extensions', + 'code_assets', + ])['target_os'] = + 123; + expect( + () => LinkInput(input).config.code.targetOS, + throwsA( + predicate( + (e) => + e is FormatException && + e.message.contains( + "Unexpected value '123' (int) for " + "'config.extensions.code_assets.target_os'. " + 'Expected a String.', + ), + ), + ), + ); + + traverseJson>(input, ['config']).remove('extensions'); traverseJson>(input, ['config', 'code'])['target_os'] = 123; expect( @@ -258,6 +284,26 @@ void main() async { test('LinkInput.config.code.link_mode_preference missing', () { final input = inputJson(hookType: 'link'); + traverseJson>(input, [ + 'config', + 'extensions', + 'code_assets', + ]).remove('link_mode_preference'); + expect( + () => LinkInput(input).config.code.linkModePreference, + throwsA( + predicate( + (e) => + e is FormatException && + e.message.contains( + 'No value was provided for ' + "'config.extensions.code_assets.link_mode_preference'.", + ), + ), + ), + ); + + traverseJson>(input, ['config']).remove('extensions'); traverseJson>(input, [ 'config', 'code',