From d745cd0af9561bd529542703885872ac6a6c6c03 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Mon, 4 Dec 2023 21:46:15 +0100 Subject: [PATCH 1/2] feat(dynamite)!: validate version of dependencies when generating Signed-off-by: Nikolas Rimikis --- .../lib/src/helpers/version_checker.dart | 96 +++++++++++++++++++ .../dynamite/lib/src/openapi_builder.dart | 12 +++ packages/dynamite/dynamite/pubspec.yaml | 2 + 3 files changed, 110 insertions(+) create mode 100644 packages/dynamite/dynamite/lib/src/helpers/version_checker.dart diff --git a/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart b/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart new file mode 100644 index 00000000000..588644fbfd7 --- /dev/null +++ b/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart @@ -0,0 +1,96 @@ +import 'package:build/build.dart'; +import 'package:pub_semver/pub_semver.dart'; +import 'package:pubspec_parse/pubspec_parse.dart'; + +final dependencies = { + 'built_collection': Version.parse('5.0.0'), + 'built_value': Version.parse('8.0.0'), + 'collection': Version.parse('1.0.0'), + 'dynamite_runtime': Version.parse('0.0.1'), + 'meta': Version.parse('1.0.0'), + 'universal_io': Version.parse('2.0.0'), + 'uri': Version.parse('1.0.0'), +}; + +final devDependencies = { + 'built_value_generator': Version.parse('8.8.0'), +}; + +/// Checks whether the correct version of the dependencies are present in the pubspec.yaml file. +Future<({bool hasFatal, String messages})> helperVersionCheck(final BuildStep buildStep) async { + final pubspecAsset = AssetId(buildStep.inputId.package, 'pubspec.yaml'); + + if (!await buildStep.canRead(pubspecAsset)) { + return ( + hasFatal: false, + messages: 'Failed to read the pubspec.yaml file. Version constraints of required packages can not be validated.', + ); + } + + final pubspecContent = await buildStep.readAsString(pubspecAsset); + final pubspec = Pubspec.parse(pubspecContent, sourceUrl: pubspecAsset.uri); + + final messages = StringBuffer(); + var hasFatal = false; + + for (final constraint in dependencies.entries) { + final result = _validateVersion(pubspec.dependencies, constraint.key, constraint.value); + + if (result.message != null) { + messages.writeln(result.message); + } + + if (result.isFatal) { + hasFatal = true; + } + } + + for (final constraint in devDependencies.entries) { + final result = _validateVersion(pubspec.devDependencies, constraint.key, constraint.value); + + if (result.message != null) { + messages.writeln(result.message); + } + + if (result.isFatal) { + hasFatal = true; + } + } + + return (hasFatal: hasFatal, messages: messages.toString()); +} + +({bool isFatal, String? message}) _validateVersion( + final Map dependencies, + final String packageName, + final Version minVersion, +) { + final dependency = dependencies[packageName]; + final maxVersion = minVersion.nextBreaking; + + if (dependency == null) { + return ( + isFatal: false, + message: + 'Could not find the dependency on `$packageName` in pubspec.yaml file. Compatibility check is being skipped.', + ); + } else if (dependency is HostedDependency) { + final constraint = dependency.version; + final invalidConstraintMessage = + 'The version constraint $constraint on `$packageName` allows versions before $minVersion or after $maxVersion which is not allowed.'; + + if (constraint is Version && (constraint < minVersion || constraint > maxVersion)) { + return (isFatal: true, message: invalidConstraintMessage); + } + + final range = constraint as VersionRange; + final rangeMin = range.min; + final rangeMax = range.max; + + if (rangeMin == null || rangeMax == null || rangeMin < minVersion || rangeMax > maxVersion) { + return (isFatal: true, message: invalidConstraintMessage); + } + } + + return (isFatal: false, message: null); +} diff --git a/packages/dynamite/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/dynamite/lib/src/openapi_builder.dart index 4f1ff754ac6..b72ff267e56 100644 --- a/packages/dynamite/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/dynamite/lib/src/openapi_builder.dart @@ -12,6 +12,7 @@ import 'package:dynamite/src/builder/generate_schemas.dart'; import 'package:dynamite/src/builder/imports.dart'; import 'package:dynamite/src/builder/serializer.dart'; import 'package:dynamite/src/builder/state.dart'; +import 'package:dynamite/src/helpers/version_checker.dart'; import 'package:dynamite/src/models/config.dart'; import 'package:dynamite/src/models/openapi.dart' as openapi; import 'package:version/version.dart'; @@ -38,6 +39,17 @@ class OpenAPIBuilder implements Builder { @override Future build(final BuildStep buildStep) async { + final result = await helperVersionCheck(buildStep); + + if (result.messages.isNotEmpty) { + if (result.hasFatal) { + log.severe(result.messages); + return; + } else { + log.info(result.messages); + } + } + try { final inputId = buildStep.inputId; final outputId = inputId.changeExtension('.dart'); diff --git a/packages/dynamite/dynamite/pubspec.yaml b/packages/dynamite/dynamite/pubspec.yaml index 97a3def327b..0501a97d11d 100644 --- a/packages/dynamite/dynamite/pubspec.yaml +++ b/packages/dynamite/dynamite/pubspec.yaml @@ -15,6 +15,8 @@ dependencies: intersperse: ^2.0.0 meta: ^1.0.0 path: ^1.0.0 + pub_semver: ^2.1.4 + pubspec_parse: ^1.2.3 uri: ^1.0.0 version: ^3.0.0 From 40c5f3e50aee769c092e2c0fe366cb8be5e1e27f Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 12 Dec 2023 12:19:06 +0100 Subject: [PATCH 2/2] chore(dynamite): require built_value_generator 8.8.1 Signed-off-by: Nikolas Rimikis --- packages/dynamite/dynamite/README.md | 2 +- packages/dynamite/dynamite/lib/src/helpers/version_checker.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/dynamite/dynamite/README.md b/packages/dynamite/dynamite/README.md index 7657b4e65d9..020c3afb7df 100644 --- a/packages/dynamite/dynamite/README.md +++ b/packages/dynamite/dynamite/README.md @@ -16,7 +16,7 @@ dependencies: uri: ^1.0.0 dev_dependencies: build_runner: ^2.4.0 - built_value_generator: ^8.8.0 + built_value_generator: ^8.8.1 ``` # Generating diff --git a/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart b/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart index 588644fbfd7..e8b84688793 100644 --- a/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart +++ b/packages/dynamite/dynamite/lib/src/helpers/version_checker.dart @@ -13,7 +13,7 @@ final dependencies = { }; final devDependencies = { - 'built_value_generator': Version.parse('8.8.0'), + 'built_value_generator': Version.parse('8.8.1'), }; /// Checks whether the correct version of the dependencies are present in the pubspec.yaml file.