Repository: FlutterGen/flutter_gen

Issue:
[FR]: Conditionally bundling assets based on flavor
### Is there an existing issue for this?

- [X] I have searched the existing issues

### Version

5.4.0

### Command type

build_runner (Default)

### What happened?

With the new flutter version 3.19, conditionally bundling assets based on flavor was introduced. As the name suggests, this allows for bundling assets contionally based on flavor of the app. [docs](https://docs.flutter.dev/deployment/flavors#conditionally-bundling-assets-based-on-flavor )

When using flutter_gen to build assets I get the following exception:

`
FlutterGen v5.4.0 Loading ... my-app/pubspec.yaml
Unhandled exception:
CheckedFromJsonException
Could not create `Flutter`.
There is a problem with "assets".
type 'YamlMap' is not a subtype of type 'String' in type cast
#0      $checkedConvert (package:json_annotation/src/checked_helpers.dart:91:5)
#1      $checkedCreate.checkedConvert (package:json_annotation/src/checked_helpers.dart:28:7)
#2      _$FlutterFromJson.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:38:34)
#3      $checkedCreate.<anonymous closure> (package:json_annotation/src/checked_helpers.dart:33:22)
#4      $checkedNew (package:json_annotation/src/checked_helpers.dart:51:23)
#5      $checkedCreate (package:json_annotation/src/checked_helpers.dart:30:10)
#6      _$FlutterFromJson (package:flutter_gen_core/settings/pubspec.g.dart:29:40)
#7      new Flutter.fromJson (package:flutter_gen_core/settings/pubspec.dart:40:41)
#8      _$PubspecFromJson.<anonymous closure>.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:22:57)
#9      $checkedConvert (package:json_annotation/src/checked_helpers.dart:87:20)
#10     $checkedCreate.checkedConvert (package:json_annotation/src/checked_helpers.dart:28:7)
#11     _$PubspecFromJson.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:22:30)
#12     $checkedCreate.<anonymous closure> (package:json_annotation/src/checked_helpers.dart:33:22)
#13     $checkedNew (package:json_annotation/src/checked_helpers.dart:51:23)
#14     $checkedCreate (package:json_annotation/src/checked_helpers.dart:30:10)
#15     _$PubspecFromJson (package:flutter_gen_core/settings/pubspec.g.dart:9:40)
#16     new Pubspec.fromJson (package:flutter_gen_core/settings/pubspec.dart:15:41)
#17     loadPubspecConfig (package:flutter_gen_core/settings/config.dart:28:27)
#18     loadPubspecConfigOrNull (package:flutter_gen_core/settings/config.dart:34:12)
#19     FlutterGenerator.build (package:flutter_gen_core/flutter_generator.dart:25:16)
#20     main (file:///Users/myuser/.pub-cache/hosted/pub.dev/flutter_gen-5.4.0/bin/flutter_gen_command.dart:48:49)
#21     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:294:33)
#22     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
`

How my assets are defined in pubspec.yaml

`
flutter:
    uses-material-design: true

    # To add assets to your application, add an assets section, like this:
    assets:
        - path: assets/sandbox/
          flavors:
              - sandbox
        - path: assets/production/
          flavors:
              - production
`

is this not supported?

### Relevant a pubspec.yaml.

```yaml
flutter_gen:
    output: lib/gen/ # Optional (default: lib/gen/)
    line_length: 80 # Optional (default: 80)

    # Optional
    integrations:
        flutter_svg: true
        flare_flutter: true
        rive: true
        lottie: true

flutter:

    uses-material-design: true

    assets:
        - path: assets/sandbox/
          flavors:
              - sandbox
        - path: assets/production/
          flavors:
              - production
```


### Relevant log output

```shell
FlutterGen v5.4.0 Loading ... my-app/pubspec.yaml
Unhandled exception:
CheckedFromJsonException
Could not create `Flutter`.
There is a problem with "assets".
type 'YamlMap' is not a subtype of type 'String' in type cast
#0      $checkedConvert (package:json_annotation/src/checked_helpers.dart:91:5)
#1      $checkedCreate.checkedConvert (package:json_annotation/src/checked_helpers.dart:28:7)
#2      _$FlutterFromJson.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:38:34)
#3      $checkedCreate.<anonymous closure> (package:json_annotation/src/checked_helpers.dart:33:22)
#4      $checkedNew (package:json_annotation/src/checked_helpers.dart:51:23)
#5      $checkedCreate (package:json_annotation/src/checked_helpers.dart:30:10)
#6      _$FlutterFromJson (package:flutter_gen_core/settings/pubspec.g.dart:29:40)
#7      new Flutter.fromJson (package:flutter_gen_core/settings/pubspec.dart:40:41)
#8      _$PubspecFromJson.<anonymous closure>.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:22:57)
#9      $checkedConvert (package:json_annotation/src/checked_helpers.dart:87:20)
#10     $checkedCreate.checkedConvert (package:json_annotation/src/checked_helpers.dart:28:7)
#11     _$PubspecFromJson.<anonymous closure> (package:flutter_gen_core/settings/pubspec.g.dart:22:30)
#12     $checkedCreate.<anonymous closure> (package:json_annotation/src/checked_helpers.dart:33:22)
#13     $checkedNew (package:json_annotation/src/checked_helpers.dart:51:23)
#14     $checkedCreate (package:json_annotation/src/checked_helpers.dart:30:10)
#15     _$PubspecFromJson (package:flutter_gen_core/settings/pubspec.g.dart:9:40)
#16     new Pubspec.fromJson (package:flutter_gen_core/settings/pubspec.dart:15:41)
#17     loadPubspecConfig (package:flutter_gen_core/settings/config.dart:28:27)
#18     loadPubspecConfigOrNull (package:flutter_gen_core/settings/config.dart:34:12)
#19     FlutterGenerator.build (package:flutter_gen_core/flutter_generator.dart:25:16)
#20     main (file:///Users/myuser/.pub-cache/hosted/pub.dev/flutter_gen-5.4.0/bin/flutter_gen_command.dart:48:49)
#21     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:294:33)
#22     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189:12)
```


### Code of Conduct

- [X] I agree to follow this project's Code of Conduct


Discussion: Yes it is not supported.
@AlexV525 Are there plans to support this in the future?
> @AlexV525 Are there plans to support this in the future?

Not yet. We Will sync in this thread if any idea coming out.

Fix patch:
diff --git a/README.md b/README.md
index f051ef4a8..ab26d201d 100644
--- a/README.md
+++ b/README.md
@@ -167,6 +167,18 @@ flutter:
 
 These configurations will generate **`assets.gen.dart`** under the **`lib/gen/`** directory by default.
 
+#### Flavored assets
+
+Flutter supports
+[Conditionally bundling assets based on flavor](https://docs.flutter.dev/deployment/flavors#conditionally-bundling-assets-based-on-flavor).
+Assets are only available with flavors if specified.
+`flutter_gen` will generate the specified `flavors` for assets regardless the current flavor.
+The `flavors` field accessible though `.flavors`, for example:
+
+```dart
+print(MyAssets.images.chip4.flavors); // -> {'extern'}
+```
+
 #### Excluding generating for assets
 
 You can specify `flutter_gen > assets > exclude` using `Glob` patterns to exclude particular assets.
diff --git a/examples/example/lib/gen/assets.gen.dart b/examples/example/lib/gen/assets.gen.dart
index 9efacf68d..ff963ec28 100644
--- a/examples/example/lib/gen/assets.gen.dart
+++ b/examples/example/lib/gen/assets.gen.dart
@@ -35,6 +35,9 @@ class $AssetsImagesGen {
   /// File path: assets/images/chip2.jpg
   AssetGenImage get chip2 => const AssetGenImage('assets/images/chip2.jpg');
 
+  /// Directory path: assets/images/chip3
+  $AssetsImagesChip3Gen get chip3 => const $AssetsImagesChip3Gen();
+
   /// Directory path: assets/images/chip4
   $AssetsImagesChip4Gen get chip4 => const $AssetsImagesChip4Gen();
 
@@ -142,12 +145,25 @@ class $AssetsUnknownGen {
   List<String> get values => [changelog, readme, unknownMimeType];
 }
 
+class $AssetsImagesChip3Gen {
+  const $AssetsImagesChip3Gen();
+
+  /// File path: assets/images/chip3/chip3.jpg
+  AssetGenImage get chip3 =>
+      const AssetGenImage('assets/images/chip3/chip3.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip3];
+}
+
 class $AssetsImagesChip4Gen {
   const $AssetsImagesChip4Gen();
 
   /// File path: assets/images/chip4/chip4.jpg
-  AssetGenImage get chip4 =>
-      const AssetGenImage('assets/images/chip4/chip4.jpg');
+  AssetGenImage get chip4 => const AssetGenImage(
+        'assets/images/chip4/chip4.jpg',
+        flavors: {'extern'},
+      );
 
   /// List of all assets
   List<AssetGenImage> get values => [chip4];
@@ -202,11 +218,16 @@ class MyAssets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -280,17 +301,19 @@ class AssetGenImage {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
   SvgPicture svg({
@@ -313,12 +336,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
@@ -342,9 +376,13 @@ class SvgGenImage {
 }
 
 class FlareGenImage {
-  const FlareGenImage(this._assetName);
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   FlareActor flare({
     String? boundsNode,
@@ -385,9 +423,13 @@ class FlareGenImage {
 }
 
 class RiveGenImage {
-  const RiveGenImage(this._assetName);
+  const RiveGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   RiveAnimation rive({
     String? artboard,
@@ -422,9 +464,13 @@ class RiveGenImage {
 }
 
 class LottieGenImage {
-  const LottieGenImage(this._assetName);
+  const LottieGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   LottieBuilder lottie({
     Animation<double>? controller,
diff --git a/examples/example/pubspec.yaml b/examples/example/pubspec.yaml
index fd9faa368..4e92cb1d8 100644
--- a/examples/example/pubspec.yaml
+++ b/examples/example/pubspec.yaml
@@ -51,7 +51,6 @@ flutter_gen:
       style: dot-delimiter
 
     exclude:
-      - assets/images/chip3/chip3.jpg
       - assets-extern/*
       - pictures/chip5.jpg
 
@@ -76,7 +75,6 @@ flutter:
     - assets/images/
     - assets/images/chip3/chip3.jpg
     - assets/images/chip3/chip3.jpg # duplicated
-    - assets/images/chip4/
     - assets/images/icons/fuchsia.svg
     - assets/images/icons/kmm.svg
     - assets/images/icons/paint.svg
@@ -91,6 +89,10 @@ flutter:
     - assets/mix/
     - assets-extern/
     - pictures/chip5.jpg
+
+    - path: assets/images/chip4/chip4.jpg
+      flavors:
+        - extern
   fonts:
     - family: Raleway
       fonts:
diff --git a/packages/core/lib/generators/assets_generator.dart b/packages/core/lib/generators/assets_generator.dart
index 60d638aec..2547f0d48 100644
--- a/packages/core/lib/generators/assets_generator.dart
+++ b/packages/core/lib/generators/assets_generator.dart
@@ -13,11 +13,13 @@ import 'package:flutter_gen_core/generators/integrations/rive_integration.dart';
 import 'package:flutter_gen_core/generators/integrations/svg_integration.dart';
 import 'package:flutter_gen_core/settings/asset_type.dart';
 import 'package:flutter_gen_core/settings/config.dart';
+import 'package:flutter_gen_core/settings/flavored_asset.dart';
 import 'package:flutter_gen_core/settings/pubspec.dart';
 import 'package:flutter_gen_core/utils/error.dart';
 import 'package:flutter_gen_core/utils/string.dart';
 import 'package:glob/glob.dart';
 import 'package:path/path.dart';
+import 'package:yaml/yaml.dart';
 
 class AssetsGenConfig {
   AssetsGenConfig._(
@@ -41,7 +43,7 @@ class AssetsGenConfig {
   final String rootPath;
   final String _packageName;
   final FlutterGen flutterGen;
-  final List<String> assets;
+  final List<Object> assets;
   final List<Glob> exclude;
 
   String get packageParameterLiteral =>
@@ -194,51 +196,89 @@ String? generatePackageNameForConfig(AssetsGenConfig config) {
   }
 }
 
-/// Returns a list of all releative path assets that are to be considered.
-List<String> _getAssetRelativePathList(
+/// Returns a list of all relative path assets that are to be considered.
+List<FlavoredAsset> _getAssetRelativePathList(
   /// The absolute root path of the assets directory.
   String rootPath,
 
-  /// List of assets as provided the `flutter`.`assets` section in the pubspec.yaml.
-  List<String> assets,
+  /// List of assets as provided the `flutter -> assets`
+  /// section in the pubspec.yaml.
+  List<Object> assets,
 
-  /// List of globs as provided the `flutter_gen`.`assets`.`exclude` section in the pubspec.yaml.
+  /// List of globs as provided the `flutter_gen -> assets -> exclude`
+  /// section in the pubspec.yaml.
   List<Glob> excludes,
 ) {
-  final assetRelativePathList = <String>[];
-  for (final assetName in assets) {
-    final assetAbsolutePath = join(rootPath, assetName);
+  // Normalize.
+  final normalizedAssets = <Object>{...assets.whereType<String>()};
+  final normalizingMap = <String, Set<String>>{};
+  // Resolve flavored assets.
+  for (final map in assets.whereType<YamlMap>()) {
+    final path = (map['path'] as String).trim();
+    final flavors =
+        (map['flavors'] as YamlList?)?.toSet().cast<String>() ?? <String>{};
+    if (normalizingMap.containsKey(path)) {
+      // https://github.com/flutter/flutter/blob/5187cab7bdd434ca74abb45895d17e9fa553678a/packages/flutter_tools/lib/src/asset.dart#L1137-L1139
+      throw StateError(
+        'Multiple assets entries include the file "$path", '
+        'but they specify different lists of flavors.',
+      );
+    }
+    normalizingMap[path] = flavors;
+  }
+  for (final entry in normalizingMap.entries) {
+    normalizedAssets.add(
+      YamlMap.wrap({'path': entry.key, 'flavors': entry.value}),
+    );
+  }
+
+  final assetRelativePathList = <FlavoredAsset>[];
+  for (final asset in normalizedAssets) {
+    final FlavoredAsset tempAsset;
+    if (asset is YamlMap) {
+      tempAsset = FlavoredAsset(path: asset['path'], flavors: asset['flavors']);
+    } else {
+      tempAsset = FlavoredAsset(path: (asset as String).trim());
+    }
+    final assetAbsolutePath = join(rootPath, tempAsset.path);
     if (FileSystemEntity.isDirectorySync(assetAbsolutePath)) {
       assetRelativePathList.addAll(Directory(assetAbsolutePath)
           .listSync()
           .whereType<File>()
-          .map((e) => relative(e.path, from: rootPath))
+          .map(
+            (e) => tempAsset.copyWith(path: relative(e.path, from: rootPath)),
+          )
           .toList());
     } else if (FileSystemEntity.isFileSync(assetAbsolutePath)) {
-      assetRelativePathList.add(relative(assetAbsolutePath, from: rootPath));
+      assetRelativePathList.add(
+        tempAsset.copyWith(path: relative(assetAbsolutePath, from: rootPath)),
+      );
     }
   }
 
   if (excludes.isEmpty) {
     return assetRelativePathList;
   }
-
   return assetRelativePathList
-      .where((file) => !excludes.any((exclude) => exclude.matches(file)))
+      .where((asset) => !excludes.any((exclude) => exclude.matches(asset.path)))
       .toList();
 }
 
 AssetType _constructAssetTree(
-    List<String> assetRelativePathList, String rootPath) {
+  List<FlavoredAsset> assetRelativePathList,
+  String rootPath,
+) {
   // Relative path is the key
   final assetTypeMap = <String, AssetType>{
-    '.': AssetType(rootPath: rootPath, path: '.'),
+    '.': AssetType(rootPath: rootPath, path: '.', flavors: {}),
   };
-  for (final assetPath in assetRelativePathList) {
-    var path = assetPath;
+  for (final asset in assetRelativePathList) {
+    String path = asset.path;
     while (path != '.') {
       assetTypeMap.putIfAbsent(
-          path, () => AssetType(rootPath: rootPath, path: path));
+        path,
+        () => AssetType(rootPath: rootPath, path: path, flavors: asset.flavors),
+      );
       path = dirname(path);
     }
   }
@@ -320,7 +360,8 @@ String _dotDelimiterStyleDefinition(
   final assetsStaticStatements = <_Statement>[];
 
   final assetTypeQueue = ListQueue<AssetType>.from(
-      _constructAssetTree(assetRelativePathList, rootPath).children);
+    _constructAssetTree(assetRelativePathList, rootPath).children,
+  );
 
   while (assetTypeQueue.isNotEmpty) {
     final assetType = assetTypeQueue.removeFirst();
@@ -428,14 +469,20 @@ String _flatStyleDefinition(
   List<Integration> integrations,
   String Function(String) style,
 ) {
-  final statements = _getAssetRelativePathList(
+  final List<FlavoredAsset> paths = _getAssetRelativePathList(
     config.rootPath,
     config.assets,
     config.exclude,
-  )
-      .distinct()
-      .sorted()
-      .map((assetPath) => AssetType(rootPath: config.rootPath, path: assetPath))
+  );
+  paths.sort(((a, b) => a.path.compareTo(b.path)));
+  final statements = paths
+      .map(
+        (assetPath) => AssetType(
+          rootPath: config.rootPath,
+          path: assetPath.path,
+          flavors: assetPath.flavors,
+        ),
+      )
       .mapToUniqueAssetType(style)
       .map(
         (e) => _createAssetTypeStatement(
diff --git a/packages/core/lib/generators/integrations/flare_integration.dart b/packages/core/lib/generators/integrations/flare_integration.dart
index db2b4dcc2..e8644e16f 100644
--- a/packages/core/lib/generators/integrations/flare_integration.dart
+++ b/packages/core/lib/generators/integrations/flare_integration.dart
@@ -17,9 +17,14 @@ class FlareIntegration extends Integration {
   String get classOutput => _classDefinition;
 
   String get _classDefinition => '''class FlareGenImage {
-  const FlareGenImage(this._assetName);
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
+
 ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   FlareActor flare({
@@ -63,10 +68,6 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
   @override
   String get className => 'FlareGenImage';
 
-  @override
-  String classInstantiate(AssetType asset) =>
-      'FlareGenImage(\'${asset.posixStylePath}\')';
-
   @override
   bool isSupport(AssetType asset) => asset.extension == '.flr';
 
diff --git a/packages/core/lib/generators/integrations/image_integration.dart b/packages/core/lib/generators/integrations/image_integration.dart
index 672675786..17c71b561 100644
--- a/packages/core/lib/generators/integrations/image_integration.dart
+++ b/packages/core/lib/generators/integrations/image_integration.dart
@@ -10,8 +10,10 @@ import 'package:image_size_getter/image_size_getter.dart';
 ///
 /// This integration is by enabled by default.
 class ImageIntegration extends Integration {
-  ImageIntegration(String packageName, {super.parseMetadata})
-      : super(packageName);
+  ImageIntegration(
+    String packageName, {
+    super.parseMetadata,
+  }) : super(packageName);
 
   String get packageParameter => isPackage ? ' = package' : '';
 
@@ -25,12 +27,18 @@ class ImageIntegration extends Integration {
   String get classOutput => _classDefinition;
 
   String get _classDefinition => '''class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
+
 ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -109,11 +117,22 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   @override
   String classInstantiate(AssetType asset) {
-    ImageMetadata? info = parseMetadata ? _getMetadata(asset) : null;
-
-    return 'AssetGenImage(\'${asset.posixStylePath}\''
-        '${(info != null) ? ', size: Size(${info.width}, ${info.height})' : ''}'
-        ')';
+    final info = parseMetadata ? _getMetadata(asset) : null;
+    final buffer = StringBuffer(className);
+    buffer.write('(');
+    buffer.write('\'${asset.posixStylePath}\'');
+    if (info != null) {
+      buffer.write(', size: Size(${info.width}, ${info.height})');
+    }
+    if (asset.flavors.isNotEmpty) {
+      buffer.write(', flavors: {');
+      final flavors = asset.flavors.map((e) => '\'$e\'').join(', ');
+      buffer.write(flavors);
+      buffer.write('}');
+      buffer.write(','); // Better formatting.
+    }
+    buffer.write(')');
+    return buffer.toString();
   }
 
   @override
diff --git a/packages/core/lib/generators/integrations/integration.dart b/packages/core/lib/generators/integrations/integration.dart
index f4aa8bad8..4a32c713a 100644
--- a/packages/core/lib/generators/integrations/integration.dart
+++ b/packages/core/lib/generators/integrations/integration.dart
@@ -19,12 +19,25 @@ abstract class Integration {
 
   String get className;
 
-  String classInstantiate(AssetType asset);
-
   /// Is this asset type supported by this integration?
   bool isSupport(AssetType asset);
 
   bool get isConstConstructor;
+
+  String classInstantiate(AssetType asset) {
+    final buffer = StringBuffer(className);
+    buffer.write('(');
+    buffer.write('\'${asset.posixStylePath}\'');
+    if (asset.flavors.isNotEmpty) {
+      buffer.write(', flavors: {');
+      final flavors = asset.flavors.map((e) => '\'$e\'').join(', ');
+      buffer.write(flavors);
+      buffer.write('}');
+      buffer.write(','); // Better formatting.
+    }
+    buffer.write(')');
+    return buffer.toString();
+  }
 }
 
 /// The deprecation message for the package argument
diff --git a/packages/core/lib/generators/integrations/lottie_integration.dart b/packages/core/lib/generators/integrations/lottie_integration.dart
index 264153404..ac9bddd6e 100644
--- a/packages/core/lib/generators/integrations/lottie_integration.dart
+++ b/packages/core/lib/generators/integrations/lottie_integration.dart
@@ -32,9 +32,14 @@ class LottieIntegration extends Integration {
   String get classOutput => _classDefinition;
 
   String get _classDefinition => '''class LottieGenImage {
-  const LottieGenImage(this._assetName);
+  const LottieGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
+
 ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   LottieBuilder lottie({
@@ -95,10 +100,6 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
   @override
   String get className => 'LottieGenImage';
 
-  @override
-  String classInstantiate(AssetType asset) =>
-      'LottieGenImage(\'${asset.posixStylePath}\')';
-
   @override
   bool isSupport(AssetType asset) => isLottieFile(asset);
 
diff --git a/packages/core/lib/generators/integrations/rive_integration.dart b/packages/core/lib/generators/integrations/rive_integration.dart
index 9830e4ff7..98742c54e 100644
--- a/packages/core/lib/generators/integrations/rive_integration.dart
+++ b/packages/core/lib/generators/integrations/rive_integration.dart
@@ -16,9 +16,14 @@ class RiveIntegration extends Integration {
   String get classOutput => _classDefinition;
 
   String get _classDefinition => '''class RiveGenImage {
-  const RiveGenImage(this._assetName);
+  const RiveGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
+
 ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   RiveAnimation rive({
@@ -56,10 +61,6 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
   @override
   String get className => 'RiveGenImage';
 
-  @override
-  String classInstantiate(AssetType asset) =>
-      'RiveGenImage(\'${asset.posixStylePath}\')';
-
   @override
   bool isSupport(AssetType asset) => asset.extension == '.riv';
 
diff --git a/packages/core/lib/generators/integrations/svg_integration.dart b/packages/core/lib/generators/integrations/svg_integration.dart
index 247afb1c9..1e21e1839 100644
--- a/packages/core/lib/generators/integrations/svg_integration.dart
+++ b/packages/core/lib/generators/integrations/svg_integration.dart
@@ -24,20 +24,23 @@ class SvgIntegration extends Integration {
   String get _classDefinition => '''class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
   
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-${isPackage ? "\n  static const String package = '$packageName';" : ''}
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
+${isPackage ? "\n  static const String package = '$packageName';" : ''}
+
   SvgPicture svg({
     Key? key,
     bool matchTextDirection = false,
@@ -59,10 +62,23 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat ? 
-        AssetBytesLoader(_assetName, assetBundle: bundle, packageName: package) :
-        SvgAssetLoader(_assetName, assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
@@ -89,31 +105,42 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   @override
   String classInstantiate(AssetType asset) {
-    // Query extra information about the SVG
-    ImageMetadata? info = parseMetadata ? _getMetadata(asset) : null;
-
-    final String constructorName =
-        asset.extension == '.vec' ? 'SvgGenImage.vec' : 'SvgGenImage';
-
-    return "$constructorName('${asset.posixStylePath}'"
-        "${(info != null) ? ', size: Size(${info.width}, ${info.height})' : ''}"
-        ')';
+    // Query extra information about the SVG.
+    final info = parseMetadata ? _getMetadata(asset) : null;
+    final buffer = StringBuffer(className);
+    if (asset.extension == '.vec') {
+      buffer.write('.vec');
+    }
+    buffer.write('(');
+    buffer.write('\'${asset.posixStylePath}\'');
+    if (info != null) {
+      buffer.write(', size: Size(${info.width}, ${info.height})');
+    }
+    if (asset.flavors.isNotEmpty) {
+      buffer.write(', flavors: {');
+      final flavors = asset.flavors.map((e) => '\'$e\'').join(', ');
+      buffer.write(flavors);
+      buffer.write('}');
+      buffer.write(','); // Better formatting.
+    }
+    buffer.write(')');
+    return buffer.toString();
   }
 
   ImageMetadata? _getMetadata(AssetType asset) {
     try {
       // The SVG file is read fully, then parsed with the vector_graphics
-      // library. This is quite a heavy way to extract just the dimenions, but
-      // it's also the same way it will be eventually rendered by Flutter.
+      // library. This is quite a heavy way to extract just the dimensions,
+      // but it's also the same way it will be eventually rendered by Flutter.
       final svg = File(asset.fullPath).readAsStringSync();
       final vec = parseWithoutOptimizers(svg);
       return ImageMetadata(vec.width, vec.height);
     } catch (e) {
       stderr.writeln(
-          '[WARNING] Failed to parse SVG \'${asset.path}\' metadata: $e');
+        '[WARNING] Failed to parse SVG \'${asset.path}\' metadata: $e',
+      );
+      return null;
     }
-
-    return null;
   }
 
   @override
diff --git a/packages/core/lib/settings/asset_type.dart b/packages/core/lib/settings/asset_type.dart
index 0f682c034..3c2fee972 100644
--- a/packages/core/lib/settings/asset_type.dart
+++ b/packages/core/lib/settings/asset_type.dart
@@ -7,10 +7,15 @@ import 'package:path/path.dart';
 
 /// https://github.com/dart-lang/mime/blob/master/lib/src/default_extension_map.dart
 class AssetType {
-  AssetType({required this.rootPath, required this.path});
+  AssetType({
+    required this.rootPath,
+    required this.path,
+    required this.flavors,
+  });
 
   final String rootPath;
   final String path;
+  final Set<String> flavors;
 
   final List<AssetType> _children = List.empty(growable: true);
 
@@ -68,7 +73,11 @@ class UniqueAssetType extends AssetType {
     this.basenameOnly = false,
     this.needExtension = false,
     this.suffix = '',
-  }) : super(rootPath: assetType.rootPath, path: assetType.path);
+  }) : super(
+          rootPath: assetType.rootPath,
+          path: assetType.path,
+          flavors: assetType.flavors,
+        );
 
   /// Convert the asset name to a correctly styled name, e.g camelCase or
   /// snakeCase.
diff --git a/packages/core/lib/settings/flavored_asset.dart b/packages/core/lib/settings/flavored_asset.dart
new file mode 100644
index 000000000..66e24aa03
--- /dev/null
+++ b/packages/core/lib/settings/flavored_asset.dart
@@ -0,0 +1,19 @@
+class FlavoredAsset {
+  const FlavoredAsset({
+    required this.path,
+    this.flavors = const {},
+  });
+
+  final String path;
+  final Set<String> flavors;
+
+  FlavoredAsset copyWith({String? path, Set<String>? flavors}) {
+    return FlavoredAsset(
+      path: path ?? this.path,
+      flavors: flavors ?? this.flavors,
+    );
+  }
+
+  @override
+  String toString() => 'FlavoredAsset(path: $path, flavors: $flavors)';
+}
diff --git a/packages/core/lib/settings/pubspec.dart b/packages/core/lib/settings/pubspec.dart
index f2592a4e7..62436f6b5 100644
--- a/packages/core/lib/settings/pubspec.dart
+++ b/packages/core/lib/settings/pubspec.dart
@@ -32,7 +32,7 @@ class Flutter {
   });
 
   @JsonKey(name: 'assets', required: true)
-  final List<String> assets;
+  final List<Object> assets;
 
   @JsonKey(name: 'fonts', required: true)
   final List<FlutterFonts> fonts;
diff --git a/packages/core/lib/settings/pubspec.g.dart b/packages/core/lib/settings/pubspec.g.dart
index 9945fcdb5..c03f15b07 100644
--- a/packages/core/lib/settings/pubspec.g.dart
+++ b/packages/core/lib/settings/pubspec.g.dart
@@ -36,7 +36,7 @@ Flutter _$FlutterFromJson(Map json) => $checkedCreate(
         );
         final val = Flutter(
           assets: $checkedConvert('assets',
-              (v) => (v as List<dynamic>).map((e) => e as String).toList()),
+              (v) => (v as List<dynamic>).map((e) => e as Object).toList()),
           fonts: $checkedConvert(
               'fonts',
               (v) => (v as List<dynamic>)
diff --git a/packages/runner/lib/flutter_gen_runner.dart b/packages/runner/lib/flutter_gen_runner.dart
index e3b047ec4..47c085fdb 100644
--- a/packages/runner/lib/flutter_gen_runner.dart
+++ b/packages/runner/lib/flutter_gen_runner.dart
@@ -6,8 +6,10 @@ import 'package:collection/collection.dart';
 import 'package:crypto/crypto.dart';
 import 'package:flutter_gen_core/flutter_generator.dart';
 import 'package:flutter_gen_core/settings/config.dart';
+import 'package:flutter_gen_core/settings/flavored_asset.dart';
 import 'package:glob/glob.dart';
 import 'package:path/path.dart';
+import 'package:yaml/yaml.dart';
 
 Builder build(BuilderOptions options) => FlutterGenBuilder();
 
@@ -60,13 +62,30 @@ class FlutterGenBuilder extends Builder {
   ) async {
     final pubspec = config.pubspec;
 
-    final HashSet<String> assets = HashSet();
+    final HashSet<FlavoredAsset> assets = HashSet();
     if (pubspec.flutterGen.assets.enabled) {
-      for (var assetInput in pubspec.flutter.assets) {
-        if (assetInput.isEmpty) continue;
-        if (assetInput.endsWith('/')) assetInput += '*';
+      for (final asset in pubspec.flutter.assets) {
+        final FlavoredAsset flavored;
+        String assetInput;
+        if (asset is YamlMap) {
+          flavored = FlavoredAsset(
+            path: asset['path'],
+            flavors:
+                (asset['flavors'] as YamlList?)?.toSet().cast() ?? <String>{},
+          );
+          assetInput = asset['path'];
+        } else {
+          flavored = FlavoredAsset(path: asset as String);
+          assetInput = asset;
+        }
+        if (assetInput.isEmpty) {
+          continue;
+        }
+        if (assetInput.endsWith('/')) {
+          assetInput += '*';
+        }
         await for (final assetId in buildStep.findAssets(Glob(assetInput))) {
-          assets.add(assetId.path);
+          assets.add(flavored.copyWith(path: assetId.path));
         }
       }
     }
@@ -96,16 +115,16 @@ class FlutterGenBuilder extends Builder {
 }
 
 class _FlutterGenBuilderState {
-  final Digest pubspecDigest;
-  final HashSet<String> assets;
-  final HashMap<String, Digest> colors;
-
-  _FlutterGenBuilderState({
+  const _FlutterGenBuilderState({
     required this.pubspecDigest,
     required this.assets,
     required this.colors,
   });
 
+  final Digest pubspecDigest;
+  final HashSet<FlavoredAsset> assets;
+  final HashMap<String, Digest> colors;
+
   bool shouldSkipGenerate(_FlutterGenBuilderState? previous) {
     if (previous == null) return false;
     return pubspecDigest == previous.pubspecDigest &&
diff --git a/packages/runner/pubspec.yaml b/packages/runner/pubspec.yaml
index e35371b03..fa12a4777 100644
--- a/packages/runner/pubspec.yaml
+++ b/packages/runner/pubspec.yaml
@@ -16,6 +16,7 @@ dependencies:
   crypto: ^3.0.0
   glob: ^2.0.0
   path: ^1.8.0
+  yaml: ^3.0.0
 
 dev_dependencies:
   lints: any # Ignoring the version to allow editing across SDK versions.


Test patch:
diff --git a/packages/core/test/assets_gen_integrations_test.dart b/packages/core/test/assets_gen_integrations_test.dart
index 3fc67a039..66002d32b 100644
--- a/packages/core/test/assets_gen_integrations_test.dart
+++ b/packages/core/test/assets_gen_integrations_test.dart
@@ -1,5 +1,6 @@
 @TestOn('vm')
 import 'package:flutter_gen_core/generators/integrations/flare_integration.dart';
+import 'package:flutter_gen_core/generators/integrations/integration.dart';
 import 'package:flutter_gen_core/generators/integrations/lottie_integration.dart';
 import 'package:flutter_gen_core/generators/integrations/rive_integration.dart';
 import 'package:flutter_gen_core/generators/integrations/svg_integration.dart';
@@ -9,6 +10,27 @@ import 'package:test/test.dart';
 
 import 'gen_test_helper.dart';
 
+class TestIntegration extends Integration {
+  TestIntegration() : super('');
+
+  @override
+  String get className => 'TestIntegration';
+
+  @override
+  String get classOutput => throw UnimplementedError();
+
+  @override
+  bool get isConstConstructor => true;
+
+  @override
+  bool isSupport(AssetType asset) {
+    return true;
+  }
+
+  @override
+  List<String> get requiredImports => [];
+}
+
 void main() {
   group('Test Assets Integration generator', () {
     final resPath = p.absolute('test_resources');
@@ -21,6 +43,15 @@ void main() {
       await expectedAssetsGen(pubspec, generated, fact);
     });
 
+    test('Integration.classInstantiate', () {
+      expect(
+        TestIntegration().classInstantiate(
+          AssetType(rootPath: resPath, path: 'assets/path', flavors: {'test'}),
+        ),
+        'TestIntegration(\'assets/path\', flavors: {\'test\'},)',
+      );
+    });
+
     test('Assets with Svg integrations on pubspec.yaml', () async {
       const pubspec = 'test_resources/pubspec_assets_svg_integrations.yaml';
       const fact =
@@ -34,17 +65,64 @@ void main() {
       expect(integration.className, 'SvgGenImage');
       expect(
         integration.classInstantiate(
-            AssetType(rootPath: resPath, path: 'assets/path')),
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path',
+            flavors: {},
+          ),
+        ),
         'SvgGenImage(\'assets/path\')',
       );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.svg')),
-          isTrue);
+        integration.classInstantiate(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path',
+            flavors: {'test'},
+          ),
+        ),
+        'SvgGenImage(\'assets/path\', flavors: {\'test\'},)',
+      );
+      expect(
+        integration.classInstantiate(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.vec',
+            flavors: {},
+          ),
+        ),
+        'SvgGenImage.vec(\'assets/path/dog.vec\')',
+      );
+      expect(
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.svg',
+            flavors: {},
+          ),
+        ),
+        isTrue,
+      );
+      expect(
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.vec',
+            flavors: {},
+          ),
+        ),
+        isTrue,
+      );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.png')),
-          isFalse);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.png',
+            flavors: {},
+          ),
+        ),
+        isFalse,
+      );
       expect(integration.isConstConstructor, isTrue);
       expect(integration.classOutput.contains('String? package,'), isTrue);
 
@@ -75,17 +153,35 @@ void main() {
       final integration = FlareIntegration('');
       expect(integration.className, 'FlareGenImage');
       expect(
-          integration.classInstantiate(
-              AssetType(rootPath: resPath, path: 'assets/path')),
-          'FlareGenImage(\'assets/path\')');
+        integration.classInstantiate(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path',
+            flavors: {},
+          ),
+        ),
+        'FlareGenImage(\'assets/path\')',
+      );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.flr')),
-          isTrue);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.flr',
+            flavors: {},
+          ),
+        ),
+        isTrue,
+      );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.json')),
-          isFalse);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.json',
+            flavors: {},
+          ),
+        ),
+        isFalse,
+      );
       expect(integration.isConstConstructor, isTrue);
       expect(integration.classOutput.contains('_assetName,'), isTrue);
 
@@ -109,17 +205,35 @@ void main() {
       final integration = RiveIntegration('');
       expect(integration.className, 'RiveGenImage');
       expect(
-          integration.classInstantiate(
-              AssetType(rootPath: resPath, path: 'assets/path')),
-          'RiveGenImage(\'assets/path\')');
+        integration.classInstantiate(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path',
+            flavors: {},
+          ),
+        ),
+        'RiveGenImage(\'assets/path\')',
+      );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.riv')),
-          isTrue);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.riv',
+            flavors: {},
+          ),
+        ),
+        isTrue,
+      );
       expect(
-          integration.isSupport(
-              AssetType(rootPath: resPath, path: 'assets/path/dog.json')),
-          isFalse);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/path/dog.json',
+            flavors: {},
+          ),
+        ),
+        isFalse,
+      );
       expect(integration.isConstConstructor, isTrue);
       expect(integration.classOutput.contains('_assetName,'), isTrue);
 
@@ -143,18 +257,35 @@ void main() {
       final integration = LottieIntegration('');
       expect(integration.className, 'LottieGenImage');
       expect(
-          integration.classInstantiate(
-              AssetType(rootPath: resPath, path: 'assets/lottie')),
-          'LottieGenImage(\'assets/lottie\')');
+        integration.classInstantiate(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/lottie',
+            flavors: {},
+          ),
+        ),
+        'LottieGenImage(\'assets/lottie\')',
+      );
       expect(
-          integration.isSupport(AssetType(
-              rootPath: resPath, path: 'assets/lottie/hamburger_arrow.json')),
-          isTrue);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/lottie/hamburger_arrow.json',
+            flavors: {},
+          ),
+        ),
+        isTrue,
+      );
       expect(
-          integration.isSupport(AssetType(
-              rootPath: resPath,
-              path: 'assets/lottie/hamburger_arrow_without_version.json')),
-          isFalse);
+        integration.isSupport(
+          AssetType(
+            rootPath: resPath,
+            path: 'assets/lottie/hamburger_arrow_without_version.json',
+            flavors: {},
+          ),
+        ),
+        isFalse,
+      );
       expect(integration.isConstConstructor, isTrue);
       expect(integration.classOutput.contains('String? package,'), isTrue);
 
diff --git a/packages/core/test/assets_gen_test.dart b/packages/core/test/assets_gen_test.dart
index 4f3315d22..ec2d11f41 100644
--- a/packages/core/test/assets_gen_test.dart
+++ b/packages/core/test/assets_gen_test.dart
@@ -127,6 +127,28 @@ void main() {
       await expectedAssetsGen(pubspec, generated, fact);
     });
 
+    test('Assets with flavored assets', () async {
+      const pubspec = 'test_resources/pubspec_assets_flavored.yaml';
+      const fact = 'test_resources/actual_data/assets_flavored.gen.dart';
+      const generated = 'test_resources/lib/gen/assets_flavored.gen.dart';
+
+      await expectedAssetsGen(pubspec, generated, fact);
+    });
+
+    test('Assets with duplicate flavoring entries', () async {
+      const pubspec =
+          'test_resources/pubspec_assets_flavored_duplicate_entry.yaml';
+      const fact =
+          'test_resources/actual_data/assets_flavored_duplicate_entry.gen.dart';
+      const generated =
+          'test_resources/lib/gen/assets_flavored_duplicate_entry.gen.dart';
+
+      await expectLater(
+        () => runAssetsGen(pubspec, generated, fact),
+        throwsA(isA<StateError>()),
+      );
+    });
+
     test('Assets with terrible names (camelCase)', () async {
       // See [AssetTypeIterable.mapToUniqueAssetType] for the rules for picking
       // identifer names.
@@ -143,7 +165,8 @@ void main() {
         'assets/profilePng.jpg': 'profilePngJpg',
 
         // Asset overlapping with a directory name.
-        'assets/image': 'image', // Directory
+        'assets/image': 'image',
+        // Directory
         'assets/image.jpg': 'imageJpg',
 
         // Asset with no base name (but ends up overlapping the previous asset)
@@ -155,12 +178,18 @@ void main() {
         'assets/français.jpg': 'franAis',
 
         // Dart Reserved Words
-        'assets/async.png': 'async', // allowed
-        'assets/abstract.png': 'abstract', // allowed
-        'assets/await.png': 'awaitPng', // must be suffixed (but can use Png)
-        'assets/assert.png': 'assertPng', // must be suffixed (but can use Png)
-        'assets/await': 'await_', //  must be suffixed
-        'assets/assert': 'assert_', // must be suffixed
+        // allowed
+        'assets/async.png': 'async',
+        // allowed
+        'assets/abstract.png': 'abstract',
+        // must be suffixed (but can use Png)
+        'assets/await.png': 'awaitPng',
+        // must be suffixed (but can use Png)
+        'assets/assert.png': 'assertPng',
+        //  must be suffixed
+        'assets/await': 'await_',
+        // must be suffixed
+        'assets/assert': 'assert_',
 
         // Asset with a number as the first character
         'assets/7up.png': 'a7up',
@@ -176,12 +205,12 @@ void main() {
 
       final List<AssetType> assets = tests.keys
           .sorted()
-          .map((e) => AssetType(rootPath: '', path: e))
+          .map((e) => AssetType(rootPath: '', path: e, flavors: {}))
           .toList();
 
       final got = assets.mapToUniqueAssetType(camelCase);
 
-      // Expect no dups.
+      // Expect no duplicates.
       final names = got.map((e) => e.name);
       expect(names.sorted(), tests.values.sorted());
     });
diff --git a/packages/core/test/config_test.dart b/packages/core/test/config_test.dart
index ab73b3a23..53cc117d6 100644
--- a/packages/core/test/config_test.dart
+++ b/packages/core/test/config_test.dart
@@ -1,1 +1,36 @@
-void main() {}
+import 'package:collection/collection.dart';
+import 'package:flutter_gen_core/settings/flavored_asset.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group(FlavoredAsset, () {
+    test('constructor', () {
+      expect(
+        FlavoredAsset(path: '').toString(),
+        'FlavoredAsset(path: , flavors: {})',
+      );
+      expect(
+        FlavoredAsset(path: 'assets/path'),
+        isA<FlavoredAsset>(),
+      );
+      expect(
+        FlavoredAsset(path: 'assets/path', flavors: {}),
+        isA<FlavoredAsset>(),
+      );
+      expect(
+        FlavoredAsset(path: 'assets/path', flavors: {'test'}),
+        isA<FlavoredAsset>(),
+      );
+      expect(
+        FlavoredAsset(path: '1').copyWith(path: '2'),
+        predicate<FlavoredAsset>((e) => e.path == '2'),
+      );
+      expect(
+        FlavoredAsset(path: '1').copyWith(flavors: {'test'}),
+        predicate<FlavoredAsset>(
+          (e) => SetEquality().equals(e.flavors, {'test'}),
+        ),
+      );
+    });
+  });
+}
diff --git a/packages/core/test/gen_test_helper.dart b/packages/core/test/gen_test_helper.dart
index e6c48d82b..6543fc595 100644
--- a/packages/core/test/gen_test_helper.dart
+++ b/packages/core/test/gen_test_helper.dart
@@ -12,22 +12,41 @@ import 'package:test/test.dart';
 
 Future<void> clearTestResults() async {}
 
-/// Assets
-Future<void> expectedAssetsGen(
-    String pubspec, String generated, String fact) async {
-  await FlutterGenerator(File(pubspec), assetsName: p.basename(generated))
-      .build();
+Future<List<String>> runAssetsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  await FlutterGenerator(
+    File(pubspec),
+    assetsName: p.basename(generated),
+  ).build();
 
   final pubspecFile = File(pubspec);
   final config = loadPubspecConfig(pubspecFile);
   final formatter = DartFormatter(
-      pageWidth: config.pubspec.flutterGen.lineLength, lineEnding: '\n');
+    pageWidth: config.pubspec.flutterGen.lineLength,
+    lineEnding: '\n',
+  );
 
   final actual = generateAssets(
-      AssetsGenConfig.fromConfig(pubspecFile, config), formatter);
-  final expected =
-      formatter.format(File(fact).readAsStringSync().replaceAll('\r\n', '\n'));
+    AssetsGenConfig.fromConfig(pubspecFile, config),
+    formatter,
+  );
+  final expected = formatter.format(
+    File(fact).readAsStringSync().replaceAll('\r\n', '\n'),
+  );
+  return [actual, expected];
+}
 
+/// Assets
+Future<void> expectedAssetsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  final results = await runAssetsGen(pubspec, generated, fact);
+  final actual = results.first, expected = results.last;
   expect(
     File(generated).readAsStringSync(),
     isNotEmpty,
@@ -35,22 +54,42 @@ Future<void> expectedAssetsGen(
   expect(actual, expected);
 }
 
-/// Colors
-Future<void> expectedColorsGen(
-    String pubspec, String generated, String fact) async {
-  await FlutterGenerator(File(pubspec), colorsName: p.basename(generated))
-      .build();
+Future<List<String>> runColorsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  await FlutterGenerator(
+    File(pubspec),
+    colorsName: p.basename(generated),
+  ).build();
 
   final pubspecFile = File(pubspec);
   final config = loadPubspecConfig(pubspecFile);
   final formatter = DartFormatter(
-      pageWidth: config.pubspec.flutterGen.lineLength, lineEnding: '\n');
+    pageWidth: config.pubspec.flutterGen.lineLength,
+    lineEnding: '\n',
+  );
 
-  final actual =
-      generateColors(pubspecFile, formatter, config.pubspec.flutterGen.colors);
-  final expected =
-      formatter.format(File(fact).readAsStringSync().replaceAll('\r\n', '\n'));
+  final actual = generateColors(
+    pubspecFile,
+    formatter,
+    config.pubspec.flutterGen.colors,
+  );
+  final expected = formatter.format(
+    File(fact).readAsStringSync().replaceAll('\r\n', '\n'),
+  );
+  return [actual, expected];
+}
 
+/// Colors
+Future<void> expectedColorsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  final results = await runColorsGen(pubspec, generated, fact);
+  final actual = results.first, expected = results.last;
   expect(
     File(generated).readAsStringSync(),
     isNotEmpty,
@@ -58,22 +97,43 @@ Future<void> expectedColorsGen(
   expect(actual, expected);
 }
 
-/// Fonts
-Future<void> expectedFontsGen(
-    String pubspec, String generated, String fact) async {
-  await FlutterGenerator(File(pubspec), fontsName: p.basename(generated))
-      .build();
+Future<List<String>> runFontsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  await FlutterGenerator(
+    File(pubspec),
+    fontsName: p.basename(generated),
+  ).build();
 
   final pubspecFile = File(pubspec);
   final config = loadPubspecConfig(pubspecFile);
   final formatter = DartFormatter(
-      pageWidth: config.pubspec.flutterGen.lineLength, lineEnding: '\n');
+    pageWidth: config.pubspec.flutterGen.lineLength,
+    lineEnding: '\n',
+  );
 
   final actual = generateFonts(
-      formatter, config.pubspec.flutter.fonts, config.pubspec.flutterGen.fonts);
-  final expected =
-      formatter.format(File(fact).readAsStringSync().replaceAll('\r\n', '\n'));
+    formatter,
+    config.pubspec.flutter.fonts,
+    config.pubspec.flutterGen.fonts,
+  );
+  final expected = formatter.format(
+    File(fact).readAsStringSync().replaceAll('\r\n', '\n'),
+  );
+
+  return [actual, expected];
+}
 
+/// Fonts
+Future<void> expectedFontsGen(
+  String pubspec,
+  String generated,
+  String fact,
+) async {
+  final results = await runFontsGen(pubspec, generated, fact);
+  final actual = results.first, expected = results.last;
   expect(
     File(generated).readAsStringSync(),
     isNotEmpty,
diff --git a/packages/core/test_resources/actual_data/assets.gen.dart b/packages/core/test_resources/actual_data/assets.gen.dart
index 623750cb5..acf5974b7 100644
--- a/packages/core/test_resources/actual_data/assets.gen.dart
+++ b/packages/core/test_resources/actual_data/assets.gen.dart
@@ -160,11 +160,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -238,17 +243,19 @@ class AssetGenImage {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
   SvgPicture svg({
@@ -271,12 +278,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
@@ -300,9 +318,13 @@ class SvgGenImage {
 }
 
 class FlareGenImage {
-  const FlareGenImage(this._assetName);
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   FlareActor flare({
     String? boundsNode,
diff --git a/packages/core/test_resources/actual_data/assets_camel_case.gen.dart b/packages/core/test_resources/actual_data/assets_camel_case.gen.dart
index 95df6265c..f409e1043 100644
--- a/packages/core/test_resources/actual_data/assets_camel_case.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_camel_case.gen.dart
@@ -82,11 +82,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
diff --git a/packages/core/test_resources/actual_data/assets_change_class_name.gen.dart b/packages/core/test_resources/actual_data/assets_change_class_name.gen.dart
index e73d70e0a..36f01d714 100644
--- a/packages/core/test_resources/actual_data/assets_change_class_name.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_change_class_name.gen.dart
@@ -41,11 +41,16 @@ class MyAssets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
diff --git a/packages/core/test_resources/actual_data/assets_directory_path.gen.dart b/packages/core/test_resources/actual_data/assets_directory_path.gen.dart
index 0071ab5d1..e4025aad4 100644
--- a/packages/core/test_resources/actual_data/assets_directory_path.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_directory_path.gen.dart
@@ -78,11 +78,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -156,17 +161,19 @@ class AssetGenImage {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
   SvgPicture svg({
@@ -189,12 +196,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
diff --git a/packages/core/test_resources/actual_data/assets_flare_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_flare_integrations.gen.dart
index 231614e7c..02b53db94 100644
--- a/packages/core/test_resources/actual_data/assets_flare_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_flare_integrations.gen.dart
@@ -28,9 +28,13 @@ class Assets {
 }
 
 class FlareGenImage {
-  const FlareGenImage(this._assetName);
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   FlareActor flare({
     String? boundsNode,
diff --git a/packages/core/test_resources/actual_data/assets_flavored.gen.dart b/packages/core/test_resources/actual_data/assets_flavored.gen.dart
new file mode 100644
index 000000000..987e64ade
--- /dev/null
+++ b/packages/core/test_resources/actual_data/assets_flavored.gen.dart
@@ -0,0 +1,367 @@
+/// GENERATED CODE - DO NOT MODIFY BY HAND
+/// *****************************************************
+///  FlutterGen
+/// *****************************************************
+
+// coverage:ignore-file
+// ignore_for_file: type=lint
+// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
+
+import 'package:flutter/widgets.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:vector_graphics/vector_graphics.dart';
+import 'package:flare_flutter/flare_actor.dart';
+import 'package:flare_flutter/flare_controller.dart';
+
+class $PicturesGen {
+  const $PicturesGen();
+
+  /// File path: pictures/chip5.jpg
+  AssetGenImage get chip5 => const AssetGenImage('pictures/chip5.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip5];
+}
+
+class $AssetsFlareGen {
+  const $AssetsFlareGen();
+
+  /// File path: assets/flare/Penguin.flr
+  FlareGenImage get penguin => const FlareGenImage('assets/flare/Penguin.flr');
+
+  /// List of all assets
+  List<FlareGenImage> get values => [penguin];
+}
+
+class $AssetsImagesGen {
+  const $AssetsImagesGen();
+
+  /// File path: assets/images/chip1.jpg
+  AssetGenImage get chip1 => const AssetGenImage('assets/images/chip1.jpg');
+
+  /// File path: assets/images/chip2.jpg
+  AssetGenImage get chip2 => const AssetGenImage('assets/images/chip2.jpg');
+
+  /// Directory path: assets/images/chip3
+  $AssetsImagesChip3Gen get chip3 => const $AssetsImagesChip3Gen();
+
+  /// Directory path: assets/images/chip4
+  $AssetsImagesChip4Gen get chip4 => const $AssetsImagesChip4Gen();
+
+  /// Directory path: assets/images/icons
+  $AssetsImagesIconsGen get icons => const $AssetsImagesIconsGen();
+
+  /// File path: assets/images/logo.png
+  AssetGenImage get logo => const AssetGenImage('assets/images/logo.png');
+
+  /// File path: assets/images/profile.jpg
+  AssetGenImage get profileJpg =>
+      const AssetGenImage('assets/images/profile.jpg');
+
+  /// File path: assets/images/profile.png
+  AssetGenImage get profilePng =>
+      const AssetGenImage('assets/images/profile.png');
+
+  /// List of all assets
+  List<AssetGenImage> get values =>
+      [chip1, chip2, logo, profileJpg, profilePng];
+}
+
+class $AssetsJsonGen {
+  const $AssetsJsonGen();
+
+  /// File path: assets/json/list.json
+  String get list => 'assets/json/list.json';
+
+  /// File path: assets/json/map.json
+  String get map => 'assets/json/map.json';
+
+  /// List of all assets
+  List<String> get values => [list, map];
+}
+
+class $AssetsMovieGen {
+  const $AssetsMovieGen();
+
+  /// File path: assets/movie/the_earth.mp4
+  String get theEarth => 'assets/movie/the_earth.mp4';
+
+  /// List of all assets
+  List<String> get values => [theEarth];
+}
+
+class $AssetsUnknownGen {
+  const $AssetsUnknownGen();
+
+  /// File path: assets/unknown/unknown_mime_type.bk
+  String get unknownMimeType => 'assets/unknown/unknown_mime_type.bk';
+
+  /// List of all assets
+  List<String> get values => [unknownMimeType];
+}
+
+class $AssetsImagesChip3Gen {
+  const $AssetsImagesChip3Gen();
+
+  /// File path: assets/images/chip3/chip3.jpg
+  AssetGenImage get chip3 =>
+      const AssetGenImage('assets/images/chip3/chip3.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip3];
+}
+
+class $AssetsImagesChip4Gen {
+  const $AssetsImagesChip4Gen();
+
+  /// File path: assets/images/chip4/chip4.jpg
+  AssetGenImage get chip4 => const AssetGenImage(
+        'assets/images/chip4/chip4.jpg',
+        flavors: {'test'},
+      );
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip4];
+}
+
+class $AssetsImagesIconsGen {
+  const $AssetsImagesIconsGen();
+
+  /// File path: assets/images/icons/dart@test.svg
+  SvgGenImage get dartTest =>
+      const SvgGenImage('assets/images/icons/dart@test.svg');
+
+  /// File path: assets/images/icons/fuchsia.svg
+  SvgGenImage get fuchsia =>
+      const SvgGenImage('assets/images/icons/fuchsia.svg');
+
+  /// File path: assets/images/icons/kmm.svg
+  SvgGenImage get kmm => const SvgGenImage('assets/images/icons/kmm.svg');
+
+  /// File path: assets/images/icons/paint.svg
+  SvgGenImage get paint => const SvgGenImage('assets/images/icons/paint.svg');
+
+  /// List of all assets
+  List<SvgGenImage> get values => [dartTest, fuchsia, kmm, paint];
+}
+
+class Assets {
+  Assets._();
+
+  static const String changelog = 'CHANGELOG.md';
+  static const $AssetsFlareGen flare = $AssetsFlareGen();
+  static const $AssetsImagesGen images = $AssetsImagesGen();
+  static const $AssetsJsonGen json = $AssetsJsonGen();
+  static const $AssetsMovieGen movie = $AssetsMovieGen();
+  static const $AssetsUnknownGen unknown = $AssetsUnknownGen();
+  static const $PicturesGen pictures = $PicturesGen();
+
+  /// List of all assets
+  static List<String> get values => [changelog];
+}
+
+class AssetGenImage {
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
+
+  final String _assetName;
+
+  final Size? size;
+  final Set<String> flavors;
+
+  Image image({
+    Key? key,
+    AssetBundle? bundle,
+    ImageFrameBuilder? frameBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    String? semanticLabel,
+    bool excludeFromSemantics = false,
+    double? scale,
+    double? width,
+    double? height,
+    Color? color,
+    Animation<double>? opacity,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    AlignmentGeometry alignment = Alignment.center,
+    ImageRepeat repeat = ImageRepeat.noRepeat,
+    Rect? centerSlice,
+    bool matchTextDirection = false,
+    bool gaplessPlayback = false,
+    bool isAntiAlias = false,
+    String? package,
+    FilterQuality filterQuality = FilterQuality.low,
+    int? cacheWidth,
+    int? cacheHeight,
+  }) {
+    return Image.asset(
+      _assetName,
+      key: key,
+      bundle: bundle,
+      frameBuilder: frameBuilder,
+      errorBuilder: errorBuilder,
+      semanticLabel: semanticLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      scale: scale,
+      width: width,
+      height: height,
+      color: color,
+      opacity: opacity,
+      colorBlendMode: colorBlendMode,
+      fit: fit,
+      alignment: alignment,
+      repeat: repeat,
+      centerSlice: centerSlice,
+      matchTextDirection: matchTextDirection,
+      gaplessPlayback: gaplessPlayback,
+      isAntiAlias: isAntiAlias,
+      package: package,
+      filterQuality: filterQuality,
+      cacheWidth: cacheWidth,
+      cacheHeight: cacheHeight,
+    );
+  }
+
+  ImageProvider provider({
+    AssetBundle? bundle,
+    String? package,
+  }) {
+    return AssetImage(
+      _assetName,
+      bundle: bundle,
+      package: package,
+    );
+  }
+
+  String get path => _assetName;
+
+  String get keyName => _assetName;
+}
+
+class SvgGenImage {
+  const SvgGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  }) : _isVecFormat = false;
+
+  const SvgGenImage.vec(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  }) : _isVecFormat = true;
+
+  final String _assetName;
+  final Size? size;
+  final Set<String> flavors;
+  final bool _isVecFormat;
+
+  SvgPicture svg({
+    Key? key,
+    bool matchTextDirection = false,
+    AssetBundle? bundle,
+    String? package,
+    double? width,
+    double? height,
+    BoxFit fit = BoxFit.contain,
+    AlignmentGeometry alignment = Alignment.center,
+    bool allowDrawingOutsideViewBox = false,
+    WidgetBuilder? placeholderBuilder,
+    String? semanticsLabel,
+    bool excludeFromSemantics = false,
+    SvgTheme? theme,
+    ColorFilter? colorFilter,
+    Clip clipBehavior = Clip.hardEdge,
+    @deprecated Color? color,
+    @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
+    @deprecated bool cacheColorFilter = false,
+  }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
+    return SvgPicture(
+      loader,
+      key: key,
+      matchTextDirection: matchTextDirection,
+      width: width,
+      height: height,
+      fit: fit,
+      alignment: alignment,
+      allowDrawingOutsideViewBox: allowDrawingOutsideViewBox,
+      placeholderBuilder: placeholderBuilder,
+      semanticsLabel: semanticsLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      colorFilter: colorFilter ??
+          (color == null ? null : ColorFilter.mode(color, colorBlendMode)),
+      clipBehavior: clipBehavior,
+      cacheColorFilter: cacheColorFilter,
+    );
+  }
+
+  String get path => _assetName;
+
+  String get keyName => _assetName;
+}
+
+class FlareGenImage {
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
+
+  final String _assetName;
+  final Set<String> flavors;
+
+  FlareActor flare({
+    String? boundsNode,
+    String? animation,
+    BoxFit fit = BoxFit.contain,
+    Alignment alignment = Alignment.center,
+    bool isPaused = false,
+    bool snapToEnd = false,
+    FlareController? controller,
+    FlareCompletedCallback? callback,
+    Color? color,
+    bool shouldClip = true,
+    bool sizeFromArtboard = false,
+    String? artboard,
+    bool antialias = true,
+  }) {
+    return FlareActor(
+      _assetName,
+      boundsNode: boundsNode,
+      animation: animation,
+      fit: fit,
+      alignment: alignment,
+      isPaused: isPaused,
+      snapToEnd: snapToEnd,
+      controller: controller,
+      callback: callback,
+      color: color,
+      shouldClip: shouldClip,
+      sizeFromArtboard: sizeFromArtboard,
+      artboard: artboard,
+      antialias: antialias,
+    );
+  }
+
+  String get path => _assetName;
+
+  String get keyName => _assetName;
+}
diff --git a/packages/core/test_resources/actual_data/assets_lottie_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_lottie_integrations.gen.dart
index abde7ee96..8db51bf65 100644
--- a/packages/core/test_resources/actual_data/assets_lottie_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_lottie_integrations.gen.dart
@@ -28,9 +28,13 @@ class Assets {
 }
 
 class LottieGenImage {
-  const LottieGenImage(this._assetName);
+  const LottieGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   LottieBuilder lottie({
     Animation<double>? controller,
diff --git a/packages/core/test_resources/actual_data/assets_no_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_no_integrations.gen.dart
index 722ecdc7c..8774a22cb 100644
--- a/packages/core/test_resources/actual_data/assets_no_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_no_integrations.gen.dart
@@ -116,11 +116,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
diff --git a/packages/core/test_resources/actual_data/assets_package_exclude_files.gen.dart b/packages/core/test_resources/actual_data/assets_package_exclude_files.gen.dart
index d60634822..e67908c7e 100644
--- a/packages/core/test_resources/actual_data/assets_package_exclude_files.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_package_exclude_files.gen.dart
@@ -71,11 +71,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
diff --git a/packages/core/test_resources/actual_data/assets_package_parameter.gen.dart b/packages/core/test_resources/actual_data/assets_package_parameter.gen.dart
index 99ae52686..21f1b1a9b 100644
--- a/packages/core/test_resources/actual_data/assets_package_parameter.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_package_parameter.gen.dart
@@ -69,13 +69,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   static const String package = 'test';
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -151,21 +156,23 @@ class AssetGenImage {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
-  static const String package = 'test';
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
+  static const String package = 'test';
+
   SvgPicture svg({
     Key? key,
     bool matchTextDirection = false,
@@ -187,12 +194,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
diff --git a/packages/core/test_resources/actual_data/assets_parse_metadata.gen.dart b/packages/core/test_resources/actual_data/assets_parse_metadata.gen.dart
index 8a343ff4b..ef4968182 100644
--- a/packages/core/test_resources/actual_data/assets_parse_metadata.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_parse_metadata.gen.dart
@@ -169,11 +169,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
@@ -247,17 +252,19 @@ class AssetGenImage {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
   SvgPicture svg({
@@ -280,12 +287,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
@@ -309,9 +327,13 @@ class SvgGenImage {
 }
 
 class FlareGenImage {
-  const FlareGenImage(this._assetName);
+  const FlareGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   FlareActor flare({
     String? boundsNode,
diff --git a/packages/core/test_resources/actual_data/assets_rive_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_rive_integrations.gen.dart
index 54841081b..d296b1689 100644
--- a/packages/core/test_resources/actual_data/assets_rive_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_rive_integrations.gen.dart
@@ -27,9 +27,13 @@ class Assets {
 }
 
 class RiveGenImage {
-  const RiveGenImage(this._assetName);
+  const RiveGenImage(
+    this._assetName, {
+    this.flavors = const {},
+  });
 
   final String _assetName;
+  final Set<String> flavors;
 
   RiveAnimation rive({
     String? artboard,
diff --git a/packages/core/test_resources/actual_data/assets_snake_case.gen.dart b/packages/core/test_resources/actual_data/assets_snake_case.gen.dart
index 07baa9ccc..31d813ae0 100644
--- a/packages/core/test_resources/actual_data/assets_snake_case.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_snake_case.gen.dart
@@ -83,11 +83,16 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size = null});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+  });
 
   final String _assetName;
 
   final Size? size;
+  final Set<String> flavors;
 
   Image image({
     Key? key,
diff --git a/packages/core/test_resources/actual_data/assets_svg_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_svg_integrations.gen.dart
index 4d9b32b11..8eedabddb 100644
--- a/packages/core/test_resources/actual_data/assets_svg_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_svg_integrations.gen.dart
@@ -43,17 +43,19 @@ class Assets {
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = false;
 
   const SvgGenImage.vec(
     this._assetName, {
-    this.size = null,
+    this.size,
+    this.flavors = const {},
   }) : _isVecFormat = true;
 
   final String _assetName;
-
   final Size? size;
+  final Set<String> flavors;
   final bool _isVecFormat;
 
   SvgPicture svg({
@@ -76,12 +78,23 @@ class SvgGenImage {
     @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
     @deprecated bool cacheColorFilter = false,
   }) {
+    final BytesLoader loader;
+    if (_isVecFormat) {
+      loader = AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
     return SvgPicture(
-      _isVecFormat
-          ? AssetBytesLoader(_assetName,
-              assetBundle: bundle, packageName: package)
-          : SvgAssetLoader(_assetName,
-              assetBundle: bundle, packageName: package, theme: theme),
+      loader,
       key: key,
       matchTextDirection: matchTextDirection,
       width: width,
diff --git a/packages/core/test_resources/pubspec_assets_flavored.yaml b/packages/core/test_resources/pubspec_assets_flavored.yaml
new file mode 100644
index 000000000..aa185e4a0
--- /dev/null
+++ b/packages/core/test_resources/pubspec_assets_flavored.yaml
@@ -0,0 +1,28 @@
+name: test
+
+flutter_gen:
+  output: lib/gen/ # Optional (default: lib/gen/)
+  line_length: 80 # Optional (default: 80)
+
+  integrations:
+    flutter_svg: true
+    flare_flutter: true
+
+flutter:
+  assets:
+    - assets/images
+    - assets/images/chip3/chip3.jpg
+    - assets/images/chip3/chip3.jpg # duplicated
+    - assets/images/icons/fuchsia.svg
+    - assets/images/icons/kmm.svg
+    - assets/images/icons/paint.svg
+    - assets/images/icons/dart@test.svg
+    - assets/json/
+    - pictures/chip5.jpg
+    - assets/flare/
+    - assets/movie/
+    - assets/unknown/unknown_mime_type.bk
+    - CHANGELOG.md
+    - path: assets/images/chip4/
+      flavors:
+        - test
diff --git a/packages/core/test_resources/pubspec_assets_flavored_duplicate_entry.yaml b/packages/core/test_resources/pubspec_assets_flavored_duplicate_entry.yaml
new file mode 100644
index 000000000..53a4af6e9
--- /dev/null
+++ b/packages/core/test_resources/pubspec_assets_flavored_duplicate_entry.yaml
@@ -0,0 +1,31 @@
+name: test
+
+flutter_gen:
+  output: lib/gen/ # Optional (default: lib/gen/)
+  line_length: 80 # Optional (default: 80)
+
+  integrations:
+    flutter_svg: true
+    flare_flutter: true
+
+flutter:
+  assets:
+    - assets/images
+    - assets/images/chip3/chip3.jpg
+    - assets/images/chip3/chip3.jpg # duplicated
+    - assets/images/icons/fuchsia.svg
+    - assets/images/icons/kmm.svg
+    - assets/images/icons/paint.svg
+    - assets/images/icons/dart@test.svg
+    - assets/json/
+    - pictures/chip5.jpg
+    - assets/flare/
+    - assets/movie/
+    - assets/unknown/unknown_mime_type.bk
+    - CHANGELOG.md
+    - path: assets/images/chip4/
+      flavors:
+        - test
+    - path: assets/images/chip4/
+      flavors:
+        - another_test