From 0d107a9085655f49842283682537f042b79fdb7b Mon Sep 17 00:00:00 2001 From: Gregory Conrad Date: Thu, 10 Sep 2026 16:57:34 -0400 Subject: [PATCH 1/3] chore(deps): bump major versions --- examples/dart_only/pubspec.yaml | 2 +- examples/flutter/pubspec.yaml | 2 +- native_toolchain_rust/pubspec.yaml | 2 +- pubspec.lock | 74 +++++++++++++++--------------- pubspec.yaml | 2 +- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/examples/dart_only/pubspec.yaml b/examples/dart_only/pubspec.yaml index bca6dea..0439962 100644 --- a/examples/dart_only/pubspec.yaml +++ b/examples/dart_only/pubspec.yaml @@ -10,5 +10,5 @@ dependencies: native_toolchain_rust: ^1.0.6 dev_dependencies: - ffigen: ^21.0.0 + ffigen: ^22.0.0 test: ^1.29.0 diff --git a/examples/flutter/pubspec.yaml b/examples/flutter/pubspec.yaml index 26eaf65..167e4da 100644 --- a/examples/flutter/pubspec.yaml +++ b/examples/flutter/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: native_toolchain_rust: ^1.0.6 dev_dependencies: - ffigen: ^21.0.0 + ffigen: ^22.0.0 flutter_test: sdk: flutter integration_test: diff --git a/native_toolchain_rust/pubspec.yaml b/native_toolchain_rust/pubspec.yaml index 24daf32..4101931 100644 --- a/native_toolchain_rust/pubspec.yaml +++ b/native_toolchain_rust/pubspec.yaml @@ -12,7 +12,7 @@ environment: sdk: ^3.9.0 dependencies: - code_assets: ^1.2.1 + code_assets: ^2.0.0 hooks: ^2.1.0 logging: ^1.3.0 meta: ^1.17.0 diff --git a/pubspec.lock b/pubspec.lock index 42d5ac9..7b9b36c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -101,18 +101,18 @@ packages: dependency: transitive description: name: clock - sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" code_assets: dependency: transitive description: name: code_assets - sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 + sha256: cfd4f5f575a49c5f10ca856e9846073f1e6c3ee94912377eea5f6cefc5272941 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "2.0.0" collection: dependency: transitive description: @@ -157,10 +157,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "3f88fc9c96c568d631356507355a2d1e983ee000c9ac008bdcb39b5bf53ce777" + sha256: "82ade9fc4273f29ed673e33166944465225b4f7fc5d4aaef48605cc751c18fc1" url: "https://pub.dev" source: hosted - version: "3.1.12" + version: "3.1.13" fake_async: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: ffigen - sha256: "56fc0be88937409839a59c133dfdee4165e80da324c9e39f59013060249ffb44" + sha256: "31b2ca630cede89babbbf31688d20b735967c51bf60572b06ec16718e5a7f1ec" url: "https://pub.dev" source: hosted - version: "21.0.0" + version: "22.0.0" file: dependency: transitive description: @@ -225,10 +225,10 @@ packages: dependency: transitive description: name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de + sha256: "218aeb56050c714f62a3182775320dfa04602b55074873e24e31bbd39bda96fb" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.2.0" graphs: dependency: transitive description: @@ -278,10 +278,10 @@ packages: dependency: transitive description: name: io - sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b + sha256: "2635216ca6a737e60de577ffa1a48a0bec76ca8a62917cfc1bb88c14c570646f" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.1.0" json_annotation: dependency: transitive description: @@ -358,10 +358,10 @@ packages: dependency: transitive description: name: mime - sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + sha256: bd47de35f07e27267e69c8c8b22edf9473bfee170a60d60fcc93730c5144b7f6 url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" mocktail: dependency: transitive description: @@ -382,10 +382,10 @@ packages: dependency: transitive description: name: native_toolchain_c - sha256: a1c26117c48cebe5677b0cf0e33a980a79a7c5577effc86f52e5a0d309cdcb60 + sha256: "9d233b6f2d9c52e1a2b5fbe70451d2c10ac674d3bb419d0ec8de14989d437c26" url: "https://pub.dev" source: hosted - version: "0.19.3" + version: "0.19.4" node_preamble: dependency: transitive description: @@ -422,26 +422,26 @@ packages: dependency: transitive description: name: platform - sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + sha256: a36d119c13416516a7b5913fbe8af8531e11633d784c550b2125f76c758524ec url: "https://pub.dev" source: hosted - version: "3.1.6" + version: "3.2.0" pool: dependency: transitive description: name: pool - sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" + sha256: "4177f68c237ea2128d1bee66ac17b2ce05ba3dbaafcbdd54c5d40a39d0b6b11c" url: "https://pub.dev" source: hosted - version: "1.5.2" + version: "1.5.3" process: dependency: transitive description: name: process - sha256: c6248e4526673988586e8c00bb22a49210c258dc91df5227d5da9748ecf79744 + sha256: "4242ba3508d37e01808bdf71ad1d5bb93a8d671bf2e7450e6b1b353fb0808891" url: "https://pub.dev" source: hosted - version: "5.0.5" + version: "5.0.6" prompts: dependency: transitive description: @@ -454,10 +454,10 @@ packages: dependency: transitive description: name: pub_semver - sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" pub_updater: dependency: transitive description: @@ -470,10 +470,10 @@ packages: dependency: transitive description: name: pubspec_parse - sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082" + sha256: c38b81cbf34450b67e0265d73433569d12e34782e30ed769c9cc99c9d5f2e796 url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.0" quiver: dependency: transitive description: @@ -539,10 +539,10 @@ packages: dependency: transitive description: name: source_maps - sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812" + sha256: "14c2945847669b44089bb1222f66873d7ff7103c58911917f2a63c5a62327898" url: "https://pub.dev" source: hosted - version: "0.10.13" + version: "0.10.14" source_span: dependency: transitive description: @@ -555,10 +555,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" url: "https://pub.dev" source: hosted - version: "1.12.1" + version: "1.12.2" stream_channel: dependency: transitive description: @@ -643,10 +643,10 @@ packages: dependency: "direct dev" description: name: very_good_analysis - sha256: "481af67ab5877af20325251dc215a4ebac7666a1c8cf09198ffd457bc612b33d" + sha256: "0bd5eb8d6be76aa0d71e70cbdae6cac8f784f761170568e3c2214a6948c7f6d3" url: "https://pub.dev" source: hosted - version: "10.3.0" + version: "11.0.0" vm_service: dependency: transitive description: @@ -691,10 +691,10 @@ packages: dependency: transitive description: name: webdriver - sha256: "2f3a14ca026957870cfd9c635b83507e0e51d8091568e90129fbf805aba7cade" + sha256: "28b82ec894fed45dd71c23ba62d1af973ed97dd59a4f5790a4d38b0b13e5657e" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.2.0" webkit_inspection_protocol: dependency: transitive description: @@ -715,10 +715,10 @@ packages: dependency: transitive description: name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" yaml_edit: dependency: transitive description: @@ -728,5 +728,5 @@ packages: source: hosted version: "2.2.4" sdks: - dart: ">=3.12.0 <4.0.0" + dart: ">=3.13.0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index c02c4df..844f766 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ workspace: dev_dependencies: melos: ^7.8.1 - very_good_analysis: ^10.3.0 + very_good_analysis: ^11.0.0 melos: scripts: From 54d30a4cb391475eba6e890708c97e113febad41 Mon Sep 17 00:00:00 2001 From: Gregory Conrad Date: Thu, 10 Sep 2026 17:49:30 -0400 Subject: [PATCH 2/3] updates for ffigen --- examples/dart_only/lib/src/ffi.g.dart | 7 ++----- examples/dart_only/tool/ffigen.dart | 19 ++++++++++++++----- examples/flutter/lib/src/ffi.g.dart | 10 +++++----- examples/flutter/tool/ffigen.dart | 23 ++++++++++++++--------- 4 files changed, 35 insertions(+), 24 deletions(-) diff --git a/examples/dart_only/lib/src/ffi.g.dart b/examples/dart_only/lib/src/ffi.g.dart index 39a871d..8a9baf3 100644 --- a/examples/dart_only/lib/src/ffi.g.dart +++ b/examples/dart_only/lib/src/ffi.g.dart @@ -1,11 +1,8 @@ // AUTO GENERATED FILE, DO NOT EDIT. // // Generated by `package:ffigen`. -// ignore_for_file: type=lint, unused_import +// ignore_for_file: type=lint, unused_import, unused_element, deprecated_member_use_from_same_package import 'dart:ffi' as ffi; @ffi.Native() -external int rust_add( - int a, - int b, -); +external int rust_add(int a, int b); diff --git a/examples/dart_only/tool/ffigen.dart b/examples/dart_only/tool/ffigen.dart index 1f1e468..416c127 100644 --- a/examples/dart_only/tool/ffigen.dart +++ b/examples/dart_only/tool/ffigen.dart @@ -2,11 +2,20 @@ import 'dart:io'; import 'package:ffigen/ffigen.dart'; -void main() { +Future main() async { final packageRoot = Platform.script.resolve('../'); - FfiGenerator( - headers: Headers(entryPoints: [packageRoot.resolve('rust/bindings.h')]), - output: Output(dartFile: packageRoot.resolve('lib/src/ffi.g.dart')), - functions: Functions.includeSet({'rust_add'}), + await FfiGenerator( + input: Input(entryPoints: [packageRoot.resolve('rust/bindings.h')]), + output: Output( + dart: DartOutput(path: packageRoot.resolve('lib/src/ffi.g.dart')), + ), + visitors: [ + Visitor( + func: (node) { + const toInclude = {'rust_add'}; + node.isIncluded = toInclude.contains(node.originalName); + }, + ), + ], ).generate(); } diff --git a/examples/flutter/lib/src/ffi.g.dart b/examples/flutter/lib/src/ffi.g.dart index 17fd0be..53cd296 100644 --- a/examples/flutter/lib/src/ffi.g.dart +++ b/examples/flutter/lib/src/ffi.g.dart @@ -1,14 +1,14 @@ // AUTO GENERATED FILE, DO NOT EDIT. // // Generated by `package:ffigen`. -// ignore_for_file: type=lint, unused_import +// ignore_for_file: type=lint, unused_import, unused_element, deprecated_member_use_from_same_package import 'dart:ffi' as ffi; -@ffi.Native() -external void reset_count(); +@ffi.Native() +external int get_count(); @ffi.Native() external void increase_count(); -@ffi.Native() -external int get_count(); +@ffi.Native() +external void reset_count(); diff --git a/examples/flutter/tool/ffigen.dart b/examples/flutter/tool/ffigen.dart index 6fe8f43..b899dba 100644 --- a/examples/flutter/tool/ffigen.dart +++ b/examples/flutter/tool/ffigen.dart @@ -2,15 +2,20 @@ import 'dart:io'; import 'package:ffigen/ffigen.dart'; -void main() { +Future main() async { final packageRoot = Platform.script.resolve('../'); - FfiGenerator( - headers: Headers(entryPoints: [packageRoot.resolve('rust/bindings.h')]), - output: Output(dartFile: packageRoot.resolve('lib/src/ffi.g.dart')), - functions: Functions.includeSet({ - 'reset_count', - 'increase_count', - 'get_count', - }), + await FfiGenerator( + input: Input(entryPoints: [packageRoot.resolve('rust/bindings.h')]), + output: Output( + dart: DartOutput(path: packageRoot.resolve('lib/src/ffi.g.dart')), + ), + visitors: [ + Visitor( + func: (node) { + const toInclude = {'reset_count', 'increase_count', 'get_count'}; + node.isIncluded = toInclude.contains(node.originalName); + }, + ), + ], ).generate(); } From cd706d8980cdbbc4aa46d68bc6d0a2598ce5f7da Mon Sep 17 00:00:00 2001 From: Gregory Conrad Date: Thu, 10 Sep 2026 17:52:17 -0400 Subject: [PATCH 3/3] update format --- examples/dart_only/hook/build.dart | 7 +++-- examples/flutter/hook/build.dart | 7 +++-- .../lib/src/build_environment.dart | 4 +-- .../lib/src/crate_info_validator.dart | 13 +++------ .../lib/src/toml_parsing.dart | 4 +-- .../test/crate_info_validator_test.dart | 14 +++++----- .../test/crate_resolver_test.dart | 23 +++++++--------- .../test/dependency_discoverer_test.dart | 27 +++++++++---------- .../test/exception_test.dart | 5 +--- 9 files changed, 40 insertions(+), 64 deletions(-) diff --git a/examples/dart_only/hook/build.dart b/examples/dart_only/hook/build.dart index c1f1d9d..96e11a9 100644 --- a/examples/dart_only/hook/build.dart +++ b/examples/dart_only/hook/build.dart @@ -3,9 +3,8 @@ import 'package:native_toolchain_rust/native_toolchain_rust.dart'; void main(List args) async { await build(args, (input, output) async { - await const RustBuilder(assetName: 'src/ffi.g.dart').run( - input: input, - output: output, - ); + await const RustBuilder( + assetName: 'src/ffi.g.dart', + ).run(input: input, output: output); }); } diff --git a/examples/flutter/hook/build.dart b/examples/flutter/hook/build.dart index c1f1d9d..96e11a9 100644 --- a/examples/flutter/hook/build.dart +++ b/examples/flutter/hook/build.dart @@ -3,9 +3,8 @@ import 'package:native_toolchain_rust/native_toolchain_rust.dart'; void main(List args) async { await build(args, (input, output) async { - await const RustBuilder(assetName: 'src/ffi.g.dart').run( - input: input, - output: output, - ); + await const RustBuilder( + assetName: 'src/ffi.g.dart', + ).run(input: input, output: output); }); } diff --git a/native_toolchain_rust/lib/src/build_environment.dart b/native_toolchain_rust/lib/src/build_environment.dart index 8b41fc9..85dfa31 100644 --- a/native_toolchain_rust/lib/src/build_environment.dart +++ b/native_toolchain_rust/lib/src/build_environment.dart @@ -34,9 +34,7 @@ interface class BuildEnvironmentFactory { interface class AndroidBuildEnvironmentFactory { const AndroidBuildEnvironmentFactory(); - Map createBuildEnvVars({ - required CodeConfig codeConfig, - }) { + Map createBuildEnvVars({required CodeConfig codeConfig}) { final CodeConfig(:targetTriple, :cCompiler) = codeConfig; if (cCompiler == null) { throw UnsupportedError( diff --git a/native_toolchain_rust/lib/src/crate_info_validator.dart b/native_toolchain_rust/lib/src/crate_info_validator.dart index ab90c93..7114917 100644 --- a/native_toolchain_rust/lib/src/crate_info_validator.dart +++ b/native_toolchain_rust/lib/src/crate_info_validator.dart @@ -18,9 +18,7 @@ interface class CrateInfoValidator { required String toolchainTomlPath, required String targetTriple, }) { - final manifest = cargoManifestParser.parseManifest( - manifestPath, - ); + final manifest = cargoManifestParser.parseManifest(manifestPath); final [ String? libName, @@ -29,13 +27,8 @@ interface class CrateInfoValidator { ] = RustValidationException.compose([ () => manifest.libName, () { - final CargoManifest( - :libName, - :crateName, - :libCrateTypes, - ) = cargoManifestParser.parseManifest( - manifestPath, - ); + final CargoManifest(:libName, :crateName, :libCrateTypes) = + cargoManifestParser.parseManifest(manifestPath); const requiredTypes = ['staticlib', 'cdylib']; if (!requiredTypes.every(libCrateTypes.contains)) { diff --git a/native_toolchain_rust/lib/src/toml_parsing.dart b/native_toolchain_rust/lib/src/toml_parsing.dart index b8fa1b7..1ace406 100644 --- a/native_toolchain_rust/lib/src/toml_parsing.dart +++ b/native_toolchain_rust/lib/src/toml_parsing.dart @@ -66,9 +66,7 @@ interface class CargoManifestParser { final Logger logger; final TomlDocumentWrapperFactory tomlDocumentFactory; - CargoManifest parseManifest( - String manifestPath, - ) { + CargoManifest parseManifest(String manifestPath) { logger.info('Looking for Cargo.toml'); if (!File(manifestPath).existsSync()) { throw RustValidationException([ diff --git a/native_toolchain_rust/test/crate_info_validator_test.dart b/native_toolchain_rust/test/crate_info_validator_test.dart index 25f6fbd..9a8526d 100644 --- a/native_toolchain_rust/test/crate_info_validator_test.dart +++ b/native_toolchain_rust/test/crate_info_validator_test.dart @@ -30,10 +30,9 @@ void main() { libCrateTypes: ['staticlib', 'cdylib'], ), ); - when(() => mockToolchainTomlParser.parseToolchainToml(any())).thenReturn(( - channel: '1.90.0', - targets: {'aarch64-linux-android'}, - )); + when( + () => mockToolchainTomlParser.parseToolchainToml(any()), + ).thenReturn((channel: '1.90.0', targets: {'aarch64-linux-android'})); final result = validator.fetchAndValidateCrateInfo( manifestPath: 'dummy_manifest_path', @@ -52,10 +51,9 @@ void main() { libCrateTypes: ['staticlib'], ), ); - when(() => mockToolchainTomlParser.parseToolchainToml(any())).thenReturn(( - channel: 'stable', - targets: {'x86_64-linux-gnu'}, - )); + when( + () => mockToolchainTomlParser.parseToolchainToml(any()), + ).thenReturn((channel: 'stable', targets: {'x86_64-linux-gnu'})); expect( () => validator.fetchAndValidateCrateInfo( diff --git a/native_toolchain_rust/test/crate_resolver_test.dart b/native_toolchain_rust/test/crate_resolver_test.dart index cc5b91b..7f08c7c 100644 --- a/native_toolchain_rust/test/crate_resolver_test.dart +++ b/native_toolchain_rust/test/crate_resolver_test.dart @@ -30,19 +30,16 @@ void main() { expect(result.path, equals(crateDir.path)); }); - test( - 'resolveCrateDirectory throws RustValidationException ' - 'if no directory exists', - () { - expect( - () => resolver.resolveCrateDirectory( - rootPath: tempDir.path, - cratePathOptions: ['non_existent_crate'], - ), - throwsA(isA()), - ); - }, - ); + test('resolveCrateDirectory throws RustValidationException ' + 'if no directory exists', () { + expect( + () => resolver.resolveCrateDirectory( + rootPath: tempDir.path, + cratePathOptions: ['non_existent_crate'], + ), + throwsA(isA()), + ); + }); test('resolveCrateDirectory returns the first existing directory', () { final crateDir1 = Directory(path.join(tempDir.path, 'crate1')); diff --git a/native_toolchain_rust/test/dependency_discoverer_test.dart b/native_toolchain_rust/test/dependency_discoverer_test.dart index 3486761..67b3ef7 100644 --- a/native_toolchain_rust/test/dependency_discoverer_test.dart +++ b/native_toolchain_rust/test/dependency_discoverer_test.dart @@ -63,23 +63,20 @@ target/debug/librust_lib.a: /path/to/some/other/file.rs expect(dependencies, isEmpty); }); - test( - 'discover does not include the dependency file itself', - () { - // Cargo refreshes the mtime of the dep-info file on every invocation, - // even for no-op rebuilds. Including it in the dependency list causes - // Flutter's build graph to emit "File modified during build. Build - // must be rerun." warnings. See issue #73. - final dependencyFilePath = path.join(tempDir.path, 'test.d'); - File(dependencyFilePath).writeAsStringSync( - 'target/debug/librust_lib.a: src/lib.rs', - ); + test('discover does not include the dependency file itself', () { + // Cargo refreshes the mtime of the dep-info file on every invocation, + // even for no-op rebuilds. Including it in the dependency list causes + // Flutter's build graph to emit "File modified during build. Build + // must be rerun." warnings. See issue #73. + final dependencyFilePath = path.join(tempDir.path, 'test.d'); + File( + dependencyFilePath, + ).writeAsStringSync('target/debug/librust_lib.a: src/lib.rs'); - final dependencies = dependencyDiscoverer.discover(dependencyFilePath); + final dependencies = dependencyDiscoverer.discover(dependencyFilePath); - expect(dependencies, isNot(contains(path.toUri(dependencyFilePath)))); - }, - ); + expect(dependencies, isNot(contains(path.toUri(dependencyFilePath)))); + }); test( 'discover throws an exception if the dependency file is not found', diff --git a/native_toolchain_rust/test/exception_test.dart b/native_toolchain_rust/test/exception_test.dart index 3e132ae..cbb3f86 100644 --- a/native_toolchain_rust/test/exception_test.dart +++ b/native_toolchain_rust/test/exception_test.dart @@ -4,10 +4,7 @@ import 'package:test/test.dart'; void main() { group('RustValidationException', () { test('compose returns results when no exceptions are thrown', () { - final results = RustValidationException.compose([ - () => 1, - () => 2, - ]); + final results = RustValidationException.compose([() => 1, () => 2]); expect(results, equals([1, 2])); });