Unverified Commit bafe7cbb authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Watch wildcard directories in addition to asset bundle (#29883)

parent 141f87b3
......@@ -63,6 +63,10 @@ class _ManifestAssetBundle implements AssetBundle {
@override
final Map<String, DevFSContent> entries = <String, DevFSContent>{};
// If an asset corresponds to a wildcard directory, then it may have been
// updated without changes to the manifest.
final Map<Uri, Directory> _wildcardDirectories = <Uri, Directory>{};
DateTime _lastBuildTimestamp;
static const String defaultManifestPath = 'pubspec.yaml';
......@@ -83,6 +87,12 @@ class _ManifestAssetBundle implements AssetBundle {
if (stat.type == FileSystemEntityType.notFound)
return true;
for (Directory directory in _wildcardDirectories.values) {
if (directory.statSync().modified.isAfter(_lastBuildTimestamp)) {
return true;
}
}
return stat.modified.isAfter(_lastBuildTimestamp);
}
......@@ -119,6 +129,7 @@ class _ManifestAssetBundle implements AssetBundle {
final String assetBasePath = fs.path.dirname(fs.path.absolute(manifestPath));
final PackageMap packageMap = PackageMap(packagesPath);
final List<Uri> wildcardDirectories = <Uri>[];
// The _assetVariants map contains an entry for each asset listed
// in the pubspec.yaml file's assets and font and sections. The
......@@ -127,12 +138,14 @@ class _ManifestAssetBundle implements AssetBundle {
final Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
packageMap,
flutterManifest,
wildcardDirectories,
assetBasePath,
excludeDirs: <String>[assetDirPath, getBuildDirectory()],
);
if (assetVariants == null)
if (assetVariants == null) {
return 1;
}
final List<Map<String, dynamic>> fonts = _parseFonts(
flutterManifest,
......@@ -156,6 +169,7 @@ class _ManifestAssetBundle implements AssetBundle {
final Map<_Asset, List<_Asset>> packageAssets = _parseAssets(
packageMap,
packageFlutterManifest,
wildcardDirectories,
packageBasePath,
packageName: packageName,
);
......@@ -206,6 +220,11 @@ class _ManifestAssetBundle implements AssetBundle {
entries[asset.entryUri.path] ??= DevFSFileContent(asset.assetFile);
}
// Update wildcard directories we we can detect changes in them.
for (Uri uri in wildcardDirectories) {
_wildcardDirectories[uri] ??= fs.directory(uri);
}
entries[_assetManifestJson] = _createAssetManifest(assetVariants);
entries[_fontManifestJson] = DevFSStringContent(json.encode(fonts));
......@@ -524,6 +543,7 @@ class _AssetDirectoryCache {
Map<_Asset, List<_Asset>> _parseAssets(
PackageMap packageMap,
FlutterManifest flutterManifest,
List<Uri> wildcardDirectories,
String assetBase, {
List<String> excludeDirs = const <String>[],
String packageName,
......@@ -533,6 +553,7 @@ Map<_Asset, List<_Asset>> _parseAssets(
final _AssetDirectoryCache cache = _AssetDirectoryCache(excludeDirs);
for (Uri assetUri in flutterManifest.assets) {
if (assetUri.toString().endsWith('/')) {
wildcardDirectories.add(assetUri);
_parseAssetsFromFolder(packageMap, flutterManifest, assetBase,
cache, result, assetUri,
excludeDirs: excludeDirs, packageName: packageName);
......
......@@ -56,6 +56,46 @@ void main() {
}, overrides: <Type, Generator>{
FileSystem: () => testFileSystem,
});
testUsingContext('wildcard directories are updated when filesystem changes', () async {
fs.file('.packages').createSync();
fs.file(fs.path.join('assets', 'foo', 'bar.txt')).createSync(recursive: true);
fs.file('pubspec.yaml')
..createSync()
..writeAsStringSync(r'''
name: example
flutter:
assets:
- assets/foo/
''');
final AssetBundle bundle = AssetBundleFactory.instance.createBundle();
await bundle.build(manifestPath: 'pubspec.yaml');
// Expected assets:
// - asset manifest
// - font manifest
// - license file
// - assets/foo/bar.txt
expect(bundle.entries.length, 4);
expect(bundle.needsBuild(manifestPath: 'pubspec.yaml'), false);
// Adding a file should update the stat of the directory, but instead
// we need to fully recreate it.
fs.directory(fs.path.join('assets', 'foo')).deleteSync(recursive: true);
fs.file(fs.path.join('assets', 'foo', 'fizz.txt')).createSync(recursive: true);
fs.file(fs.path.join('assets', 'foo', 'bar.txt')).createSync();
expect(bundle.needsBuild(manifestPath: 'pubspec.yaml'), true);
await bundle.build(manifestPath: 'pubspec.yaml');
// Expected assets:
// - asset manifest
// - font manifest
// - license file
// - assets/foo/bar.txt
// - assets/foo/fizz.txt
expect(bundle.entries.length, 5);
}, overrides: <Type, Generator>{
FileSystem: () => testFileSystem,
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment