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 { ...@@ -63,6 +63,10 @@ class _ManifestAssetBundle implements AssetBundle {
@override @override
final Map<String, DevFSContent> entries = <String, DevFSContent>{}; 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; DateTime _lastBuildTimestamp;
static const String defaultManifestPath = 'pubspec.yaml'; static const String defaultManifestPath = 'pubspec.yaml';
...@@ -83,6 +87,12 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -83,6 +87,12 @@ class _ManifestAssetBundle implements AssetBundle {
if (stat.type == FileSystemEntityType.notFound) if (stat.type == FileSystemEntityType.notFound)
return true; return true;
for (Directory directory in _wildcardDirectories.values) {
if (directory.statSync().modified.isAfter(_lastBuildTimestamp)) {
return true;
}
}
return stat.modified.isAfter(_lastBuildTimestamp); return stat.modified.isAfter(_lastBuildTimestamp);
} }
...@@ -119,6 +129,7 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -119,6 +129,7 @@ class _ManifestAssetBundle implements AssetBundle {
final String assetBasePath = fs.path.dirname(fs.path.absolute(manifestPath)); final String assetBasePath = fs.path.dirname(fs.path.absolute(manifestPath));
final PackageMap packageMap = PackageMap(packagesPath); final PackageMap packageMap = PackageMap(packagesPath);
final List<Uri> wildcardDirectories = <Uri>[];
// The _assetVariants map contains an entry for each asset listed // The _assetVariants map contains an entry for each asset listed
// in the pubspec.yaml file's assets and font and sections. The // in the pubspec.yaml file's assets and font and sections. The
...@@ -127,12 +138,14 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -127,12 +138,14 @@ class _ManifestAssetBundle implements AssetBundle {
final Map<_Asset, List<_Asset>> assetVariants = _parseAssets( final Map<_Asset, List<_Asset>> assetVariants = _parseAssets(
packageMap, packageMap,
flutterManifest, flutterManifest,
wildcardDirectories,
assetBasePath, assetBasePath,
excludeDirs: <String>[assetDirPath, getBuildDirectory()], excludeDirs: <String>[assetDirPath, getBuildDirectory()],
); );
if (assetVariants == null) if (assetVariants == null) {
return 1; return 1;
}
final List<Map<String, dynamic>> fonts = _parseFonts( final List<Map<String, dynamic>> fonts = _parseFonts(
flutterManifest, flutterManifest,
...@@ -156,6 +169,7 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -156,6 +169,7 @@ class _ManifestAssetBundle implements AssetBundle {
final Map<_Asset, List<_Asset>> packageAssets = _parseAssets( final Map<_Asset, List<_Asset>> packageAssets = _parseAssets(
packageMap, packageMap,
packageFlutterManifest, packageFlutterManifest,
wildcardDirectories,
packageBasePath, packageBasePath,
packageName: packageName, packageName: packageName,
); );
...@@ -206,6 +220,11 @@ class _ManifestAssetBundle implements AssetBundle { ...@@ -206,6 +220,11 @@ class _ManifestAssetBundle implements AssetBundle {
entries[asset.entryUri.path] ??= DevFSFileContent(asset.assetFile); 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[_assetManifestJson] = _createAssetManifest(assetVariants);
entries[_fontManifestJson] = DevFSStringContent(json.encode(fonts)); entries[_fontManifestJson] = DevFSStringContent(json.encode(fonts));
...@@ -524,6 +543,7 @@ class _AssetDirectoryCache { ...@@ -524,6 +543,7 @@ class _AssetDirectoryCache {
Map<_Asset, List<_Asset>> _parseAssets( Map<_Asset, List<_Asset>> _parseAssets(
PackageMap packageMap, PackageMap packageMap,
FlutterManifest flutterManifest, FlutterManifest flutterManifest,
List<Uri> wildcardDirectories,
String assetBase, { String assetBase, {
List<String> excludeDirs = const <String>[], List<String> excludeDirs = const <String>[],
String packageName, String packageName,
...@@ -533,6 +553,7 @@ Map<_Asset, List<_Asset>> _parseAssets( ...@@ -533,6 +553,7 @@ Map<_Asset, List<_Asset>> _parseAssets(
final _AssetDirectoryCache cache = _AssetDirectoryCache(excludeDirs); final _AssetDirectoryCache cache = _AssetDirectoryCache(excludeDirs);
for (Uri assetUri in flutterManifest.assets) { for (Uri assetUri in flutterManifest.assets) {
if (assetUri.toString().endsWith('/')) { if (assetUri.toString().endsWith('/')) {
wildcardDirectories.add(assetUri);
_parseAssetsFromFolder(packageMap, flutterManifest, assetBase, _parseAssetsFromFolder(packageMap, flutterManifest, assetBase,
cache, result, assetUri, cache, result, assetUri,
excludeDirs: excludeDirs, packageName: packageName); excludeDirs: excludeDirs, packageName: packageName);
......
...@@ -56,6 +56,46 @@ void main() { ...@@ -56,6 +56,46 @@ void main() {
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => testFileSystem, 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