add whole directories as assets
If I want to add multiple files of the same type in the same directory I have to add a lot of lines, often repeating the name of a file in different writing for the annotation, for the variable name and for the generated name. It would be nice to be able to point to a directory and include all files as assets.
For example just those 2 lines for a containing directory instead of 10 lines for 5 files (TextAssets instead of TextAsset):
@Asset('$assetsPrefix/shaders')
const shaders = TextAssets(text: _shaders$content, dirname: _shaders$dirname);
Or maybe a different annotation like Assets or AssetDir. I'd also add dirname or maybe also filename just for consistency with my other issue.
I'm not yet sure what the TextAssets class would look like. A map with all files and the name as key would probably the easiest way but also errorprone. Maybe a generated enum instead of string.
For example (code may not be valid as I just wrote it here just now):
// in assets.dart
@Asset('$assetsPrefix/shaders')
const shaders = TextAssets<ShaderEnum>(files: _shaders$content, dirname: _shaders$dirname);
// or
@Asset('$assetsPrefix/shaders')
const shaders = DirAsset<TextAsset, ShaderEnum>(files: _shaders$content, dirname: _shaders$dirname);
// or, including optional filepatterns from the start
@AssetDir('$assetsPrefix/shaders', filePattern: r'.*\.(vert|frag)')
const shaders = DirAsset<TextAsset, ShaderEnum>(files: _shaders$content, dirname: _shaders$dirname);
// in assets.g.dart
_shaders$content = {
ShaderEnum.vertBrackgroundShader: TextAsset(text: r'''filecontent''', filename: r'backgroundShader.vert'),
ShaderEnum.fragBrackgroundShader: TextAsset(text: r'''filecontent''', filename: r'backgroundShader.frag'),
};
enum ShaderEnum {
vertBackgroundShader, fragBackgroundShader
}
// in shaders directory
backgroundShader.vert
backgroundSahder.frag
// on use
final content = shaders[ShaderEnum.verBackgroundShader].text;
// what DirAsset could look like, FileAsset would be a new interface for the other Asset-classes
class DirAsset<S extends FileAsset, T> {
final Map<T, S> _files;
final String dirName;
DirAsset({Map<T, S> files, this.dirName}) : _files = files;
S operator[](T assetKey) => _files[assetKey];
}
The filename to enum translation will need some cleanup as not every char in a filename is allowed as a identifier (or just report an error if a filename cannot be converted).
More advanced features like file filters or inclusion of subfolders may also be worth considering, but it's not something I would need.
What do you think?
EDIT: Had the idea of a general DirAsset instead of plural forms of all other assets-classes and added it in the example code
I like this idea, but it wouldn't work, as the build system Dart uses has no way at the moment of running file globs like this.
We could do something where you can specify multiple files per value and some regex to convert the file names into map keys, that way long file lists are at least more concise than writing out individual asset assignments.
I'm not sure, but shouldn't it be possible to use BuildStep#findAssets?
Or, but this would be an extreme change and completely change the way aspen works, use a MergingBuilder and instead of using annotations define all options/globs/everything in the build.yaml and just generate the complete assets.dart or whatever a user want's to call it.