From a74f07342c35eaa08ce9398c4daea528fe21e437 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 16 Jul 2026 12:58:07 +0000 Subject: [PATCH 1/3] dart format --- example/add/lib/src/g/add.g.dart | 5 +- .../lib/src/hook_helpers/hook_helpers.dart | 24 +- example/example.dart | 24 +- lib/src/builder/build_mode.dart | 5 +- lib/src/builder/log_level.dart | 18 +- lib/src/builder/user_config.dart | 3 +- lib/src/native_toolchain/android_ndk.dart | 5 +- lib/src/native_toolchain/apple_clang.dart | 10 +- lib/src/native_toolchain/clang.dart | 12 +- lib/src/native_toolchain/cmake.dart | 34 +- lib/src/native_toolchain/gcc.dart | 18 +- lib/src/native_toolchain/ninja.dart | 34 +- lib/src/tool/tool.dart | 5 +- lib/src/tool/tool_instance.dart | 17 +- lib/src/tool/tool_requirement.dart | 5 +- lib/src/tool/tool_resolver.dart | 20 +- lib/src/utils/sem_version.dart | 6 +- .../cmake_builder_cross_android_test.dart | 55 +- .../builder/cmake_builder_cross_ios_test.dart | 55 +- .../cmake_builder_cross_linux_host_test.dart | 12 +- .../cmake_builder_cross_macos_host_test.dart | 37 +- ...cmake_builder_cross_windows_host_test.dart | 31 +- test/builder/cmake_builder_git_test.dart | 7 +- test/builder/cmake_builder_test.dart | 60 +- test/helpers.dart | 56 +- test/native_toolchain/apple_clang_test.dart | 4 +- test/native_toolchain/cmake_test.dart | 647 +++++++++++------- test/native_toolchain/gcc_test.dart | 38 +- test/native_toolchain/ninja_test.dart | 647 +++++++++++------- test/native_toolchain/recognizer_test.dart | 17 +- test/native_toolchain/xcode_test.dart | 19 +- test/tool/tool_instance_test.dart | 36 +- test/tool/tool_requirement_test.dart | 17 +- test/tool/tool_resolver_test.dart | 29 +- test/tool/tool_test.dart | 10 +- test/utils/run_process_test.dart | 8 +- 36 files changed, 1095 insertions(+), 935 deletions(-) diff --git a/example/add/lib/src/g/add.g.dart b/example/add/lib/src/g/add.g.dart index 9f58447..15e3b0d 100644 --- a/example/add/lib/src/g/add.g.dart +++ b/example/add/lib/src/g/add.g.dart @@ -15,7 +15,4 @@ library; import 'dart:ffi' as ffi; @ffi.Native() -external int math_add( - int a, - int b, -); +external int math_add(int a, int b); diff --git a/example/add/lib/src/hook_helpers/hook_helpers.dart b/example/add/lib/src/hook_helpers/hook_helpers.dart index d4e8d56..f89df5c 100644 --- a/example/add/lib/src/hook_helpers/hook_helpers.dart +++ b/example/add/lib/src/hook_helpers/hook_helpers.dart @@ -7,11 +7,7 @@ import 'package:native_toolchain_cmake/native_toolchain_cmake.dart'; const name = 'add'; -Future runBuild( - BuildInput input, - BuildOutputBuilder output, - Uri sourceDir, -) async { +Future runBuild(BuildInput input, BuildOutputBuilder output, Uri sourceDir) async { final _logger = Logger('') ..level = Level.ALL // temp fwd to stderr until process logs pass to stdout @@ -23,9 +19,7 @@ Future runBuild( 'CMAKE_BUILD_TYPE': 'Release', 'CMAKE_INSTALL_PREFIX': '${input.outputDirectory.toFilePath()}/install', }, - targets: [ - 'install', - ], + targets: ['install'], buildLocal: true, logger: _logger, ); @@ -48,11 +42,7 @@ Future runBuild( _logger.info('Found libs: $outLibs'); } -Future runBuildGit( - BuildInput input, - BuildOutputBuilder output, - Uri sourceDir, -) async { +Future runBuildGit(BuildInput input, BuildOutputBuilder output, Uri sourceDir) async { final logger = Logger('') ..level = Level.ALL // temp fwd to stderr until process logs pass to stdout @@ -72,11 +62,7 @@ Future runBuildGit( logger: logger, ); - await builder.run( - input: input, - output: output, - logger: logger, - ); + await builder.run(input: input, output: output, logger: logger); // manually add assets final libPath = switch (input.config.code.targetOS) { @@ -85,7 +71,7 @@ Future runBuildGit( OS.windows => "install/lib/add.dll", OS.android => "install/lib/libadd.so", OS.iOS => "install/lib/libadd.dylib", - _ => throw UnsupportedError("Unsupported OS") + _ => throw UnsupportedError("Unsupported OS"), }; output.assets.code.add( CodeAsset( diff --git a/example/example.dart b/example/example.dart index 108848f..1df057f 100644 --- a/example/example.dart +++ b/example/example.dart @@ -20,11 +20,7 @@ void main(List args) async { const name = 'add'; -Future runBuild( - BuildInput input, - BuildOutputBuilder output, - Uri sourceDir, -) async { +Future runBuild(BuildInput input, BuildOutputBuilder output, Uri sourceDir) async { final _logger = Logger('') ..level = Level.ALL // temp fwd to stderr until process logs pass to stdout @@ -36,9 +32,7 @@ Future runBuild( 'CMAKE_BUILD_TYPE': 'Release', 'CMAKE_INSTALL_PREFIX': '${input.outputDirectory.toFilePath()}/install', }, - targets: [ - 'install', - ], + targets: ['install'], buildLocal: true, logger: _logger, ); @@ -61,11 +55,7 @@ Future runBuild( _logger.info('Found libs: $outLibs'); } -Future runBuildGit( - BuildInput input, - BuildOutputBuilder output, - Uri sourceDir, -) async { +Future runBuildGit(BuildInput input, BuildOutputBuilder output, Uri sourceDir) async { final logger = Logger('') ..level = Level.ALL // temp fwd to stderr until process logs pass to stdout @@ -85,11 +75,7 @@ Future runBuildGit( logger: logger, ); - await builder.run( - input: input, - output: output, - logger: logger, - ); + await builder.run(input: input, output: output, logger: logger); // manually add assets final libPath = switch (input.config.code.targetOS) { @@ -98,7 +84,7 @@ Future runBuildGit( OS.windows => "install/lib/add.dll", OS.android => "install/lib/libadd.so", OS.iOS => "install/lib/libadd.dylib", - _ => throw UnsupportedError("Unsupported OS") + _ => throw UnsupportedError("Unsupported OS"), }; output.assets.code.add( CodeAsset( diff --git a/lib/src/builder/build_mode.dart b/lib/src/builder/build_mode.dart index fd3f30e..7898760 100644 --- a/lib/src/builder/build_mode.dart +++ b/lib/src/builder/build_mode.dart @@ -35,10 +35,7 @@ final class BuildMode { static const release = BuildMode._('release'); /// All known build modes. - static const values = [ - debug, - release, - ]; + static const values = [debug, release]; /// The name of this [BuildMode]. /// diff --git a/lib/src/builder/log_level.dart b/lib/src/builder/log_level.dart index 8dd81a7..f0953bf 100644 --- a/lib/src/builder/log_level.dart +++ b/lib/src/builder/log_level.dart @@ -15,13 +15,13 @@ enum LogLevel { const LogLevel(this.value); static LogLevel fromValue(String value) => switch (value) { - "ERROR" => ERROR, - "WARNING" => WARNING, - "NOTICE" => NOTICE, - "STATUS" => STATUS, - "VERBOSE" => VERBOSE, - "DEBUG" => DEBUG, - "TRACE" => TRACE, - _ => throw ArgumentError("Unknown value for LogLevel: $value"), - }; + "ERROR" => ERROR, + "WARNING" => WARNING, + "NOTICE" => NOTICE, + "STATUS" => STATUS, + "VERBOSE" => VERBOSE, + "DEBUG" => DEBUG, + "TRACE" => TRACE, + _ => throw ArgumentError("Unknown value for LogLevel: $value"), + }; } diff --git a/lib/src/builder/user_config.dart b/lib/src/builder/user_config.dart index e39f1f8..1373ab1 100644 --- a/lib/src/builder/user_config.dart +++ b/lib/src/builder/user_config.dart @@ -43,7 +43,8 @@ class UserConfig { bool envVarAndroidHomeAsDefault = true, }) : preferAndroidCmake = preferAndroidCmake ?? targetOS == OS.android, preferAndroidNinja = preferAndroidNinja ?? targetOS == OS.android, - androidHome = androidHome ?? (envVarAndroidHomeAsDefault ? Platform.environment['ANDROID_HOME'] : null); + androidHome = + androidHome ?? (envVarAndroidHomeAsDefault ? Platform.environment['ANDROID_HOME'] : null); UserConfig copyWith({ OS? targetOS, diff --git a/lib/src/native_toolchain/android_ndk.dart b/lib/src/native_toolchain/android_ndk.dart index 6a3e987..22aa42d 100644 --- a/lib/src/native_toolchain/android_ndk.dart +++ b/lib/src/native_toolchain/android_ndk.dart @@ -61,10 +61,7 @@ class _AndroidNdkResolver implements ToolResolver { ]), ); - final ndkInstances = await installLocationResolver.resolve( - logger: logger, - environment: environment, - ); + final ndkInstances = await installLocationResolver.resolve(logger: logger, environment: environment); // sort latest version first ndkInstances.sort( (a, b) => switch ((a.version, b.version)) { diff --git a/lib/src/native_toolchain/apple_clang.dart b/lib/src/native_toolchain/apple_clang.dart index 9c7eb4c..8e5a076 100644 --- a/lib/src/native_toolchain/apple_clang.dart +++ b/lib/src/native_toolchain/apple_clang.dart @@ -14,10 +14,7 @@ final Tool appleClang = Tool( wrappedResolver: CliFilter( cliArguments: ['--version'], keepIf: ({required String stdout}) => stdout.contains('Apple clang'), - wrappedResolver: PathToolResolver( - toolName: 'Apple Clang', - executableName: 'clang', - ), + wrappedResolver: PathToolResolver(toolName: 'Apple Clang', executableName: 'clang'), ), ), ); @@ -52,9 +49,6 @@ final Tool appleLd = Tool( final Tool otool = Tool( name: 'otool', defaultResolver: CliVersionResolver( - wrappedResolver: PathToolResolver( - toolName: 'otool', - executableName: 'otool', - ), + wrappedResolver: PathToolResolver(toolName: 'otool', executableName: 'otool'), ), ); diff --git a/lib/src/native_toolchain/clang.dart b/lib/src/native_toolchain/clang.dart index b81a7e7..59a90d8 100644 --- a/lib/src/native_toolchain/clang.dart +++ b/lib/src/native_toolchain/clang.dart @@ -18,21 +18,13 @@ final Tool clang = Tool( cliArguments: ['--version'], keepIf: ({required String stdout}) => !stdout.contains('Apple clang'), wrappedResolver: ToolResolvers([ - PathToolResolver( - toolName: 'Clang', - executableName: OS.current.executableFileName('clang'), - ), + PathToolResolver(toolName: 'Clang', executableName: OS.current.executableFileName('clang')), RelativeToolResolver( toolName: 'Clang', wrappedResolver: visualStudio.defaultResolver!, relativePath: Uri(path: './VC/Tools/Llvm/bin/clang.exe'), ), - InstallLocationResolver( - toolName: 'Clang', - paths: [ - 'C:/Program Files/LLVM/bin/clang.exe', - ], - ), + InstallLocationResolver(toolName: 'Clang', paths: ['C:/Program Files/LLVM/bin/clang.exe']), ]), ), ), diff --git a/lib/src/native_toolchain/cmake.dart b/lib/src/native_toolchain/cmake.dart index 9c53c3e..112f68e 100644 --- a/lib/src/native_toolchain/cmake.dart +++ b/lib/src/native_toolchain/cmake.dart @@ -24,25 +24,27 @@ class _CmakeResolver implements ToolResolver { final executableName = OS.current.executableFileName('cmake'); CliVersionResolver _getAndroidResolver({UserConfig? userConfig}) { - return unitTestCmakeAndroidResolver ?? CliVersionResolver( - wrappedResolver: ToolResolvers([ - InstallLocationResolver( - toolName: 'CMake', - paths: [ - if (userConfig?.androidHome != null) '${userConfig?.androidHome}/cmake/*/bin/$executableName', - if (Platform.isLinux) r'$HOME/Android/Sdk/cmake/*/bin/' + executableName, - if (Platform.isMacOS) r'$HOME/Library/Android/sdk/cmake/*/bin/' + executableName, - if (Platform.isWindows) r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + executableName, - ], - ), - ]), - ); + return unitTestCmakeAndroidResolver ?? + CliVersionResolver( + wrappedResolver: ToolResolvers([ + InstallLocationResolver( + toolName: 'CMake', + paths: [ + if (userConfig?.androidHome != null) '${userConfig?.androidHome}/cmake/*/bin/$executableName', + if (Platform.isLinux) r'$HOME/Android/Sdk/cmake/*/bin/' + executableName, + if (Platform.isMacOS) r'$HOME/Library/Android/sdk/cmake/*/bin/' + executableName, + if (Platform.isWindows) r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + executableName, + ], + ), + ]), + ); } CliVersionResolver _getSystemResolver() { - return unitTestCmakeSystemResolver ?? CliVersionResolver( - wrappedResolver: PathToolResolver(toolName: 'CMake', executableName: 'cmake'), - ); + return unitTestCmakeSystemResolver ?? + CliVersionResolver( + wrappedResolver: PathToolResolver(toolName: 'CMake', executableName: 'cmake'), + ); } @override diff --git a/lib/src/native_toolchain/gcc.dart b/lib/src/native_toolchain/gcc.dart index b7dcbee..c9105d1 100644 --- a/lib/src/native_toolchain/gcc.dart +++ b/lib/src/native_toolchain/gcc.dart @@ -13,10 +13,7 @@ import '../tool/tool_resolver.dart'; final gcc = Tool( name: 'GCC', defaultResolver: CliVersionResolver( - wrappedResolver: PathToolResolver( - toolName: 'GCC', - executableName: 'gcc', - ), + wrappedResolver: PathToolResolver(toolName: 'GCC', executableName: 'gcc'), ), ); @@ -74,14 +71,11 @@ final riscv64LinuxGnuGccAr = _gnuArchiver('riscv64-linux-gnu'); final riscv64LinuxGnuLd = _gnuLinker('riscv64-linux-gnu'); Tool _gcc(String prefix) => Tool( - name: gcc.name, - defaultResolver: CliVersionResolver( - wrappedResolver: PathToolResolver( - toolName: gcc.name, - executableName: '$prefix-gcc', - ), - ), - ); + name: gcc.name, + defaultResolver: CliVersionResolver( + wrappedResolver: PathToolResolver(toolName: gcc.name, executableName: '$prefix-gcc'), + ), +); Tool _gnuArchiver(String prefix) { final gcc = _gcc(prefix); diff --git a/lib/src/native_toolchain/ninja.dart b/lib/src/native_toolchain/ninja.dart index 6e914e7..1b1e947 100644 --- a/lib/src/native_toolchain/ninja.dart +++ b/lib/src/native_toolchain/ninja.dart @@ -23,25 +23,27 @@ class _NinjaResolver implements ToolResolver { final executableName = OS.current.executableFileName('ninja'); CliVersionResolver _getAndroidResolver({UserConfig? userConfig}) { - return unitTestNinjaAndroidResolver ?? CliVersionResolver( - wrappedResolver: ToolResolvers([ - InstallLocationResolver( - toolName: 'Ninja', - paths: [ - if (userConfig?.androidHome != null) '${userConfig?.androidHome}/cmake/*/bin/$executableName', - if (Platform.isLinux) r'$HOME/Android/Sdk/cmake/*/bin/' + executableName, - if (Platform.isMacOS) r'$HOME/Library/Android/sdk/cmake/*/bin/' + executableName, - if (Platform.isWindows) r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + executableName, - ], - ), - ]), - ); + return unitTestNinjaAndroidResolver ?? + CliVersionResolver( + wrappedResolver: ToolResolvers([ + InstallLocationResolver( + toolName: 'Ninja', + paths: [ + if (userConfig?.androidHome != null) '${userConfig?.androidHome}/cmake/*/bin/$executableName', + if (Platform.isLinux) r'$HOME/Android/Sdk/cmake/*/bin/' + executableName, + if (Platform.isMacOS) r'$HOME/Library/Android/sdk/cmake/*/bin/' + executableName, + if (Platform.isWindows) r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + executableName, + ], + ), + ]), + ); } CliVersionResolver _getSystemResolver() { - return unitTestNinjaSystemResolver ?? CliVersionResolver( - wrappedResolver: PathToolResolver(toolName: 'Ninja', executableName: 'ninja'), - ); + return unitTestNinjaSystemResolver ?? + CliVersionResolver( + wrappedResolver: PathToolResolver(toolName: 'Ninja', executableName: 'ninja'), + ); } @override diff --git a/lib/src/tool/tool.dart b/lib/src/tool/tool.dart index ff42f28..1603856 100644 --- a/lib/src/tool/tool.dart +++ b/lib/src/tool/tool.dart @@ -9,10 +9,7 @@ class Tool { ToolResolver? defaultResolver; - Tool({ - required this.name, - this.defaultResolver, - }); + Tool({required this.name, this.defaultResolver}); @override bool operator ==(Object other) => other is Tool && name == other.name; diff --git a/lib/src/tool/tool_instance.dart b/lib/src/tool/tool_instance.dart index b2074c3..d9f273c 100644 --- a/lib/src/tool/tool_instance.dart +++ b/lib/src/tool/tool_instance.dart @@ -18,21 +18,10 @@ class ToolInstance implements Comparable { /// Can be null if version is hard to determine. final Version? version; - ToolInstance({ - required this.tool, - required this.uri, - this.version, - }); + ToolInstance({required this.tool, required this.uri, this.version}); - ToolInstance copyWith({ - Uri? uri, - Version? version, - }) => - ToolInstance( - tool: tool, - uri: uri ?? this.uri, - version: version ?? this.version, - ); + ToolInstance copyWith({Uri? uri, Version? version}) => + ToolInstance(tool: tool, uri: uri ?? this.uri, version: version ?? this.version); @override String toString() => 'ToolInstance(${tool.name}, $version, $uri)'; diff --git a/lib/src/tool/tool_requirement.dart b/lib/src/tool/tool_requirement.dart index 2c6d118..82f9139 100644 --- a/lib/src/tool/tool_requirement.dart +++ b/lib/src/tool/tool_requirement.dart @@ -22,10 +22,7 @@ class ToolRequirement implements Requirement { final Version? minimumVersion; - ToolRequirement( - this.tool, { - this.minimumVersion, - }); + ToolRequirement(this.tool, {this.minimumVersion}); @override String toString() => 'ToolRequirement(${tool.name}, minimumVersion: $minimumVersion)'; diff --git a/lib/src/tool/tool_resolver.dart b/lib/src/tool/tool_resolver.dart index 0a9f8ba..8cb02ae 100644 --- a/lib/src/tool/tool_resolver.dart +++ b/lib/src/tool/tool_resolver.dart @@ -67,7 +67,12 @@ class PathToolResolver extends ToolResolver { static Uri get which => Uri.file(Platform.isWindows ? 'where' : 'which'); Future runWhich({required Logger? logger, Map? environment}) async { - final process = await runProcess(executable: which, arguments: [executableName], logger: logger, environment: environment); + final process = await runProcess( + executable: which, + arguments: [executableName], + logger: logger, + environment: environment, + ); if (process.exitCode == 0) { final file = File(LineSplitter.split(process.stdout).first); final uri = File(await file.resolveSymbolicLinks()).uri; @@ -141,11 +146,7 @@ class CliVersionResolver implements ToolResolver { List arguments = const ['--version'], int expectedExitCode = 0, }) async { - final process = await runProcess( - executable: executable, - arguments: arguments, - logger: logger, - ); + final process = await runProcess(executable: executable, arguments: arguments, logger: logger); if (process.exitCode != expectedExitCode) { final executablePath = executable.toFilePath(); throw ToolError( @@ -203,11 +204,8 @@ class ToolResolvers implements ToolResolver { UserConfig? userConfig, Map? environment, }) async => [ - for (final resolver in resolvers) ...await resolver.resolve( - logger: logger, - userConfig: userConfig, - environment: environment, - ), + for (final resolver in resolvers) + ...await resolver.resolve(logger: logger, userConfig: userConfig, environment: environment), ]; } diff --git a/lib/src/utils/sem_version.dart b/lib/src/utils/sem_version.dart index 39f8342..bf15c9d 100644 --- a/lib/src/utils/sem_version.dart +++ b/lib/src/utils/sem_version.dart @@ -36,7 +36,9 @@ Version? versionFromString(String containsVersion) { } final _semverRegex = RegExp( - r'(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?'); + r'(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?', +); final _semverRegexReleaxed = RegExp( - r'(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?'); + r'(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?', +); diff --git a/test/builder/cmake_builder_cross_android_test.dart b/test/builder/cmake_builder_cross_android_test.dart index e5e430b..590adea 100644 --- a/test/builder/cmake_builder_cross_android_test.dart +++ b/test/builder/cmake_builder_cross_android_test.dart @@ -39,33 +39,36 @@ void main() { flutterAndroidNdkVersionHighestSupported, ]) { for (final enableUserDefinedConfig in [true, false]) { - test('CMakeBuilder $linkMode library $target minSdkVersion $apiLevel enableUserDefinedConfig $enableUserDefinedConfig', () async { - final tempUri = await tempDirForTest(); - final libUri = await buildLib( - tempUri, - target, - apiLevel, - linkMode, - enableUserDefinedConfig: enableUserDefinedConfig, - ); - if (Platform.isLinux) { - final machine = await readelfMachine(libUri.path); - expect(machine, contains(readElfMachine[target])); - } else if (Platform.isMacOS) { - final result = await runProcess( - executable: Uri.file('objdump'), - arguments: ['-T', libUri.path], - logger: logger, + test( + 'CMakeBuilder $linkMode library $target minSdkVersion $apiLevel enableUserDefinedConfig $enableUserDefinedConfig', + () async { + final tempUri = await tempDirForTest(); + final libUri = await buildLib( + tempUri, + target, + apiLevel, + linkMode, + enableUserDefinedConfig: enableUserDefinedConfig, ); - expect(result.exitCode, 0); - final machine = result.stdout.split('\n').firstWhere((e) => e.contains('file format')); - expect(machine, contains(objdumpFileFormat[target])); - } - // TODO: failed - // if (linkMode == DynamicLoadingBundled()) { - // await expectPageSize(libUri, 16 * 1024); - // } - }); + if (Platform.isLinux) { + final machine = await readelfMachine(libUri.path); + expect(machine, contains(readElfMachine[target])); + } else if (Platform.isMacOS) { + final result = await runProcess( + executable: Uri.file('objdump'), + arguments: ['-T', libUri.path], + logger: logger, + ); + expect(result.exitCode, 0); + final machine = result.stdout.split('\n').firstWhere((e) => e.contains('file format')); + expect(machine, contains(objdumpFileFormat[target])); + } + // TODO: failed + // if (linkMode == DynamicLoadingBundled()) { + // await expectPageSize(libUri, 16 * 1024); + // } + }, + ); } } } diff --git a/test/builder/cmake_builder_cross_ios_test.dart b/test/builder/cmake_builder_cross_ios_test.dart index 6cddd63..db8a286 100644 --- a/test/builder/cmake_builder_cross_ios_test.dart +++ b/test/builder/cmake_builder_cross_ios_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('mac-os') -@OnPlatform({ - 'mac-os': Timeout.factor(2), -}) +@OnPlatform({'mac-os': Timeout.factor(2)}) library; import 'dart:io'; @@ -27,16 +25,10 @@ void main() { return; } - const targets = [ - Architecture.arm64, - Architecture.x64, - ]; + const targets = [Architecture.arm64, Architecture.x64]; // Dont include 'mach-o' or 'Mach-O', different spelling is used. - const objdumpFileFormat = { - Architecture.arm64: 'arm64', - Architecture.x64: '64-bit x86-64', - }; + const objdumpFileFormat = {Architecture.arm64: 'arm64', Architecture.x64: '64-bit x86-64'}; const name = 'add'; @@ -63,10 +55,7 @@ void main() { targetOS: OS.iOS, targetArchitecture: target, linkModePreference: LinkModePreference.dynamic, - iOS: IOSCodeConfig( - targetSdk: targetIOSSdk, - targetVersion: flutteriOSHighestBestEffort, - ), + iOS: IOSCodeConfig(targetSdk: targetIOSSdk, targetVersion: flutteriOSHighestBestEffort), cCompiler: cCompiler, ), ); @@ -80,11 +69,7 @@ void main() { buildMode: BuildMode.release, generator: Generator.make, ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final libUri = buildInput.outputDirectory.resolve(libName); final objdumpResult = await runProcess( @@ -120,11 +105,7 @@ void main() { final targetInstallName = '@executable_path/Frameworks/$libName'; await runProcess( executable: Uri.file('install_name_tool'), - arguments: [ - '-id', - targetInstallName, - libUri.toFilePath(), - ], + arguments: ['-id', targetInstallName, libUri.toFilePath()], logger: logger, ); final libInstallName2 = await runOtoolInstallName(libUri, libName); @@ -141,13 +122,7 @@ void main() { await Directory.fromUri(out1Uri).create(); final out2Uri = tempUri.resolve('out1/'); await Directory.fromUri(out2Uri).create(); - final lib1Uri = await buildLib( - out1Uri, - out2Uri, - target, - iosVersion, - DynamicLoadingBundled(), - ); + final lib1Uri = await buildLib(out1Uri, out2Uri, target, iosVersion, DynamicLoadingBundled()); final otoolResult = await runProcess( executable: Uri.file('otool'), @@ -181,12 +156,10 @@ Future buildLib( CodeAssetExtension( targetOS: OS.iOS, targetArchitecture: targetArchitecture, - linkModePreference: - linkMode == DynamicLoadingBundled() ? LinkModePreference.dynamic : LinkModePreference.static, - iOS: IOSCodeConfig( - targetSdk: IOSSdk.iPhoneOS, - targetVersion: targetIOSVersion, - ), + linkModePreference: linkMode == DynamicLoadingBundled() + ? LinkModePreference.dynamic + : LinkModePreference.static, + iOS: IOSCodeConfig(targetSdk: IOSSdk.iPhoneOS, targetVersion: targetIOSVersion), cCompiler: cCompiler, ), ); @@ -200,11 +173,7 @@ Future buildLib( buildMode: BuildMode.release, generator: Generator.make, ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final libUri = buildInput.outputDirectory.resolve(OS.iOS.libraryFileName(name, linkMode)); return libUri; diff --git a/test/builder/cmake_builder_cross_linux_host_test.dart b/test/builder/cmake_builder_cross_linux_host_test.dart index 35305f9..915d24a 100644 --- a/test/builder/cmake_builder_cross_linux_host_test.dart +++ b/test/builder/cmake_builder_cross_linux_host_test.dart @@ -20,11 +20,7 @@ void main() { return; } - const targets = [ - Architecture.arm64, - Architecture.x64, - Architecture.riscv64, - ]; + const targets = [Architecture.arm64, Architecture.x64, Architecture.riscv64]; for (final linkMode in [DynamicLoadingBundled()]) { for (final target in targets) { @@ -60,11 +56,7 @@ void main() { sourceDir: Directory('test/builder/testfiles/add').absolute.uri, buildMode: BuildMode.release, ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final libUri = buildInput.outputDirectory.resolve(OS.linux.libraryFileName(name, linkMode)); final machine = await readelfMachine(libUri.path); diff --git a/test/builder/cmake_builder_cross_macos_host_test.dart b/test/builder/cmake_builder_cross_macos_host_test.dart index 6c03b25..3aeccd3 100644 --- a/test/builder/cmake_builder_cross_macos_host_test.dart +++ b/test/builder/cmake_builder_cross_macos_host_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('mac-os') -@OnPlatform({ - 'mac-os': Timeout.factor(2), -}) +@OnPlatform({'mac-os': Timeout.factor(2)}) library; import 'dart:io'; @@ -24,16 +22,10 @@ void main() { return; } - const targets = [ - Architecture.arm64, - Architecture.x64, - ]; + const targets = [Architecture.arm64, Architecture.x64]; // Dont include 'mach-o' or 'Mach-O', different spelling is used. - const objdumpFileFormat = { - Architecture.arm64: 'arm64', - Architecture.x64: '64-bit x86-64', - }; + const objdumpFileFormat = {Architecture.arm64: 'arm64', Architecture.x64: '64-bit x86-64'}; for (final target in targets) { test('CMakeBuilder library $target', () async { @@ -68,13 +60,11 @@ void main() { buildMode: BuildMode.release, appleArgs: const AppleBuilderArgs(enableArc: false, enableBitcode: false, enableVisibility: true), ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); - final libUri = buildInput.outputDirectory.resolve(OS.macOS.libraryFileName(name, DynamicLoadingBundled())); + final libUri = buildInput.outputDirectory.resolve( + OS.macOS.libraryFileName(name, DynamicLoadingBundled()), + ); final result = await runProcess( executable: Uri.file('objdump'), arguments: ['-t', libUri.path], @@ -97,12 +87,7 @@ void main() { await Directory.fromUri(out1Uri).create(); final out2Uri = tempUri.resolve('out2/'); await Directory.fromUri(out1Uri).create(); - final lib1Uri = await buildLib( - out1Uri, - out2Uri, - target, - macosVersion, - ); + final lib1Uri = await buildLib(out1Uri, out2Uri, target, macosVersion); final otoolResult = await runProcess( executable: Uri.file('otool'), @@ -149,11 +134,7 @@ Future buildLib( sourceDir: Directory('test/builder/testfiles/add').absolute.uri, buildMode: BuildMode.release, ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final libUri = buildInput.outputDirectory.resolve(OS.iOS.libraryFileName(name, DynamicLoadingBundled())); return libUri; diff --git a/test/builder/cmake_builder_cross_windows_host_test.dart b/test/builder/cmake_builder_cross_windows_host_test.dart index 918fda3..1fb62e1 100644 --- a/test/builder/cmake_builder_cross_windows_host_test.dart +++ b/test/builder/cmake_builder_cross_windows_host_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('windows') -@OnPlatform({ - 'windows': Timeout.factor(10), -}) +@OnPlatform({'windows': Timeout.factor(10)}) library; import 'dart:io'; @@ -25,11 +23,7 @@ void main() async { return; } - const targets = [ - Architecture.arm64, - Architecture.ia32, - Architecture.x64, - ]; + const targets = [Architecture.arm64, Architecture.ia32, Architecture.x64]; late Uri dumpbinUri; @@ -37,16 +31,9 @@ void main() async { dumpbinUri = (await dumpbin.defaultResolver!.resolve(logger: logger)).first.uri; }); - const dumpbinMachine = { - Architecture.arm64: 'ARM64', - Architecture.ia32: 'x86', - Architecture.x64: 'x64', - }; + const dumpbinMachine = {Architecture.arm64: 'ARM64', Architecture.ia32: 'x86', Architecture.x64: 'x64'}; - final dumpbinFileType = { - DynamicLoadingBundled(): 'DLL', - StaticLinking(): 'LIBRARY', - }; + final dumpbinFileType = {DynamicLoadingBundled(): 'DLL', StaticLinking(): 'LIBRARY'}; for (final linkMode in [DynamicLoadingBundled()]) { for (final target in targets) { @@ -81,16 +68,10 @@ void main() async { name: name, sourceDir: Directory('test/builder/testfiles/add').absolute.uri, buildMode: buildMode, - defines: { - 'CMAKE_INSTALL_PREFIX': buildInput.outputDirectory.resolve('install').toFilePath(), - }, + defines: {'CMAKE_INSTALL_PREFIX': buildInput.outputDirectory.resolve('install').toFilePath()}, targets: ['install'], ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final libUri = buildInput.outputDirectory.resolve('install/lib/${OS.current.dylibFileName(name)}'); expect(await File.fromUri(libUri).exists(), true); diff --git a/test/builder/cmake_builder_git_test.dart b/test/builder/cmake_builder_git_test.dart index 44d89d9..83f8bbd 100644 --- a/test/builder/cmake_builder_git_test.dart +++ b/test/builder/cmake_builder_git_test.dart @@ -52,9 +52,7 @@ void main() { gitSubDir: 'example/add/src', buildLocal: buildLocal, logger: logger, - defines: { - 'CMAKE_INSTALL_PREFIX': 'install', - }, + defines: {'CMAKE_INSTALL_PREFIX': 'install'}, targets: ['install'], ); @@ -86,7 +84,8 @@ void main() { final archName = input.config.code.targetArchitecture.name.toLowerCase(); final buildDir = buildLocal ? Directory.fromUri( - tempDir.resolve('build/').resolve("$osName/").resolve(archName).normalizePath()) + tempDir.resolve('build/').resolve("$osName/").resolve(archName).normalizePath(), + ) : Directory.fromUri(input.outputDirectory); expect( buildDir.existsSync(), diff --git a/test/builder/cmake_builder_test.dart b/test/builder/cmake_builder_test.dart index c94e918..febff21 100644 --- a/test/builder/cmake_builder_test.dart +++ b/test/builder/cmake_builder_test.dart @@ -1,7 +1,4 @@ -@OnPlatform({ - 'mac-os': Timeout.factor(2), - 'windows': Timeout.factor(10), -}) +@OnPlatform({'mac-os': Timeout.factor(2), 'windows': Timeout.factor(10)}) import 'dart:ffi'; import 'dart:io'; @@ -14,10 +11,7 @@ import 'package:test/test.dart'; import '../helpers.dart'; -const sourceDirs = [ - 'test/builder/testfiles/hello_world', - 'test/builder/testfiles/hello_world_cpp', -]; +const sourceDirs = ['test/builder/testfiles/hello_world', 'test/builder/testfiles/hello_world_cpp']; void main() { final targetOS = OS.current; @@ -66,16 +60,14 @@ void main() { await builder.run(input: buildInput, output: buildOutput, logger: logger); final executableUri = switch (targetOS) { - OS.macOS => buildInput.outputDirectory - .resolve('$name.app/Contents/MacOS/${OS.current.executableFileName(name)}'), + OS.macOS => buildInput.outputDirectory.resolve( + '$name.app/Contents/MacOS/${OS.current.executableFileName(name)}', + ), OS.windows => buildInput.outputDirectory.resolve('${buildMode.name.toCapitalCase()}/$name.exe'), _ => buildInput.outputDirectory.resolve(OS.current.executableFileName(name)), }; expect(await File.fromUri(executableUri).exists(), true); - final result = await runProcess( - executable: executableUri, - logger: logger, - ); + final result = await runProcess(executable: executableUri, logger: logger); expect(result.exitCode, 0); if (buildMode == BuildMode.debug) { expect(result.stdout.trim(), startsWith('Running in debug mode.')); @@ -118,9 +110,7 @@ void main() { name: name, sourceDir: Directory('test/builder/testfiles/add').absolute.uri, buildMode: buildMode, - defines: { - 'CMAKE_INSTALL_PREFIX': buildInput.outputDirectory.resolve('install').toFilePath(), - }, + defines: {'CMAKE_INSTALL_PREFIX': buildInput.outputDirectory.resolve('install').toFilePath()}, targets: ['install'], androidArgs: const AndroidBuilderArgs(), appleArgs: const AppleBuilderArgs(), @@ -173,43 +163,25 @@ Future testDefines({BuildMode buildMode = BuildMode.debug}) async { androidArgs: const AndroidBuilderArgs(), appleArgs: const AppleBuilderArgs(), ); - await builder.run( - input: buildInput, - output: buildOutput, - logger: logger, - ); + await builder.run(input: buildInput, output: buildOutput, logger: logger); final executableUri = switch (targetOS) { - OS.macOS => - buildInput.outputDirectory.resolve('$name.app/Contents/MacOS/${OS.current.executableFileName(name)}'), + OS.macOS => buildInput.outputDirectory.resolve( + '$name.app/Contents/MacOS/${OS.current.executableFileName(name)}', + ), OS.windows => buildInput.outputDirectory.resolve('${buildMode.name.toCapitalCase()}/$name.exe'), _ => buildInput.outputDirectory.resolve(OS.current.executableFileName(name)), }; expect(await File.fromUri(executableUri).exists(), true); - final result = await runProcess( - executable: executableUri, - logger: logger, - ); + final result = await runProcess(executable: executableUri, logger: logger); expect(result.exitCode, 0); if (buildMode == BuildMode.release) { - expect( - result.stdout, - contains('Macro NDEBUG is defined: 1'), - ); + expect(result.stdout, contains('Macro NDEBUG is defined: 1')); } else { - expect( - result.stdout, - contains('Macro NDEBUG is undefined.'), - ); - expect( - result.stdout, - contains('Macro DEBUG is defined: 1'), - ); + expect(result.stdout, contains('Macro NDEBUG is undefined.')); + expect(result.stdout, contains('Macro DEBUG is defined: 1')); } - expect( - result.stdout, - contains('Macro FOO is defined: BAR'), - ); + expect(result.stdout, contains('Macro FOO is defined: BAR')); } diff --git a/test/helpers.dart b/test/helpers.dart index 45ad155..5d121f7 100644 --- a/test/helpers.dart +++ b/test/helpers.dart @@ -34,9 +34,9 @@ import 'package:test/test.dart'; /// } /// ``` String testSuffix(List tags) => switch (tags) { - [] => '', - _ => ' (${tags.join(', ')})', - }; + [] => '', + _ => ' (${tags.join(', ')})', +}; const keepTempKey = 'KEEP_TEMPORARY_DIRECTORIES'; @@ -53,11 +53,11 @@ Future tempDirForTest({String? prefix, bool keepTemp = false}) async { /// Logger that outputs the full trace when a test fails. Logger get logger => _logger ??= () { - // A new logger is lazily created for each test so that the messages - // captured by printOnFailure are scoped to the correct test. - addTearDown(() => _logger = null); - return _createTestLogger(); - }(); + // A new logger is lazily created for each test so that the messages + // captured by printOnFailure are scoped to the correct test. + addTearDown(() => _logger = null); + return _createTestLogger(); +}(); Logger? _logger; @@ -102,10 +102,12 @@ Uri findPackageRoot(String packageName) { return cwd; } } - throw StateError("Could not find package root for package '$packageName'. " - 'Tried finding the package root via Platform.script ' - "'${Platform.script.toFilePath()}' and Directory.current " - "'${Directory.current.uri.toFilePath()}'."); + throw StateError( + "Could not find package root for package '$packageName'. " + 'Tried finding the package root via Platform.script ' + "'${Platform.script.toFilePath()}' and Directory.current " + "'${Directory.current.uri.toFilePath()}'.", + ); } Uri packageUri = findPackageRoot('native_toolchain_c'); @@ -137,8 +139,9 @@ final Uri? _envScript = Platform.environment['DART_HOOK_TESTING_C_COMPILER__ENV_ /// Arguments for [_envScript] provided by environment. /// /// Provided on Dart CI. -final List? _envScriptArgs = - Platform.environment['DART_HOOK_TESTING_C_COMPILER__ENV_SCRIPT_ARGUMENTS']?.split(' '); +final List? _envScriptArgs = Platform + .environment['DART_HOOK_TESTING_C_COMPILER__ENV_SCRIPT_ARGUMENTS'] + ?.split(' '); /// Configuration for the native toolchain. /// @@ -152,10 +155,7 @@ final cCompiler = (_cc == null || _ar == null || _ld == null) windows: WindowsCCompilerConfig( developerCommandPrompt: _envScript == null ? null - : DeveloperCommandPrompt( - script: _envScript!, - arguments: _envScriptArgs ?? [], - ), + : DeveloperCommandPrompt(script: _envScript!, arguments: _envScriptArgs ?? []), ), ); @@ -224,10 +224,7 @@ Future nmReadSymbols(CodeAsset asset) async { final assetUri = asset.file!; final result = await runProcess( executable: Uri(path: 'nm'), - arguments: [ - '-D', - assetUri.toFilePath(), - ], + arguments: ['-D', assetUri.toFilePath()], logger: logger, ); @@ -235,17 +232,11 @@ Future nmReadSymbols(CodeAsset asset) async { return result.stdout; } -Future expectSymbols({ - required CodeAsset asset, - required List symbols, -}) async { +Future expectSymbols({required CodeAsset asset, required List symbols}) async { if (Platform.isLinux) { final nmOutput = await nmReadSymbols(asset); - expect( - nmOutput, - stringContainsInOrder(symbols), - ); + expect(nmOutput, stringContainsInOrder(symbols)); } else { throw UnimplementedError(); } @@ -282,10 +273,7 @@ Future textSectionAddress(Uri dylib) async { throw UnimplementedError(); } -Future expectPageSize( - Uri dylib, - int pageSize, -) async { +Future expectPageSize(Uri dylib, int pageSize) async { if (Platform.isMacOS || Platform.isLinux) { // If page size is 16kb, the `.text` section address should be // above 0x4000. With smaller page sizes it's above 0x1000. diff --git a/test/native_toolchain/apple_clang_test.dart b/test/native_toolchain/apple_clang_test.dart index efe3a61..9a4bb5c 100644 --- a/test/native_toolchain/apple_clang_test.dart +++ b/test/native_toolchain/apple_clang_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('mac-os') -@OnPlatform({ - 'mac-os': Timeout.factor(2), -}) +@OnPlatform({'mac-os': Timeout.factor(2)}) library; import 'dart:io'; diff --git a/test/native_toolchain/cmake_test.dart b/test/native_toolchain/cmake_test.dart index 22da9a7..121f2fe 100644 --- a/test/native_toolchain/cmake_test.dart +++ b/test/native_toolchain/cmake_test.dart @@ -23,7 +23,7 @@ void main() { pathsSearched.add(path); return []; } - + setUp(() { mockSystemResolver = MockCliVersionResolver(); unitTestCmakeSystemResolver = mockSystemResolver; @@ -32,18 +32,18 @@ void main() { }); test('Android home not set', () async { - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final executableName = OS.current.executableFileName('cmake'); String expectedSearchPath = executableName; @@ -54,7 +54,7 @@ void main() { } else if (Platform.isWindows) { expectedSearchPath = r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + expectedSearchPath; } - + final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(pathsSearched.length, equals(1)); @@ -65,14 +65,17 @@ void main() { }); test('Android home is set', () async { - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -88,7 +91,7 @@ void main() { } else if (Platform.isWindows) { expectedSearchPath = r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + expectedSearchPath; } - + final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(pathsSearched.length, equals(2)); @@ -110,20 +113,26 @@ void main() { group('Android target: ', () { test('one Android cmake, any version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -132,30 +141,36 @@ void main() { }); test('many Android cmake, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('3.3.2') + version: Version.parse('3.3.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.0.1') + version: Version.parse('4.0.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(3)); @@ -164,26 +179,35 @@ void main() { }); test('many Android cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('3.3.2') + version: Version.parse('3.3.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.0.1') + version: Version.parse('4.0.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -197,40 +221,56 @@ void main() { }); test('one Android cmake, no system cmake, prefers system cmake', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, preferAndroidCmake: false, ); - expect(() async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); + expect( + () async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); }); test('no Android cmake, has system cmake', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer((_) => Future>(() => [])); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -239,16 +279,23 @@ void main() { }); test('no Android cmake, has system cmake, prefers Android cmake', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer((_) => Future>(() => [])); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -262,36 +309,47 @@ void main() { }); test('many Android cmake, has system cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('3.3.2') + version: Version.parse('3.3.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.2.2') + version: Version.parse('4.2.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.0.1') + version: Version.parse('4.0.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, - cmakeVersion: "4.1.2" + cmakeVersion: "4.1.2", ); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); @@ -303,55 +361,85 @@ void main() { group('iOS target: ', () { test('one Android cmake, no system cmake', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.iOS, envVarAndroidHomeAsDefault: false); + + expect( + () async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), ); - - expect(() async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); }); test('one Android cmake, no system cmake, do not prefer Android cmake', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, preferAndroidCmake: false, ); - expect(() async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); + expect( + () async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); }); test('one Android cmake, no system cmake, prefer Android cmake, any version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -365,16 +453,25 @@ void main() { }); test('one Android cmake, no system cmake, prefer Android cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -388,72 +485,112 @@ void main() { expect(tools.first.version, equals(Version.parse('4.1.2'))); }); - test('one Android cmake, no system cmake, prefer Android cmake, user defined version not found', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - preferAndroidCmake: true, - cmakeVersion: "4.1.3", - ); - expect(() async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); - }); - - test('one Android cmake, one system cmake, do not prefer Android cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') - ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - cmakeVersion: "4.1.2", - ); - final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + test( + 'one Android cmake, no system cmake, prefer Android cmake, user defined version not found', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('android_cmake_path_1'), + version: Version.parse('4.1.2'), + ), + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + preferAndroidCmake: true, + cmakeVersion: "4.1.3", + ); + expect( + () async => cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); + }, + ); - expect(tools.length, equals(1)); - expect(tools.first.uri, equals(Uri.dataFromString('system_cmake_path_1'))); - expect(tools.first.version, equals(Version.parse('4.1.2'))); - }); + test( + 'one Android cmake, one system cmake, do not prefer Android cmake, user defined version', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('android_cmake_path_1'), + version: Version.parse('4.1.2'), + ), + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('system_cmake_path_1'), + version: Version.parse('4.1.2'), + ), + ], + ), + ); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + cmakeVersion: "4.1.2", + ); + final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + + expect(tools.length, equals(1)); + expect(tools.first.uri, equals(Uri.dataFromString('system_cmake_path_1'))); + expect(tools.first.version, equals(Version.parse('4.1.2'))); + }, + ); test('one Android cmake, one system cmake, prefer Android cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -468,32 +605,43 @@ void main() { }); test('many Android cmake, one system cmake, prefer Android cmake, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.5') + version: Version.parse('4.1.5'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.1.4') + version: Version.parse('4.1.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.3') + version: Version.parse('4.1.3'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -507,36 +655,44 @@ void main() { }); test('many Android cmake, one system cmake, do not prefer Android cmake, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.5') + version: Version.parse('4.1.5'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.1.4') + version: Version.parse('4.1.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.3') + version: Version.parse('4.1.3'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.iOS, envVarAndroidHomeAsDefault: false); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -545,37 +701,48 @@ void main() { }); test('many Android cmake, one system cmake, prefer Android cmake, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2') + version: Version.parse('4.1.2'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.5') + version: Version.parse('4.1.5'), ), ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.1.4') + version: Version.parse('4.1.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'CMake'), uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.3') + version: Version.parse('4.1.3'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, preferAndroidCmake: true, - cmakeVersion: "4.1.4" + cmakeVersion: "4.1.4", ); final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); @@ -584,45 +751,59 @@ void main() { expect(tools.first.version, equals(Version.parse('4.1.4'))); }); - test('many Android cmake, one system cmake, prefer Android cmake, user defined dirty version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('android_cmake_path_1'), - version: Version.parse('4.1.2-rc0') - ), - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('android_cmake_path_2'), - version: Version.parse('4.1.2-rc4') - ), - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('android_cmake_path_3'), - version: Version.parse('4.1.4-dirty0') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'CMake'), - uri: Uri.dataFromString('system_cmake_path_1'), - version: Version.parse('4.1.3') - ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - preferAndroidCmake: true, - cmakeVersion: "4.1.4" - ); - final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); - - expect(tools.length, equals(1)); - expect(tools.first.uri, equals(Uri.dataFromString('android_cmake_path_3'))); - expect(tools.first.version, equals(Version.parse('4.1.4-dirty0'))); - }); + test( + 'many Android cmake, one system cmake, prefer Android cmake, user defined dirty version', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('android_cmake_path_1'), + version: Version.parse('4.1.2-rc0'), + ), + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('android_cmake_path_2'), + version: Version.parse('4.1.2-rc4'), + ), + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('android_cmake_path_3'), + version: Version.parse('4.1.4-dirty0'), + ), + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'CMake'), + uri: Uri.dataFromString('system_cmake_path_1'), + version: Version.parse('4.1.3'), + ), + ], + ), + ); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + preferAndroidCmake: true, + cmakeVersion: "4.1.4", + ); + final tools = await cmake.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + + expect(tools.length, equals(1)); + expect(tools.first.uri, equals(Uri.dataFromString('android_cmake_path_3'))); + expect(tools.first.version, equals(Version.parse('4.1.4-dirty0'))); + }, + ); }); }); } diff --git a/test/native_toolchain/gcc_test.dart b/test/native_toolchain/gcc_test.dart index 5a09a9f..374313e 100644 --- a/test/native_toolchain/gcc_test.dart +++ b/test/native_toolchain/gcc_test.dart @@ -23,17 +23,13 @@ void main() { void testToolSet(String name, List tools) { test('gcc cross compilation $name smoke test', () async { - final resolver = ToolResolvers([ - for (final tool in tools) tool.defaultResolver!, - ]); + final resolver = ToolResolvers([for (final tool in tools) tool.defaultResolver!]); final resolved = await resolver.resolve(logger: logger); printOnFailure(resolved.toString()); expect(resolved.isNotEmpty, true); - final requirement = RequireAll([ - for (final tool in tools) ToolRequirement(tool), - ]); + final requirement = RequireAll([for (final tool in tools) ToolRequirement(tool)]); final satisfied = requirement.satisfy(resolved); printOnFailure(tools.toString()); @@ -42,33 +38,13 @@ void main() { }); } - testToolSet('aarch64LinuxGnuGcc', [ - aarch64LinuxGnuGcc, - aarch64LinuxGnuGccAr, - aarch64LinuxGnuLd, - ]); + testToolSet('aarch64LinuxGnuGcc', [aarch64LinuxGnuGcc, aarch64LinuxGnuGccAr, aarch64LinuxGnuLd]); - testToolSet('armLinuxGnueabihfGcc', [ - armLinuxGnueabihfGcc, - armLinuxGnueabihfGccAr, - armLinuxGnueabihfLd, - ]); + testToolSet('armLinuxGnueabihfGcc', [armLinuxGnueabihfGcc, armLinuxGnueabihfGccAr, armLinuxGnueabihfLd]); - testToolSet('i686LinuxGnuGcc', [ - i686LinuxGnuGcc, - i686LinuxGnuGccAr, - i686LinuxGnuLd, - ]); + testToolSet('i686LinuxGnuGcc', [i686LinuxGnuGcc, i686LinuxGnuGccAr, i686LinuxGnuLd]); - testToolSet('x86_64LinuxGnuGcc', [ - x86_64LinuxGnuGcc, - x86_64LinuxGnuGccAr, - x86_64LinuxGnuLd, - ]); + testToolSet('x86_64LinuxGnuGcc', [x86_64LinuxGnuGcc, x86_64LinuxGnuGccAr, x86_64LinuxGnuLd]); - testToolSet('riscv64LinuxGnuGcc', [ - riscv64LinuxGnuGcc, - riscv64LinuxGnuGccAr, - riscv64LinuxGnuLd, - ]); + testToolSet('riscv64LinuxGnuGcc', [riscv64LinuxGnuGcc, riscv64LinuxGnuGccAr, riscv64LinuxGnuLd]); } diff --git a/test/native_toolchain/ninja_test.dart b/test/native_toolchain/ninja_test.dart index fb5c858..c1d9af0 100644 --- a/test/native_toolchain/ninja_test.dart +++ b/test/native_toolchain/ninja_test.dart @@ -23,7 +23,7 @@ void main() { pathsSearched.add(path); return []; } - + setUp(() { mockSystemResolver = MockCliVersionResolver(); unitTestNinjaSystemResolver = mockSystemResolver; @@ -32,18 +32,18 @@ void main() { }); test('Android home not set', () async { - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final executableName = OS.current.executableFileName('ninja'); String expectedSearchPath = executableName; @@ -54,7 +54,7 @@ void main() { } else if (Platform.isWindows) { expectedSearchPath = r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + expectedSearchPath; } - + final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(pathsSearched.length, equals(1)); @@ -65,14 +65,17 @@ void main() { }); test('Android home is set', () async { - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -88,7 +91,7 @@ void main() { } else if (Platform.isWindows) { expectedSearchPath = r'$HOME/AppData/Local/Android/Sdk/cmake/*/bin/' + expectedSearchPath; } - + final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(pathsSearched.length, equals(2)); @@ -110,20 +113,26 @@ void main() { group('Android target: ', () { test('one Android ninja, any version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -132,30 +141,36 @@ void main() { }); test('many Android ninja, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.2') + version: Version.parse('1.12.2'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.13.1') + version: Version.parse('1.13.1'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(3)); @@ -164,26 +179,35 @@ void main() { }); test('many Android ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.13.2') + version: Version.parse('1.13.2'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.11.1') + version: Version.parse('1.11.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -197,40 +221,56 @@ void main() { }); test('one Android ninja, no system ninja, prefers system ninja', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, preferAndroidNinja: false, ); - expect(() async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); + expect( + () async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); }); test('no Android ninja, has system ninja', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer((_) => Future>(() => [])); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.android, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.android, envVarAndroidHomeAsDefault: false); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -239,16 +279,23 @@ void main() { }); test('no Android ninja, has system ninja, prefers Android ninja', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer((_) => Future>(() => [])); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, @@ -262,36 +309,47 @@ void main() { }); test('many Android ninja, has system ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.13.2') + version: Version.parse('1.13.2'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.12.2') + version: Version.parse('1.12.2'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.10.1') + version: Version.parse('1.10.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.android, envVarAndroidHomeAsDefault: false, - ninjaVersion: "1.12.1" + ninjaVersion: "1.12.1", ); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); @@ -303,55 +361,85 @@ void main() { group('iOS target: ', () { test('one Android ninja, no system ninja', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig(targetOS: OS.iOS, envVarAndroidHomeAsDefault: false); + + expect( + () async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), ); - - expect(() async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); }); test('one Android ninja, no system ninja, do not prefer Android ninja', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, preferAndroidNinja: false, ); - expect(() async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); + expect( + () async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); }); test('one Android ninja, no system ninja, prefer Android ninja, any version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -365,16 +453,25 @@ void main() { }); test('one Android ninja, no system ninja, prefer Android ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -388,72 +485,112 @@ void main() { expect(tools.first.version, equals(Version.parse('1.12.1'))); }); - test('one Android ninja, no system ninja, prefer Android ninja, user defined version not found', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - preferAndroidNinja: true, - ninjaVersion: "1.12.3", - ); - expect(() async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), throwsA(isA())); - }); - - test('one Android ninja, one system ninja, do not prefer Android ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') - ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - ninjaVersion: "1.12.1", - ); - final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + test( + 'one Android ninja, no system ninja, prefer Android ninja, user defined version not found', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('android_ninja_path_1'), + version: Version.parse('1.12.1'), + ), + ], + ), + ); + when( + () => mockSystemResolver.resolve(logger: any(named: 'logger')), + ).thenAnswer((_) => Future>(() => [])); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + preferAndroidNinja: true, + ninjaVersion: "1.12.3", + ); + expect( + () async => ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig), + throwsA(isA()), + ); + }, + ); - expect(tools.length, equals(1)); - expect(tools.first.uri, equals(Uri.dataFromString('system_ninja_path_1'))); - expect(tools.first.version, equals(Version.parse('1.12.1'))); - }); + test( + 'one Android ninja, one system ninja, do not prefer Android ninja, user defined version', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('android_ninja_path_1'), + version: Version.parse('1.12.1'), + ), + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('system_ninja_path_1'), + version: Version.parse('1.12.1'), + ), + ], + ), + ); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + ninjaVersion: "1.12.1", + ); + final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + + expect(tools.length, equals(1)); + expect(tools.first.uri, equals(Uri.dataFromString('system_ninja_path_1'))); + expect(tools.first.version, equals(Version.parse('1.12.1'))); + }, + ); test('one Android ninja, one system ninja, prefer Android ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -468,32 +605,43 @@ void main() { }); test('many Android ninja, one system ninja, prefer Android ninja, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.15.5') + version: Version.parse('1.15.5'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.14.4') + version: Version.parse('1.14.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.13.3') + version: Version.parse('1.13.3'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, @@ -507,36 +655,44 @@ void main() { }); test('many Android ninja, one system ninja, do not prefer Android ninja, latest version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.15.5') + version: Version.parse('1.15.5'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.11.4') + version: Version.parse('1.11.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.13.3') + version: Version.parse('1.13.3'), ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, + ], + ), ); + final userConfig = UserConfig(targetOS: OS.iOS, envVarAndroidHomeAsDefault: false); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); expect(tools.length, equals(1)); @@ -545,37 +701,48 @@ void main() { }); test('many Android ninja, one system ninja, prefer Android ninja, user defined version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1') + version: Version.parse('1.12.1'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.14.5') + version: Version.parse('1.14.5'), ), ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.14.4') + version: Version.parse('1.14.4'), ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ ToolInstance( tool: Tool(name: 'Ninja'), uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.14.3') + version: Version.parse('1.14.3'), ), - ])); + ], + ), + ); final userConfig = UserConfig( targetOS: OS.iOS, envVarAndroidHomeAsDefault: false, preferAndroidNinja: true, - ninjaVersion: "1.14.4" + ninjaVersion: "1.14.4", ); final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); @@ -584,45 +751,59 @@ void main() { expect(tools.first.version, equals(Version.parse('1.14.4'))); }); - test('many Android ninja, one system ninja, prefer Android ninja, user defined dirty version', () async { - when(() => mockAndroidResolver.resolve(logger: any(named: 'logger'), userConfig: any(named: 'userConfig'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('android_ninja_path_1'), - version: Version.parse('1.12.1-rc0') - ), - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('android_ninja_path_2'), - version: Version.parse('1.12.1-rc4') - ), - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('android_ninja_path_3'), - version: Version.parse('1.14.4-dirty0') - ), - ])); - when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))) - .thenAnswer((_) => Future>(() => [ - ToolInstance( - tool: Tool(name: 'Ninja'), - uri: Uri.dataFromString('system_ninja_path_1'), - version: Version.parse('1.13.3') - ), - ])); - final userConfig = UserConfig( - targetOS: OS.iOS, - envVarAndroidHomeAsDefault: false, - preferAndroidNinja: true, - ninjaVersion: "1.14.4" - ); - final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); - - expect(tools.length, equals(1)); - expect(tools.first.uri, equals(Uri.dataFromString('android_ninja_path_3'))); - expect(tools.first.version, equals(Version.parse('1.14.4-dirty0'))); - }); + test( + 'many Android ninja, one system ninja, prefer Android ninja, user defined dirty version', + () async { + when( + () => mockAndroidResolver.resolve( + logger: any(named: 'logger'), + userConfig: any(named: 'userConfig'), + ), + ).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('android_ninja_path_1'), + version: Version.parse('1.12.1-rc0'), + ), + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('android_ninja_path_2'), + version: Version.parse('1.12.1-rc4'), + ), + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('android_ninja_path_3'), + version: Version.parse('1.14.4-dirty0'), + ), + ], + ), + ); + when(() => mockSystemResolver.resolve(logger: any(named: 'logger'))).thenAnswer( + (_) => Future>( + () => [ + ToolInstance( + tool: Tool(name: 'Ninja'), + uri: Uri.dataFromString('system_ninja_path_1'), + version: Version.parse('1.13.3'), + ), + ], + ), + ); + final userConfig = UserConfig( + targetOS: OS.iOS, + envVarAndroidHomeAsDefault: false, + preferAndroidNinja: true, + ninjaVersion: "1.14.4", + ); + final tools = await ninja.defaultResolver!.resolve(logger: logger, userConfig: userConfig); + + expect(tools.length, equals(1)); + expect(tools.first.uri, equals(Uri.dataFromString('android_ninja_path_3'))); + expect(tools.first.version, equals(Version.parse('1.14.4-dirty0'))); + }, + ); }); }); } diff --git a/test/native_toolchain/recognizer_test.dart b/test/native_toolchain/recognizer_test.dart index 23cf37f..2a08364 100644 --- a/test/native_toolchain/recognizer_test.dart +++ b/test/native_toolchain/recognizer_test.dart @@ -87,9 +87,7 @@ class RecognizerTest { Future setUp() async { toolInstance = (await tool.defaultResolver!.resolve( logger: null /* no printOnFailure support in setup. */, - )) - .where((element) => element.tool == tool) - .firstOrNull; + )).where((element) => element.tool == tool).firstOrNull; } void addTest() { @@ -100,13 +98,10 @@ class RecognizerTest { return; } - test( - 'recognize ${tool.name}', - () async { - final recognizer_ = recognizer(toolInstance!.uri); - final toolInstanceAgain = (await recognizer_.resolve(logger: logger)).first; - expect(toolInstanceAgain, toolInstance); - }, - ); + test('recognize ${tool.name}', () async { + final recognizer_ = recognizer(toolInstance!.uri); + final toolInstanceAgain = (await recognizer_.resolve(logger: logger)).first; + expect(toolInstanceAgain, toolInstance); + }); } } diff --git a/test/native_toolchain/xcode_test.dart b/test/native_toolchain/xcode_test.dart index 23970d8..af87b09 100644 --- a/test/native_toolchain/xcode_test.dart +++ b/test/native_toolchain/xcode_test.dart @@ -3,9 +3,7 @@ // BSD-style license that can be found in the LICENSE file. @TestOn('mac-os') -@OnPlatform({ - 'mac-os': Timeout.factor(2), -}) +@OnPlatform({'mac-os': Timeout.factor(2)}) library; import 'dart:io'; @@ -29,20 +27,23 @@ void main() { }); test('macosxSdk', () async { - final resolved = - (await macosxSdk.defaultResolver!.resolve(logger: logger)).where((i) => i.tool == macosxSdk); + final resolved = (await macosxSdk.defaultResolver!.resolve( + logger: logger, + )).where((i) => i.tool == macosxSdk); expect(resolved.isNotEmpty, true); }); test('iPhoneOSSdk', () async { - final resolved = - (await iPhoneOSSdk.defaultResolver!.resolve(logger: logger)).where((i) => i.tool == iPhoneOSSdk); + final resolved = (await iPhoneOSSdk.defaultResolver!.resolve( + logger: logger, + )).where((i) => i.tool == iPhoneOSSdk); expect(resolved.isNotEmpty, true); }); test('iPhoneSimulatorSdk', () async { - final resolved = (await iPhoneSimulatorSdk.defaultResolver!.resolve(logger: logger)) - .where((i) => i.tool == iPhoneSimulatorSdk); + final resolved = (await iPhoneSimulatorSdk.defaultResolver!.resolve( + logger: logger, + )).where((i) => i.tool == iPhoneSimulatorSdk); expect(resolved.isNotEmpty, true); }); diff --git a/test/tool/tool_instance_test.dart b/test/tool/tool_instance_test.dart index 9f8bce6..60a19a0 100644 --- a/test/tool/tool_instance_test.dart +++ b/test/tool/tool_instance_test.dart @@ -10,8 +10,14 @@ import 'package:test/test.dart'; void main() { test('equals and hashCode', () { - final barToolInstance = ToolInstance(tool: Tool(name: 'bar'), uri: Uri.file('path/to/bar')); - final fooToolInstance = ToolInstance(tool: Tool(name: 'foo'), uri: Uri.file('path/to/foo')); + final barToolInstance = ToolInstance( + tool: Tool(name: 'bar'), + uri: Uri.file('path/to/bar'), + ); + final fooToolInstance = ToolInstance( + tool: Tool(name: 'foo'), + uri: Uri.file('path/to/foo'), + ); expect(barToolInstance, barToolInstance); expect(barToolInstance != fooToolInstance, true); @@ -20,9 +26,18 @@ void main() { expect(barToolInstance.hashCode != fooToolInstance.hashCode, true); expect( - ToolInstance(tool: Tool(name: 'bar'), version: Version(1, 0, 0), uri: Uri.file('path/to/bar')) != - ToolInstance(tool: Tool(name: 'bar'), version: Version(1, 0, 1), uri: Uri.file('path/to/bar')), - true); + ToolInstance( + tool: Tool(name: 'bar'), + version: Version(1, 0, 0), + uri: Uri.file('path/to/bar'), + ) != + ToolInstance( + tool: Tool(name: 'bar'), + version: Version(1, 0, 1), + uri: Uri.file('path/to/bar'), + ), + true, + ); }); test('compareTo', () { @@ -32,7 +47,11 @@ void main() { version: Version(2, 0, 0), uri: Uri.file('path/to/bar'), ), - ToolInstance(tool: Tool(name: 'bar'), version: Version(1, 0, 0), uri: Uri.file('path/to/bar')), + ToolInstance( + tool: Tool(name: 'bar'), + version: Version(1, 0, 0), + uri: Uri.file('path/to/bar'), + ), ToolInstance( tool: Tool(name: 'bar'), uri: Uri.file('path/to/bar'), @@ -48,10 +67,7 @@ void main() { ]; final toolInstancesSorted = [...toolInstances]..sort(); - expect( - const DeepCollectionEquality().equals(toolInstancesSorted, toolInstances), - true, - ); + expect(const DeepCollectionEquality().equals(toolInstancesSorted, toolInstances), true); }); test('toString', () { diff --git a/test/tool/tool_requirement_test.dart b/test/tool/tool_requirement_test.dart index 1b4614c..3b4d7f4 100644 --- a/test/tool/tool_requirement_test.dart +++ b/test/tool/tool_requirement_test.dart @@ -33,15 +33,12 @@ void main() { ), ]; final result = requirement.satisfy(toolInstances); - expect( - result, - [ - ToolInstance( - tool: Tool(name: 'bar'), - version: Version(10, 0, 0), - uri: Uri.file('path/to/bar'), - ) - ], - ); + expect(result, [ + ToolInstance( + tool: Tool(name: 'bar'), + version: Version(10, 0, 0), + uri: Uri.file('path/to/bar'), + ), + ]); }); } diff --git a/test/tool/tool_resolver_test.dart b/test/tool/tool_resolver_test.dart index 0b34bc0..24618c8 100644 --- a/test/tool/tool_resolver_test.dart +++ b/test/tool/tool_resolver_test.dart @@ -25,9 +25,7 @@ void main() { ]; expect(toolInstances.isNotEmpty, true); final toolInstance = toolInstances.first; - final versionArguments = [ - if (toolInstance.tool != cl) '--version', - ]; + final versionArguments = [if (toolInstance.tool != cl) '--version']; final version = await CliVersionResolver.executableVersion( toolInstance.uri, arguments: versionArguments, @@ -66,25 +64,26 @@ void main() { await File.fromUri(bazExeUri).writeAsString('dummy'); expect(await File.fromUri(barExeUri).exists(), true); expect(await File.fromUri(bazExeUri).exists(), true); - final barResolver = InstallLocationResolver( - toolName: 'bar', - paths: [barExeUri.toFilePath().unescape()], - ); + final barResolver = InstallLocationResolver(toolName: 'bar', paths: [barExeUri.toFilePath().unescape()]); final bazResolver = RelativeToolResolver( toolName: 'baz', wrappedResolver: barResolver, relativePath: Uri.file(bazExeName), ); final resolvedBarInstances = await barResolver.resolve(logger: logger); - expect( - resolvedBarInstances, - [ToolInstance(tool: Tool(name: 'bar'), uri: barExeUri)], - ); + expect(resolvedBarInstances, [ + ToolInstance( + tool: Tool(name: 'bar'), + uri: barExeUri, + ), + ]); final resolvedBazInstances = await bazResolver.resolve(logger: logger); - expect( - resolvedBazInstances, - [ToolInstance(tool: Tool(name: 'baz'), uri: bazExeUri)], - ); + expect(resolvedBazInstances, [ + ToolInstance( + tool: Tool(name: 'baz'), + uri: bazExeUri, + ), + ]); }); test('logger', () async { diff --git a/test/tool/tool_test.dart b/test/tool/tool_test.dart index d36f74d..751c436 100644 --- a/test/tool/tool_test.dart +++ b/test/tool/tool_test.dart @@ -23,12 +23,18 @@ void main() { expect(clang != androidNdk, true); expect( Tool(name: 'foo'), - Tool(name: 'foo', defaultResolver: PathToolResolver(toolName: 'foo')), + Tool( + name: 'foo', + defaultResolver: PathToolResolver(toolName: 'foo'), + ), ); expect(Tool(name: 'foo') != Tool(name: 'bar'), true); expect( Tool(name: 'foo').hashCode, - Tool(name: 'foo', defaultResolver: PathToolResolver(toolName: 'foo')).hashCode, + Tool( + name: 'foo', + defaultResolver: PathToolResolver(toolName: 'foo'), + ).hashCode, ); expect(Tool(name: 'foo').hashCode != Tool(name: 'bar').hashCode, true); }); diff --git a/test/utils/run_process_test.dart b/test/utils/run_process_test.dart index ad69a38..730f8fa 100644 --- a/test/utils/run_process_test.dart +++ b/test/utils/run_process_test.dart @@ -57,13 +57,7 @@ void main() { assert(cm != null); final result = await runProcess( executable: cm!.uri, - arguments: [ - "-S", - srcDir.path, - "-B", - dstDir.path, - "-DCMAKE_INSTALL_PREFIX=install", - ], + arguments: ["-S", srcDir.path, "-B", dstDir.path, "-DCMAKE_INSTALL_PREFIX=install"], logger: logger, captureOutput: true, throwOnUnexpectedExitCode: false, From f316bc4c566891e16044e71a59598f94f871b999 Mon Sep 17 00:00:00 2001 From: Moritz Date: Thu, 16 Jul 2026 13:51:18 +0000 Subject: [PATCH 2/3] add run standalone --- example/add/bin/add.dart | 1 + example/flutter/analysis_options.yaml | 10 ++ lib/src/builder/builder.dart | 104 ++++++++++++------ lib/src/builder/run_builder.dart | 67 ++++++----- lib/src/native_toolchain/msvc.dart | 9 +- lib/src/utils/env_from_native_config.dart | 22 ++-- lib/src/utils/package_config_parser.dart | 36 +++--- lib/src/utils/run_process.dart | 3 +- .../cmake_builder_cross_android_test.dart | 2 +- .../cmake_builder_standalone_test.dart | 67 +++++++++++ test/helpers.dart | 2 +- test/native_toolchain/clang_test.dart | 2 +- test/utils/run_process_test.dart | 2 +- 13 files changed, 232 insertions(+), 95 deletions(-) create mode 100644 test/builder/cmake_builder_standalone_test.dart diff --git a/example/add/bin/add.dart b/example/add/bin/add.dart index b4adebc..ceb21d3 100644 --- a/example/add/bin/add.dart +++ b/example/add/bin/add.dart @@ -1,5 +1,6 @@ import 'package:add/add.dart'; void main() { + // ignore: avoid_print print(calculate(7, 7, times: 3)); } diff --git a/example/flutter/analysis_options.yaml b/example/flutter/analysis_options.yaml index 0d29021..efa5b00 100644 --- a/example/flutter/analysis_options.yaml +++ b/example/flutter/analysis_options.yaml @@ -7,6 +7,16 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** + include: package:flutter_lints/flutter.yaml linter: diff --git a/lib/src/builder/builder.dart b/lib/src/builder/builder.dart index adea7bd..17888e2 100644 --- a/lib/src/builder/builder.dart +++ b/lib/src/builder/builder.dart @@ -110,7 +110,7 @@ class CMakeBuilder implements Builder { /// defaults to `false`. CMakeBuilder.create({ required this.name, - required this.sourceDir, + required Uri sourceDir, this.outDir, this.defines = const {}, this.buildMode = BuildMode.release, @@ -125,7 +125,8 @@ class CMakeBuilder implements Builder { this.useVcvars = true, this.parallelJobs, this.parallelUseAllProcessors = false, - }) : cmakeListsDir = sourceDir; + }) : sourceDir = sourceDir.isAbsolute ? sourceDir : Directory.fromUri(sourceDir).absolute.uri, + cmakeListsDir = sourceDir.isAbsolute ? sourceDir : Directory.fromUri(sourceDir).absolute.uri; /// This constructor initializes a new build config by cloning the /// repository from [gitUrl] into a subdirectory under [sourceDir]. @@ -159,7 +160,7 @@ class CMakeBuilder implements Builder { CMakeBuilder.fromGit({ required this.name, required String gitUrl, - required this.sourceDir, + required Uri sourceDir, this.outDir, String gitBranch = 'main', String gitCommit = 'FETCH_HEAD', @@ -177,9 +178,10 @@ class CMakeBuilder implements Builder { this.useVcvars = true, this.parallelJobs, this.parallelUseAllProcessors = false, - }) : cmakeListsDir = sourceDir { + }) : sourceDir = sourceDir.isAbsolute ? sourceDir : Directory.fromUri(sourceDir).absolute.uri, + cmakeListsDir = sourceDir.isAbsolute ? sourceDir : Directory.fromUri(sourceDir).absolute.uri { // Some platforms will error if directory does not exist, create it. - cmakeListsDir = sourceDir.resolve('external/$name/').normalizePath(); + cmakeListsDir = this.sourceDir.resolve('external/$name/').normalizePath(); Directory.fromUri(cmakeListsDir).createSync(recursive: true); runProcessSync( @@ -229,18 +231,55 @@ class CMakeBuilder implements Builder { Logger? logger, bool skipGenerateIfCached = false, }) async { + await runStandalone( + outputDirectory: input.outputDirectory, + targetOS: input.config.code.targetOS, + targetArchitecture: input.config.code.targetArchitecture, + packageRoot: input.packageRoot, + android: input.config.code.targetOS == OS.android ? input.config.code.android : null, + iOS: input.config.code.targetOS == OS.iOS ? input.config.code.iOS : null, + macOS: input.config.code.targetOS == OS.macOS ? input.config.code.macOS : null, + logger: logger, + userDefines: input.json['user_defines'] as Map? ?? const {}, + input: input, + skipGenerateIfCached: skipGenerateIfCached, + ); + } + + /// Runs the CMake generate and build process with explicit arguments instead + /// of [BuildInput] or [BuildOutputBuilder]. + /// + /// Useful for standalone build scripts outside of `hook/build.dart`. + Future runStandalone({ + required Uri outputDirectory, + OS? targetOS, + Architecture? targetArchitecture, + Uri? packageRoot, + AndroidCodeConfig? android, + IOSCodeConfig? iOS, + MacOSCodeConfig? macOS, + Logger? logger, + Map? userDefines, + BuildInput? input, + bool skipGenerateIfCached = false, + }) async { + targetOS ??= OS.current; + targetArchitecture ??= Architecture.current; + logger ??= this.logger; + userDefines ??= const {}; + // do not override user specified output directory if they also set buildLocal to true if (outDir == null && buildLocal) { - final os = input.config.code.targetOS; - var plat = os.name.toLowerCase(); + var plat = targetOS.name.toLowerCase(); // ios-simulator has both x86_64 and arm64, ios/arm64 is ambiguous - if (os == OS.iOS && input.config.code.iOS.targetSdk == IOSSdk.iPhoneSimulator) { + if (targetOS == OS.iOS && iOS?.targetSdk == IOSSdk.iPhoneSimulator) { plat = "iossimulator"; } - final arch = input.config.code.targetArchitecture.name.toLowerCase(); + final arch = targetArchitecture.name.toLowerCase(); outDir = sourceDir.resolve('build/').resolve('$plat/').resolve(arch).normalizePath(); } - await Directory.fromUri(outDir ?? input.outputDirectory).create(recursive: true); + final effectiveOutDir = outDir ?? outputDirectory; + await Directory.fromUri(effectiveOutDir).create(recursive: true); // hooks: // user_defines: @@ -257,14 +296,14 @@ class CMakeBuilder implements Builder { // ninja_version: null # "1.10.2" // windows: // cmake_version: null # "3.31.6" - final androidConfig = input.userDefines["android"] as Map?; - final iosConfig = input.userDefines["ios"] as Map?; - final linuxConfig = input.userDefines["linux"] as Map?; - final macOSConfig = input.userDefines["macos"] as Map?; - final windowsConfig = input.userDefines["windows"] as Map?; - - var cmakeVersion = input.userDefines["cmake_version"] as String?; - cmakeVersion = switch (input.config.code.targetOS) { + final androidConfig = userDefines["android"] as Map?; + final iosConfig = userDefines["ios"] as Map?; + final linuxConfig = userDefines["linux"] as Map?; + final macOSConfig = userDefines["macos"] as Map?; + final windowsConfig = userDefines["windows"] as Map?; + + var cmakeVersion = userDefines["cmake_version"] as String?; + cmakeVersion = switch (targetOS) { OS.android => androidConfig?["cmake_version"] as String? ?? cmakeVersion, OS.iOS => iosConfig?["cmake_version"] as String? ?? cmakeVersion, OS.linux => linuxConfig?["cmake_version"] as String? ?? cmakeVersion, @@ -273,8 +312,8 @@ class CMakeBuilder implements Builder { _ => cmakeVersion, }; - var ninjaVersion = input.userDefines["ninja_version"] as String?; - ninjaVersion = switch (input.config.code.targetOS) { + var ninjaVersion = userDefines["ninja_version"] as String?; + ninjaVersion = switch (targetOS) { OS.android => androidConfig?["ninja_version"] as String? ?? ninjaVersion, OS.iOS => iosConfig?["ninja_version"] as String? ?? ninjaVersion, OS.linux => linuxConfig?["ninja_version"] as String? ?? ninjaVersion, @@ -284,20 +323,20 @@ class CMakeBuilder implements Builder { }; var userConfig = UserConfig( - targetOS: input.config.code.targetOS, + targetOS: targetOS, cmakeVersion: cmakeVersion, ninjaVersion: ninjaVersion, ndkVersion: androidConfig?["ndk_version"] as String?, androidHome: androidConfig?["android_home"] as String?, - preferAndroidNinja: input.userDefines["prefer_android_ninja"] as bool?, - preferAndroidCmake: input.userDefines["prefer_android_cmake"] as bool?, + preferAndroidNinja: userDefines["prefer_android_ninja"] as bool?, + preferAndroidCmake: userDefines["prefer_android_cmake"] as bool?, ); // optional host specific build config - final envFile = input.userDefines["env_file"] as String?; + final envFile = userDefines["env_file"] as String?; if (envFile != null) { - final userEnvConfig = await getUserEnvConfig(input: input, envFile: envFile); + final userEnvConfig = await getUserEnvConfig(input: input, packageRoot: packageRoot, envFile: envFile); final androidHome = userEnvConfig['ANDROID_HOME']; if (androidHome != null) { final androidHomeEntity = Directory(androidHome); @@ -312,10 +351,13 @@ class CMakeBuilder implements Builder { } final task = RunCMakeBuilder( - input: input, - outputDir: outDir, - codeConfig: input.config.code, - logger: logger ?? this.logger, + targetOS: targetOS, + targetArchitecture: targetArchitecture, + android: android, + iOS: iOS, + macOS: macOS, + outDir: effectiveOutDir, + logger: logger, sourceDir: cmakeListsDir, generator: generator, buildMode: buildMode, @@ -334,8 +376,8 @@ class CMakeBuilder implements Builder { if (useVcvars) { envVars.addAll( await environmentFromVcvars( - targetOS: input.config.code.targetOS, - targetArchitecture: input.config.code.targetArchitecture, + targetOS: targetOS, + targetArchitecture: targetArchitecture, logger: logger, ), ); diff --git a/lib/src/builder/run_builder.dart b/lib/src/builder/run_builder.dart index 53a95ff..5547552 100644 --- a/lib/src/builder/run_builder.dart +++ b/lib/src/builder/run_builder.dart @@ -11,7 +11,6 @@ import 'dart:math'; import 'package:change_case/change_case.dart'; import 'package:code_assets/code_assets.dart'; -import 'package:hooks/hooks.dart'; import 'package:logging/logging.dart'; import 'package:pub_semver/pub_semver.dart'; @@ -29,8 +28,11 @@ import 'log_level.dart'; import 'user_config.dart'; class RunCMakeBuilder { - final HookInput input; - final CodeConfig codeConfig; + final OS targetOS; + final Architecture targetArchitecture; + final AndroidCodeConfig? android; + final IOSCodeConfig? iOS; + final MacOSCodeConfig? macOS; final Logger? logger; final Uri sourceDir; final Uri outDir; @@ -70,9 +72,13 @@ class RunCMakeBuilder { final bool parallelUseAllProcessors; RunCMakeBuilder({ - required this.input, - required this.codeConfig, required this.sourceDir, + required this.outDir, + OS? targetOS, + Architecture? targetArchitecture, + this.android, + this.iOS, + this.macOS, this.logger, this.defines = const {}, this.generator = Generator.defaultGenerator, @@ -85,10 +91,11 @@ class RunCMakeBuilder { this.lastGenStatusFile = 'ntc_last_generate_status.txt', this.parallelUseAllProcessors = false, int? parallelJobs, - Uri? outputDir, UserConfig? userConfig, - }) : outDir = outputDir ?? input.outputDirectory, - userConfig = userConfig ?? UserConfig(targetOS: codeConfig.targetOS), + CodeConfig? codeConfig, + }) : targetOS = targetOS ?? codeConfig?.targetOS ?? OS.current, + targetArchitecture = targetArchitecture ?? codeConfig?.targetArchitecture ?? Architecture.current, + userConfig = userConfig ?? UserConfig(targetOS: targetOS ?? codeConfig?.targetOS ?? OS.current), parallelJobs = parallelJobs ?? (parallelUseAllProcessors ? Platform.numberOfProcessors : null); Future cmakePath({Map? environment}) async { @@ -128,11 +135,11 @@ class RunCMakeBuilder { return Future.value(toolUri); } - Future linuxToolchainCmake() async => switch (codeConfig.targetArchitecture) { + Future linuxToolchainCmake() async => switch (targetArchitecture) { Architecture.x64 => (await currentPackageRoot()).resolve('cmake/x86_64-linux-gnu.toolchain.cmake'), Architecture.arm64 => (await currentPackageRoot()).resolve('cmake/aarch64-linux-gnu.toolchain.cmake'), Architecture.riscv64 => (await currentPackageRoot()).resolve('cmake/riscv64-linux-gnu.toolchain.cmake'), - _ => throw UnimplementedError('Unsupported architecture: ${codeConfig.targetArchitecture} for Linux'), + _ => throw UnimplementedError('Unsupported architecture: $targetArchitecture for Linux'), }; Future iosSdk(IOSSdk iosSdk, {required Logger? logger}) async { @@ -187,13 +194,13 @@ class RunCMakeBuilder { } Future _generate({Map? environment}) async { - final defs = switch (codeConfig.targetOS) { + final defs = switch (targetOS) { OS.windows => await _generateWindowsDefines(), OS.linux => await _generateLinuxDefines(), OS.macOS => await _generateMacosDefines(), OS.iOS => await _generateIOSDefines(), OS.android => await _generateAndroidDefines(), - _ => throw UnimplementedError('Unsupported OS: ${codeConfig.targetOS}'), + _ => throw UnimplementedError('Unsupported OS: $targetOS'), }; final _defines = [ @@ -281,16 +288,16 @@ class RunCMakeBuilder { } Future> _generateMacosDefines() async { - if (codeConfig.targetOS != OS.macOS) { + if (targetOS != OS.macOS) { return []; } final defs = []; final toolchain = await iosToolchainCmake(); defs.add('-DCMAKE_TOOLCHAIN_FILE=${toolchain.normalizePath().toFilePath()}'); - final platform = macosPlatforms[codeConfig.targetArchitecture]; - assert(platform != null, 'Unsupported macOS architecture: ${codeConfig.targetArchitecture}'); + final platform = macosPlatforms[targetArchitecture]; + assert(platform != null, 'Unsupported macOS architecture: $targetArchitecture'); defs.add('-DPLATFORM=$platform'); - defs.add('-DDEPLOYMENT_TARGET=${codeConfig.macOS.targetVersion}'); + defs.add('-DDEPLOYMENT_TARGET=${macOS?.targetVersion ?? "10.15"}'); defs.add('-DENABLE_BITCODE=${appleArgs.enableBitcode ? "ON" : "OFF"}'); defs.add('-DENABLE_ARC=${appleArgs.enableArc ? "ON" : "OFF"}'); defs.add('-DENABLE_VISIBILITY=${appleArgs.enableVisibility ? "ON" : "OFF"}'); @@ -299,16 +306,16 @@ class RunCMakeBuilder { } Future> _generateIOSDefines() async { - if (codeConfig.targetOS != OS.iOS) { + if (targetOS != OS.iOS) { return []; } final defs = []; - final targetIosSdk = codeConfig.iOS.targetSdk; - final targetIOSVersion = codeConfig.iOS.targetVersion; + final targetIosSdk = iOS?.targetSdk ?? IOSSdk.iPhoneOS; + final targetIOSVersion = iOS?.targetVersion ?? '12.0'; final toolchain = await iosToolchainCmake(); defs.add('-DCMAKE_TOOLCHAIN_FILE=${toolchain.normalizePath().toFilePath()}'); - final platform = iosPlatforms[codeConfig.targetArchitecture]?[targetIosSdk]; - assert(platform != null, 'Unsupported iOS architecture: ${codeConfig.targetArchitecture}'); + final platform = iosPlatforms[targetArchitecture]?[targetIosSdk]; + assert(platform != null, 'Unsupported iOS architecture: $targetArchitecture'); defs.add('-DPLATFORM=$platform'); defs.add('-DDEPLOYMENT_TARGET=$targetIOSVersion'); defs.add('-DENABLE_BITCODE=${appleArgs.enableBitcode ? "ON" : "OFF"}'); @@ -319,7 +326,7 @@ class RunCMakeBuilder { } Future> _generateAndroidDefines() async { - if (codeConfig.targetOS != OS.android) { + if (targetOS != OS.android) { return []; } final defs = []; @@ -331,9 +338,9 @@ class RunCMakeBuilder { // The Android Gradle plugin does not honor API level 19 and 20 when // invoking clang. Mimic that behavior here. // See https://github.com/dart-lang/native/issues/171. - final minimumApi = codeConfig.targetArchitecture == Architecture.riscv64 ? 35 : 21; - final _androidAPI = androidArgs.androidAPI ?? max(codeConfig.android.targetNdkApi, minimumApi); - final _androidABI = androidArgs.androidABI ?? androidAbis[codeConfig.targetArchitecture]; + final minimumApi = targetArchitecture == Architecture.riscv64 ? 35 : 21; + final _androidAPI = androidArgs.androidAPI ?? max(android?.targetNdkApi ?? 21, minimumApi); + final _androidABI = androidArgs.androidABI ?? androidAbis[targetArchitecture]; defs.add('-DANDROID_PLATFORM=android-$_androidAPI'); defs.add('-DANDROID_ABI=$_androidABI'); defs.add('-DANDROID_STL=${androidArgs.androidSTL}'); @@ -343,7 +350,7 @@ class RunCMakeBuilder { } Future> _generateWindowsDefines() async { - if (codeConfig.targetOS != OS.windows) { + if (targetOS != OS.windows) { return []; } final defs = []; @@ -351,15 +358,15 @@ class RunCMakeBuilder { // Generators besides Visual Studio do not support the -A argument. if (generator == Generator.defaultGenerator || generator.name.startsWith("Visual Studio")) { - if (codeConfig.targetArchitecture == Architecture.arm64) { + if (targetArchitecture == Architecture.arm64) { defs.add('-DCMAKE_SYSTEM_PROCESSOR=ARM64'); defs.addAll(['-A', 'ARM64']); } - if (codeConfig.targetArchitecture == Architecture.x64) { + if (targetArchitecture == Architecture.x64) { defs.add('-DCMAKE_SYSTEM_PROCESSOR=AMD64'); defs.addAll(['-A', 'x64']); } - if (codeConfig.targetArchitecture == Architecture.ia32) { + if (targetArchitecture == Architecture.ia32) { defs.add('-DCMAKE_SYSTEM_PROCESSOR=X86'); defs.addAll(['-A', 'Win32']); } @@ -368,7 +375,7 @@ class RunCMakeBuilder { } Future> _generateLinuxDefines() async { - if (codeConfig.targetOS != OS.linux) { + if (targetOS != OS.linux) { return []; } final defs = []; diff --git a/lib/src/native_toolchain/msvc.dart b/lib/src/native_toolchain/msvc.dart index dc4343c..e427364 100644 --- a/lib/src/native_toolchain/msvc.dart +++ b/lib/src/native_toolchain/msvc.dart @@ -284,12 +284,13 @@ class VisualStudioResolver implements ToolResolver { toolInfos = json.decode(vswhereResult.stdout) as List; } for (final toolInfo in toolInfos) { - final toolInfoParsed = toolInfo; - assert(toolInfoParsed['installationPath'] != null); - final dir = Directory(toolInfoParsed['installationPath'] as String); + final toolInfoMap = toolInfo as Map; + final toolInfoParsed = toolInfoMap['installationPath'] as String?; + assert(toolInfoParsed != null); + final dir = Directory(toolInfoParsed!); assert(await dir.exists()); final uri = dir.uri; - final version = versionFromString(toolInfoParsed['installationName'] as String); + final version = versionFromString(toolInfoMap['installationName'] as String); final instance = ToolInstance(tool: visualStudio, uri: uri, version: version); logger?.fine('Found $instance.'); result.add(instance); diff --git a/lib/src/utils/env_from_native_config.dart b/lib/src/utils/env_from_native_config.dart index 0f6fcf8..a3556e3 100644 --- a/lib/src/utils/env_from_native_config.dart +++ b/lib/src/utils/env_from_native_config.dart @@ -4,18 +4,16 @@ import 'package:hooks/hooks.dart'; import 'package:path/path.dart' as p; /// Get host specific build config -Future> getUserEnvConfig({required BuildInput input, required String envFile}) async { - final hookInputUserDefines = input.json['user_defines'] as Map?; - if (hookInputUserDefines == null) return {}; - - final workspacePubspec = hookInputUserDefines['workspace_pubspec'] as Map?; - if (workspacePubspec == null) return {}; - - final basePath = workspacePubspec['base_path'] as String?; - if (basePath == null) return {}; - - // base_path may be a directory when testing. - final projectDir = FileSystemEntity.isDirectorySync(basePath) ? basePath : p.dirname(basePath); +Future> getUserEnvConfig({ + required String envFile, + BuildInput? input, + Uri? packageRoot, +}) async { + String? projectDir; + if (input?.json case {'user_defines': {'workspace_pubspec': {'base_path': final String basePath}}}) { + projectDir = FileSystemEntity.isDirectorySync(basePath) ? basePath : p.dirname(basePath); + } + projectDir ??= (packageRoot ?? Directory.current.uri).toFilePath(); final envConfigPath = p.join(projectDir, envFile); final configFile = File(envConfigPath); if (!configFile.existsSync()) return {}; diff --git a/lib/src/utils/package_config_parser.dart b/lib/src/utils/package_config_parser.dart index 5b00b0b..3271cea 100644 --- a/lib/src/utils/package_config_parser.dart +++ b/lib/src/utils/package_config_parser.dart @@ -1,14 +1,14 @@ // Copyright (c) 2025, rainyl. All rights reserved. Use of this source code is governed by a // Apache-2.0 license that can be found in the LICENSE file. - import 'dart:convert'; import 'dart:io'; +import 'dart:isolate'; Future getPackagePath(String packageName) async { final packageConfig = await _parsePackageConfig(); for (final package in packageConfig.packages) { - if (package.name == packageName) { - return package.rootUri.toFilePath(); + if (package case Package(name: final name, rootUri: final rootUri) when name == packageName) { + return rootUri.toFilePath(); } } throw Exception('Package "$packageName" not found'); @@ -27,20 +27,30 @@ class Package { } Future _parsePackageConfig() async { - final file = File.fromUri(Uri.parse(Platform.packageConfig!)); + final packageConfigUri = + await Isolate.packageConfig ?? + (Platform.packageConfig != null + ? Uri.parse(Platform.packageConfig!) + : File('.dart_tool/package_config.json').absolute.uri); + final file = File.fromUri(packageConfigUri); final projectDir = file.parent; final content = await file.readAsString(); - final json = jsonDecode(content) as Map; + final json = jsonDecode(content); final packages = []; - for (final entry in json['packages'] as List) { - final name = entry['name'] as String; - final rootUri = Uri.parse(entry['rootUri'] as String); - final packageUri = Uri.parse(entry['packageUri'] as String? ?? 'lib/'); - - final pkg = Package(name, rootUri.isAbsolute ? rootUri : projectDir.uri.resolveUri(rootUri), packageUri); - - packages.add(pkg); + if (json case {'packages': final List packagesList}) { + for (final entry in packagesList) { + if (entry case {'name': final String name, 'rootUri': final String rootUriStr}) { + final packageUriStr = switch (entry) { + {'packageUri': final String uri} => uri, + _ => 'lib/', + }; + final packageUri = Uri.parse(packageUriStr); + final rootUri = Uri.parse(rootUriStr); + final resolvedRoot = rootUri.isAbsolute ? rootUri : projectDir.uri.resolveUri(rootUri); + packages.add(Package(name, resolvedRoot, packageUri)); + } + } } return PackageConfig(packages); diff --git a/lib/src/utils/run_process.dart b/lib/src/utils/run_process.dart index c9682ef..2777a28 100644 --- a/lib/src/utils/run_process.dart +++ b/lib/src/utils/run_process.dart @@ -174,7 +174,8 @@ class RunProcessResult { @override String toString() => - '''command: $command + ''' +command: $command exitCode: $exitCode stdout: $stdout stderr: $stderr'''; diff --git a/test/builder/cmake_builder_cross_android_test.dart b/test/builder/cmake_builder_cross_android_test.dart index 590adea..81f8e5e 100644 --- a/test/builder/cmake_builder_cross_android_test.dart +++ b/test/builder/cmake_builder_cross_android_test.dart @@ -122,7 +122,7 @@ Future buildLib( // ninja_version: null # "1.10.2" // TODO: add more user configs. final androidHome = Platform.environment['ANDROID_HOME']; - final envFilePath = tempUri.resolve(userDefinedConfig["env_file"] as String).toFilePath(); + final envFilePath = tempUri.resolve(userDefinedConfig["env_file"]!).toFilePath(); final envFile = File(envFilePath); await envFile.writeAsString('ANDROID_HOME=$androidHome'); } diff --git a/test/builder/cmake_builder_standalone_test.dart b/test/builder/cmake_builder_standalone_test.dart new file mode 100644 index 0000000..6b064e7 --- /dev/null +++ b/test/builder/cmake_builder_standalone_test.dart @@ -0,0 +1,67 @@ +@OnPlatform({'mac-os': Timeout.factor(2), 'windows': Timeout.factor(10)}) +library; + +import 'dart:ffi'; +import 'dart:io'; + +import 'package:code_assets/code_assets.dart'; +import 'package:native_toolchain_cmake/native_toolchain_cmake.dart'; +import 'package:native_toolchain_cmake/src/utils/run_process.dart'; +import 'package:test/test.dart'; + +import '../helpers.dart'; + +void main() { + final targetOS = OS.current; + + test('CMakeBuilder.create runStandalone executable', () async { + final tempUri = await tempDirForTest(); + const name = 'hello_world'; + final builder = CMakeBuilder.create( + name: name, + sourceDir: Directory('test/builder/testfiles/hello_world').uri, + buildMode: BuildMode.release, + ); + + await builder.runStandalone( + outputDirectory: tempUri, + targetOS: targetOS, + targetArchitecture: Architecture.current, + ); + + final executableUri = switch (targetOS) { + OS.macOS => tempUri.resolve('$name.app/Contents/MacOS/${OS.current.executableFileName(name)}'), + OS.windows => tempUri.resolve('Release/$name.exe'), + _ => tempUri.resolve(OS.current.executableFileName(name)), + }; + expect(await File.fromUri(executableUri).exists(), true); + final result = await runProcess(executable: executableUri, logger: logger); + expect(result.exitCode, 0); + expect(result.stdout.trim(), endsWith('Hello world.')); + }); + + test('CMakeBuilder.create runStandalone library', () async { + final tempUri = await tempDirForTest(); + const name = 'add'; + + final builder = CMakeBuilder.create( + name: name, + sourceDir: Directory('test/builder/testfiles/add').uri, + buildMode: BuildMode.release, + defines: {'CMAKE_INSTALL_PREFIX': tempUri.resolve('install/').toFilePath()}, + targets: ['install'], + ); + + await builder.runStandalone( + outputDirectory: tempUri, + targetOS: targetOS, + targetArchitecture: Architecture.current, + ); + + final dylibUri = tempUri.resolve('install/lib/${OS.current.dylibFileName(name)}'); + expect(await File.fromUri(dylibUri).exists(), true); + final dylib = openDynamicLibraryForTest(dylibUri.toFilePath()); + final add = dylib.lookupFunction('add'); + expect(add(1, 2), 3); + }); +} diff --git a/test/helpers.dart b/test/helpers.dart index 5d121f7..af3666d 100644 --- a/test/helpers.dart +++ b/test/helpers.dart @@ -193,7 +193,7 @@ DynamicLibrary openDynamicLibraryForTest(String path) { } extension UnescapePath on String { - String unescape() => replaceAll('\\', '/'); + String unescape() => replaceAll(r'\', '/'); } Future readelfMachine(String path) async { diff --git a/test/native_toolchain/clang_test.dart b/test/native_toolchain/clang_test.dart index 0069467..8d92fd1 100644 --- a/test/native_toolchain/clang_test.dart +++ b/test/native_toolchain/clang_test.dart @@ -18,7 +18,7 @@ import '../helpers.dart'; void main() { if (Platform.isMacOS || (Platform.isWindows && - Platform.environment['DART_HOOK_TESTING_C_COMPILER__CC']?.endsWith('cl.exe') == true)) { + (Platform.environment['DART_HOOK_TESTING_C_COMPILER__CC']?.endsWith('cl.exe') ?? false))) { // Avoid needing status files on Dart SDK CI. return; } diff --git a/test/utils/run_process_test.dart b/test/utils/run_process_test.dart index 730f8fa..a75ad94 100644 --- a/test/utils/run_process_test.dart +++ b/test/utils/run_process_test.dart @@ -4,8 +4,8 @@ import 'dart:io'; -import 'package:native_toolchain_cmake/src/utils/run_process.dart'; import 'package:native_toolchain_cmake/src/native_toolchain/cmake.dart'; +import 'package:native_toolchain_cmake/src/utils/run_process.dart'; import 'package:test/test.dart'; import '../helpers.dart'; From f4ac7c580b079c7dd9c4a72912d414cfb3e037c6 Mon Sep 17 00:00:00 2001 From: rainy liu Date: Fri, 17 Jul 2026 16:16:21 +0800 Subject: [PATCH 3/3] bump version to 0.2.7, fix example CI --- .github/workflows/examples.yaml | 12 ++++-------- CHANGELOG.md | 4 ++++ example/flutter/android/gradle.properties | 4 ++++ pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/examples.yaml b/.github/workflows/examples.yaml index 327194c..7e416f7 100644 --- a/.github/workflows/examples.yaml +++ b/.github/workflows/examples.yaml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - channel: "master" + channel: "stable" - name: run dart-cli example run: | cd ${{github.workspace}}\example\dart_cli @@ -27,7 +27,6 @@ jobs: - name: run flutter example run: | cd ${{github.workspace}}\example\flutter - flutter config --enable-native-assets flutter build windows --release linux: name: linux @@ -44,7 +43,7 @@ jobs: libstdc++-12-dev - uses: subosito/flutter-action@v2 with: - channel: "master" + channel: "stable" - name: run dart-cli example run: | cd "${{github.workspace}}/example/dart_cli" @@ -52,7 +51,6 @@ jobs: - name: run flutter example run: | cd "${{github.workspace}}/example/flutter" - flutter config --enable-native-assets flutter build linux --release macos: name: macos @@ -61,7 +59,7 @@ jobs: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: - channel: "master" + channel: "stable" - name: run dart-cli example run: | cd "${{github.workspace}}/example/dart_cli" @@ -69,7 +67,6 @@ jobs: - name: run flutter example run: | cd "${{github.workspace}}/example/flutter" - flutter config --enable-native-assets flutter build macos --release ios: name: ios @@ -97,7 +94,7 @@ jobs: gcc-riscv64-linux-gnu ninja-build - uses: subosito/flutter-action@v2 with: - channel: "master" + channel: "stable" - uses: actions/setup-java@v4 with: distribution: "temurin" @@ -110,5 +107,4 @@ jobs: - name: flutter example run: | cd "${{github.workspace}}/example/flutter" - flutter config --enable-native-assets flutter build apk --release diff --git a/CHANGELOG.md b/CHANGELOG.md index ae62195..c518bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # native_toolchain_cmake +## 0.2.7 + +- new: add `CMakeBuilder.runStandalone` to allow running builder without `BuildInput input` and `BuildOutputBuilder output` + ## 0.2.6 - bump hooks to 2.0 diff --git a/example/flutter/android/gradle.properties b/example/flutter/android/gradle.properties index f018a61..475a628 100644 --- a/example/flutter/android/gradle.properties +++ b/example/flutter/android/gradle.properties @@ -1,3 +1,7 @@ org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true android.enableJetifier=true +# This builtInKotlin flag was added automatically by Flutter migrator +android.builtInKotlin=false +# This newDsl flag was added automatically by Flutter migrator +android.newDsl=false diff --git a/pubspec.yaml b/pubspec.yaml index 64a58fb..287da52 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: native_toolchain_cmake description: >- A library to invoke and build CMake projects for Dart Native Assets. -version: 0.2.6 +version: 0.2.7 repository: https://github.com/rainyl/native_toolchain_cmake topics: