diff --git a/examples/example/lib/gen/assets.gen.dart b/examples/example/lib/gen/assets.gen.dart index 62a550943..ef6a7e76a 100644 --- a/examples/example/lib/gen/assets.gen.dart +++ b/examples/example/lib/gen/assets.gen.dart @@ -359,6 +359,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -395,6 +396,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? diff --git a/examples/example_resources/lib/gen/assets.gen.dart b/examples/example_resources/lib/gen/assets.gen.dart index 64f3098e1..a7c1817f4 100644 --- a/examples/example_resources/lib/gen/assets.gen.dart +++ b/examples/example_resources/lib/gen/assets.gen.dart @@ -194,6 +194,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -230,6 +231,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? diff --git a/packages/core/lib/generators/assets_generator.dart b/packages/core/lib/generators/assets_generator.dart index f7dfb204a..dd48d91e4 100644 --- a/packages/core/lib/generators/assets_generator.dart +++ b/packages/core/lib/generators/assets_generator.dart @@ -89,6 +89,9 @@ Future generateAssets( SvgIntegration( config.packageParameterLiteral, parseMetadata: config.flutterGen.parseMetadata, + resolvedVersion: config.integrationResolvedVersions[SvgIntegration], + resolvedVersionConstraint: + config.integrationResolvedVersionConstraints[SvgIntegration], ), if (config.flutterGen.integrations.rive) RiveIntegration( diff --git a/packages/core/lib/generators/integrations/svg_integration.dart b/packages/core/lib/generators/integrations/svg_integration.dart index 86919d88a..df5cccc26 100644 --- a/packages/core/lib/generators/integrations/svg_integration.dart +++ b/packages/core/lib/generators/integrations/svg_integration.dart @@ -2,13 +2,45 @@ import 'dart:io'; import 'package:flutter_gen_core/generators/integrations/integration.dart'; import 'package:flutter_gen_core/utils/log.dart'; +import 'package:pub_semver/pub_semver.dart' + show Version, VersionConstraint, VersionRange; import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; class SvgIntegration extends Integration { SvgIntegration( String packageName, { super.parseMetadata, - }) : super(packageName); + Version? resolvedVersion, + VersionConstraint? resolvedVersionConstraint, + }) : supportsErrorBuilder = _resolveErrorBuilderSupport( + resolvedVersion, + resolvedVersionConstraint, + ), + super(packageName); + + /// The minimum flutter_svg version that provides `SvgPicture.errorBuilder`. + static final errorBuilderMinimumSupportVersion = Version(2, 0, 17); + + /// Whether the generated `svg()` exposes `errorBuilder`. + final bool supportsErrorBuilder; + + static bool _resolveErrorBuilderSupport( + Version? resolvedVersion, + VersionConstraint? resolvedVersionConstraint, + ) { + // Resolve by version. + if (resolvedVersion != null) { + return resolvedVersion >= errorBuilderMinimumSupportVersion; + } + // Resolve by version constraint. + if (resolvedVersionConstraint != null) { + return resolvedVersionConstraint.allowsAny( + VersionRange(min: errorBuilderMinimumSupportVersion, includeMin: true), + ); + } + // Use the latest version as the fallback. + return true; + } String get packageExpression => isPackage ? ' = package' : ''; @@ -54,7 +86,7 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''} AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, - String? semanticsLabel, + ${supportsErrorBuilder ? '_svg.SvgErrorWidgetBuilder? errorBuilder,\n ' : ''}String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, _svg.ColorMapper? colorMapper, @@ -90,7 +122,7 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''} alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, - semanticsLabel: semanticsLabel, + ${supportsErrorBuilder ? 'errorBuilder: errorBuilder,\n ' : ''}semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? (color == null ? null : ColorFilter.mode(color, colorBlendMode)), clipBehavior: clipBehavior, diff --git a/packages/core/test/assets_gen_integrations_test.dart b/packages/core/test/assets_gen_integrations_test.dart index e07560f33..20312e4ff 100644 --- a/packages/core/test/assets_gen_integrations_test.dart +++ b/packages/core/test/assets_gen_integrations_test.dart @@ -191,6 +191,66 @@ void main() { ); }); + test('SvgIntegration errorBuilder resolution with resolvedVersion', () { + // Test with version < 2.0.17 (should not expose errorBuilder) + final oldIntegration = SvgIntegration( + '', + resolvedVersion: Version(2, 0, 16), + ); + expect(oldIntegration.supportsErrorBuilder, isFalse); + expect(oldIntegration.classOutput.contains('errorBuilder'), isFalse); + + // Test with version >= 2.0.17 (should expose errorBuilder) + final supportedIntegration = SvgIntegration( + '', + resolvedVersion: Version(2, 0, 17), + ); + expect(supportedIntegration.supportsErrorBuilder, isTrue); + expect( + supportedIntegration.classOutput.contains( + '_svg.SvgErrorWidgetBuilder? errorBuilder,', + ), + isTrue, + ); + expect( + supportedIntegration.classOutput.contains( + 'errorBuilder: errorBuilder,', + ), + isTrue, + ); + }); + + test('SvgIntegration errorBuilder resolution with version constraint', () { + // Test with constraint that allows 2.0.17 (should expose errorBuilder) + final allowsSupported = SvgIntegration( + '', + resolvedVersionConstraint: VersionConstraint.parse('^2.0.0'), + ); + expect(allowsSupported.supportsErrorBuilder, isTrue); + + // Test with constraint that excludes 2.0.17 (should not expose errorBuilder) + final excludesSupported = SvgIntegration( + '', + resolvedVersionConstraint: VersionConstraint.parse('>=2.0.0 <2.0.17'), + ); + expect(excludesSupported.supportsErrorBuilder, isFalse); + expect(excludesSupported.classOutput.contains('errorBuilder'), isFalse); + }); + + test('SvgIntegration errorBuilder resolution priority and fallback', () { + // resolvedVersion should take priority over resolvedVersionConstraint + final integration = SvgIntegration( + '', + resolvedVersion: Version(2, 0, 9), + resolvedVersionConstraint: VersionConstraint.parse('^2.0.0'), + ); + expect(integration.supportsErrorBuilder, isFalse); + + // Test with no version information (should expose errorBuilder as fallback) + final fallbackIntegration = SvgIntegration(''); + expect(fallbackIntegration.supportsErrorBuilder, isTrue); + }); + test('Assets with Rive integrations on pubspec.yaml', () async { const pubspec = 'test_resources/pubspec_assets_rive_integrations.yaml'; await expectedAssetsGen(pubspec); diff --git a/packages/core/test_resources/actual_data/assets_assets.gen.dart b/packages/core/test_resources/actual_data/assets_assets.gen.dart index 8adde2e9e..4a28e99cf 100644 --- a/packages/core/test_resources/actual_data/assets_assets.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets.gen.dart @@ -281,6 +281,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -317,6 +318,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? diff --git a/packages/core/test_resources/actual_data/assets_assets_deferred_components.gen.dart b/packages/core/test_resources/actual_data/assets_assets_deferred_components.gen.dart index e6b01d080..2a4b3fc64 100644 --- a/packages/core/test_resources/actual_data/assets_assets_deferred_components.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_deferred_components.gen.dart @@ -327,6 +327,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -363,6 +364,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart b/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart index 3a7e669c9..1ae65b05b 100644 --- a/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart @@ -188,6 +188,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -224,6 +225,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart b/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart index bc03f71dd..340dc29ae 100644 --- a/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart @@ -201,6 +201,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -237,6 +238,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart b/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart index 73fc62631..7c9cf8a3c 100644 --- a/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart @@ -273,6 +273,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -309,6 +310,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart b/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart index 256184310..71154fb1f 100644 --- a/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart @@ -189,6 +189,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -225,6 +226,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart b/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart index 582ea7491..c26af1ce4 100644 --- a/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart @@ -177,6 +177,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -213,6 +214,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart b/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart index 451729d22..e30826f31 100644 --- a/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart @@ -315,6 +315,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -351,6 +352,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_assets_svg_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_assets_svg_integrations.gen.dart index 351ef6d8f..d57ab4dd6 100644 --- a/packages/core/test_resources/actual_data/assets_assets_svg_integrations.gen.dart +++ b/packages/core/test_resources/actual_data/assets_assets_svg_integrations.gen.dart @@ -66,6 +66,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -102,6 +103,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/assets_normal.gen.dart b/packages/core/test_resources/actual_data/assets_normal.gen.dart index 415b35446..9e7050b33 100644 --- a/packages/core/test_resources/actual_data/assets_normal.gen.dart +++ b/packages/core/test_resources/actual_data/assets_normal.gen.dart @@ -236,6 +236,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -272,6 +273,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: diff --git a/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart index 8adde2e9e..4a28e99cf 100644 --- a/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart +++ b/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart @@ -281,6 +281,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -317,6 +318,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? diff --git a/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart index 8adde2e9e..4a28e99cf 100644 --- a/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart +++ b/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart @@ -281,6 +281,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -317,6 +318,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? diff --git a/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart index 1e6da27b6..e18af2afa 100644 --- a/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart +++ b/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart @@ -274,6 +274,7 @@ class SvgGenImage { AlignmentGeometry alignment = Alignment.center, bool allowDrawingOutsideViewBox = false, WidgetBuilder? placeholderBuilder, + _svg.SvgErrorWidgetBuilder? errorBuilder, String? semanticsLabel, bool excludeFromSemantics = false, _svg.SvgTheme? theme, @@ -310,6 +311,7 @@ class SvgGenImage { alignment: alignment, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, placeholderBuilder: placeholderBuilder, + errorBuilder: errorBuilder, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, colorFilter: colorFilter ?? (color == null ? null : ColorFilter.mode(color, colorBlendMode)),