diff --git a/.github/workflows/native.yaml b/.github/workflows/native.yaml index a4570e2b70..3744888411 100644 --- a/.github/workflows/native.yaml +++ b/.github/workflows/native.yaml @@ -72,6 +72,9 @@ jobs: - run: dart pub get -C test_data/native_add_version_skew/ if: ${{ matrix.package == 'native_assets_builder' }} + - run: dart pub get -C test_data/native_add_version_skew_2/ + if: ${{ matrix.package == 'native_assets_builder' }} + - run: dart pub get -C test_data/native_subtract/ if: ${{ matrix.package == 'native_assets_builder' }} @@ -105,6 +108,9 @@ jobs: - run: dart pub get -C test_data/native_dynamic_linking/ if: ${{ matrix.package == 'native_assets_builder' }} + - run: dart pub get -C test_data/no_hook/ + if: ${{ matrix.package == 'native_assets_builder' }} + - run: dart pub get -C example/build/download_asset/ if: ${{ matrix.package == 'native_assets_cli' }} diff --git a/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart b/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart index 4f9116ff87..1fc1cd06f9 100644 --- a/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart +++ b/pkgs/native_assets_builder/lib/src/build_runner/build_runner.dart @@ -11,6 +11,7 @@ import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; import 'package:native_assets_cli/native_assets_cli_internal.dart'; import 'package:package_config/package_config.dart'; +import 'package:pub_semver/pub_semver.dart'; import '../dependencies_hash_file/dependencies_hash_file.dart'; import '../locking/locking.dart'; @@ -116,6 +117,10 @@ class NativeAssetsBuildRunner { ); if (buildPlan == null) return null; + if (!await _ensureNativeAssetsCliProtocolVersion()) { + return null; + } + var hookResult = HookResult(); final globalMetadata = {}; for (final package in buildPlan) { @@ -806,6 +811,58 @@ ${compileResult.stdout} ? BuildOutput(hookOutputJson) : LinkOutput(hookOutputJson); } + + Future _ensureNativeAssetsCliProtocolVersion() async { + final package = packageLayout.packageConfig['native_assets_cli'] ?? + packageLayout.packageConfig['hook']; // Anticipate rename. + if (package == null) { + // No dependencies with a hook or using a different protocol helper + // package. + return true; + } + final packageRoot = package.root.normalizePath(); + final hookVersion = await _nativeAssetsCliProtocolVersion(packageRoot); + if (hookVersion == null) { + logger.fine('Could not determine the protocol version of ' + '${packageRoot.toFilePath()}.'); + // This is most likely due to a newer version of the package. + return true; + } + if (latestParsableVersion > hookVersion) { + // The hook is too old. + logger.shout( + 'The protocol version of ${packageRoot.toFilePath()} is ' + '$hookVersion, which is no longer supported. Please update your ' + 'dependencies.', + ); + return false; + } + return true; + } + + Future _nativeAssetsCliProtocolVersion(Uri packageRoot) async { + const files = [ + 'lib/src/config.dart', + 'lib/src/model/hook_config.dart', + ]; + for (final fileName in files) { + final file = _fileSystem.file(packageRoot.resolve(fileName)); + if (!await file.exists()) { + continue; + } + final contents = await file.readAsString(); + final regex = RegExp(r'latestVersion = Version\((\d+), (\d+), (\d+)\);'); + final match = regex.firstMatch(contents); + if (match == null) { + continue; + } + final major = int.parse(match.group(1)!); + final minor = int.parse(match.group(2)!); + final patch = int.parse(match.group(3)!); + return Version(major, minor, patch); + } + return null; + } } /// Parses depfile contents. diff --git a/pkgs/native_assets_builder/pubspec.yaml b/pkgs/native_assets_builder/pubspec.yaml index 4878fac635..20fccb77be 100644 --- a/pkgs/native_assets_builder/pubspec.yaml +++ b/pkgs/native_assets_builder/pubspec.yaml @@ -20,6 +20,7 @@ dependencies: native_assets_cli: path: ../native_assets_cli/ package_config: ^2.1.0 + pub_semver: ^2.1.5 yaml: ^3.1.2 yaml_edit: ^2.1.0 diff --git a/pkgs/native_assets_builder/test/build_runner/version_skew_test.dart b/pkgs/native_assets_builder/test/build_runner/version_skew_test.dart index 4c17ffa9d8..1ccb56cc3a 100644 --- a/pkgs/native_assets_builder/test/build_runner/version_skew_test.dart +++ b/pkgs/native_assets_builder/test/build_runner/version_skew_test.dart @@ -36,4 +36,33 @@ void main() async { } }); }); + + test('Test hook using a too old version of native_assets_cli', + timeout: longTimeout, () async { + await inTempDir((tempUri) async { + await copyTestProjects(targetUri: tempUri); + final packageUri = tempUri.resolve('native_add_version_skew_2/'); + + // First, run `pub get`, we need pub to resolve our dependencies. + await runPubGet( + workingDirectory: packageUri, + logger: logger, + ); + + final logMessages = []; + final result = await buildCodeAssets( + packageUri, + capturedLogs: logMessages, + ); + expect(result, isNull); + expect( + logMessages.join('\n'), + stringContainsInOrder([ + 'The protocol version of ', + 'native_assets_cli', + ' is 1.3.0, which is no longer supported.', + 'Please update your dependencies.' + ])); + }); + }); } diff --git a/pkgs/native_assets_builder/test_data/manifest.yaml b/pkgs/native_assets_builder/test_data/manifest.yaml index 39854857e4..b64ff375b4 100644 --- a/pkgs/native_assets_builder/test_data/manifest.yaml +++ b/pkgs/native_assets_builder/test_data/manifest.yaml @@ -69,6 +69,8 @@ - native_add_version_skew/src/native_add.c - native_add_version_skew/src/native_add.h - native_add_version_skew/test/native_add_test.dart +- native_add_version_skew_2/hook/build.dart +- native_add_version_skew_2/pubspec.yaml - native_add/ffigen.yaml - native_add/hook/build.dart - native_add/lib/native_add.dart diff --git a/pkgs/native_assets_builder/test_data/native_add_version_skew_2/hook/build.dart b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/hook/build.dart new file mode 100644 index 0000000000..a521272a97 --- /dev/null +++ b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/hook/build.dart @@ -0,0 +1,30 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:logging/logging.dart'; +import 'package:native_assets_cli/native_assets_cli.dart'; +import 'package:native_toolchain_c/native_toolchain_c.dart'; + +void main(List arguments) async { + await build(arguments, (config, output) async { + final packageName = config.packageName; + final cbuilder = CBuilder.library( + name: packageName, + assetName: 'src/native_add_bindings_generated.dart', + sources: [ + 'src/native_add.c', + ], + dartBuildFiles: [], + ); + await cbuilder.run( + config: config, + output: output, + logger: Logger('') + ..level = Level.ALL + ..onRecord.listen((record) { + print('${record.level.name}: ${record.time}: ${record.message}'); + }), + ); + }); +} diff --git a/pkgs/native_assets_builder/test_data/native_add_version_skew_2/manifest.yaml b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/manifest.yaml new file mode 100644 index 0000000000..bc79e8f1cd --- /dev/null +++ b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/manifest.yaml @@ -0,0 +1,2 @@ +- hook/build.dart +- pubspec.yaml diff --git a/pkgs/native_assets_builder/test_data/native_add_version_skew_2/pubspec.yaml b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/pubspec.yaml new file mode 100644 index 0000000000..41dcb16dc1 --- /dev/null +++ b/pkgs/native_assets_builder/test_data/native_add_version_skew_2/pubspec.yaml @@ -0,0 +1,20 @@ +name: native_add_version_skew_2 +description: This package should no longer work due to being too old. +version: 0.1.0 + +publish_to: none + +environment: + sdk: '>=3.3.0 <4.0.0' + +dependencies: + logging: ^1.1.1 + native_assets_cli: ^0.6.0 + native_toolchain_c: ^0.5.0 + +dev_dependencies: + ffigen: ^8.0.2 + lints: ^3.0.0 + some_dev_dep: + path: ../some_dev_dep/ + test: ^1.23.1 diff --git a/pkgs/native_assets_cli/lib/native_assets_cli_internal.dart b/pkgs/native_assets_cli/lib/native_assets_cli_internal.dart index 55acd58487..903e2c25cc 100644 --- a/pkgs/native_assets_cli/lib/native_assets_cli_internal.dart +++ b/pkgs/native_assets_cli/lib/native_assets_cli_internal.dart @@ -6,4 +6,5 @@ library; export 'native_assets_cli_builder.dart'; +export 'src/config.dart' show latestParsableVersion; export 'src/model/hook.dart';