Skip to content

[native_assets_cli] Helper to add all files in a directory as DataAssetsย #1346

Closed
@dcharkes

Description

@dcharkes

Adding all files in a directory as data assets seems to be a common use case.

In Flutter, all files in a directory can be added as assets easily:

https://docs.flutter.dev/ui/assets/assets-and-images#specifying-assets

flutter:
  assets:
    - directory/
    - directory/subdirectory/

Using these assets in Flutter is via the full file path:

https://docs.flutter.dev/ui/assets/assets-and-images#loading-text-assets

await rootBundle.loadString('assets/config.json')

We should be able to support this type of use case:

void main(List<String> args) async {
  await build(args, (config, output) async {
    await output.addDataAssetsDirectory('directory/', config);
    await output.addDataAssetsDirectory('directory/subdirectory/', config);
  });
}

Implementation sketch:

extension on BuildOutput {
  /// Adds all the files in [directory] as [DataAsset]s to this [BuildOutput].
  ///
  /// The [directory] must end with a slash and be relative to
  /// [BuildConfig.packageRoot].
  Future<void> addDataAssetsDirectory(
    String directory, {
    required BuildConfig config,
    String? linkInPackage,
  }) async {
    final packageName = config.packageName;
    final packageRoot = config.packageRoot;
    final assetDirectory = Directory.fromUri(packageRoot.resolve('assets/'));
    addDependency(assetDirectory.uri);

    await for (final assetFile in assetDirectory.list()) {
      if (assetFile is! File) {
        continue;
      }
      final assetUri = assetFile.uri;

      // The file path relative to the package root, with forward slashes.
      final name = assetUri
          .toFilePath(windows: false)
          .substring(packageRoot.toFilePath(windows: false).length);

      addAsset(
        DataAsset(
          package: packageName,
          name: name,
          file: assetUri,
        ),
        linkInPackage: linkInPackage,
      );
      addDependency(assetUri);
    }
  }
}

With such an implementation we'd also establish a convention that the a data asset in assets/foo.json will be available at runtime as package:my_package/assets/foo.json which aligns with the Flutter assets approach of making assets available via their full path.

Inspired by #1345 (comment).

Open to alternative suggestions, WDYT @mosuem?

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2A bug or feature request we're likely to work onpackage:hooks

    Type

    No type

    Projects

    Status

    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions