mirror of
https://github.com/flutter/flutter
synced 2024-08-25 11:07:06 +00:00
make hot reload reflect changes to asset transformer configurations (#144660)
In service of https://github.com/flutter/flutter/issues/143348 This PR makes hot reloads reflect changes to transformer configurations under the `assets` section in pubspec.yaml. This PR is optimized for ease of implementation, and should not be merged as-is. If it is merged as-is, seriously consider creating a tech debt issue and assigning it to someone to make sure it gets resolved.
This commit is contained in:
parent
a5cf4191dc
commit
cd785544fa
|
@ -14,6 +14,7 @@ import 'base/deferred_component.dart';
|
||||||
import 'base/file_system.dart';
|
import 'base/file_system.dart';
|
||||||
import 'base/logger.dart';
|
import 'base/logger.dart';
|
||||||
import 'base/platform.dart';
|
import 'base/platform.dart';
|
||||||
|
import 'base/utils.dart';
|
||||||
import 'build_info.dart';
|
import 'build_info.dart';
|
||||||
import 'cache.dart';
|
import 'cache.dart';
|
||||||
import 'convert.dart';
|
import 'convert.dart';
|
||||||
|
@ -84,9 +85,8 @@ enum AssetKind {
|
||||||
|
|
||||||
/// Contains all information about an asset needed by tool the to prepare and
|
/// Contains all information about an asset needed by tool the to prepare and
|
||||||
/// copy an asset file to the build output.
|
/// copy an asset file to the build output.
|
||||||
@immutable
|
|
||||||
final class AssetBundleEntry {
|
final class AssetBundleEntry {
|
||||||
const AssetBundleEntry(this.content, {
|
AssetBundleEntry(this.content, {
|
||||||
required this.kind,
|
required this.kind,
|
||||||
required this.transformers,
|
required this.transformers,
|
||||||
});
|
});
|
||||||
|
@ -96,6 +96,10 @@ final class AssetBundleEntry {
|
||||||
final List<AssetTransformerEntry> transformers;
|
final List<AssetTransformerEntry> transformers;
|
||||||
|
|
||||||
Future<List<int>> contentsAsBytes() => content.contentsAsBytes();
|
Future<List<int>> contentsAsBytes() => content.contentsAsBytes();
|
||||||
|
|
||||||
|
bool hasEquivalentConfigurationWith(AssetBundleEntry other) {
|
||||||
|
return listEquals(transformers, other.transformers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AssetBundle {
|
abstract class AssetBundle {
|
||||||
|
@ -425,11 +429,11 @@ class ManifestAssetBundle implements AssetBundle {
|
||||||
final File variantFile = variant.lookupAssetFile(_fileSystem);
|
final File variantFile = variant.lookupAssetFile(_fileSystem);
|
||||||
inputFiles.add(variantFile);
|
inputFiles.add(variantFile);
|
||||||
assert(variantFile.existsSync());
|
assert(variantFile.existsSync());
|
||||||
entries[variant.entryUri.path] ??= AssetBundleEntry(
|
_setIfConfigurationChanged(entries, variant.entryUri.path, AssetBundleEntry(
|
||||||
DevFSFileContent(variantFile),
|
DevFSFileContent(variantFile),
|
||||||
kind: variant.kind,
|
kind: variant.kind,
|
||||||
transformers: variant.transformers,
|
transformers: variant.transformers,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Save the contents of each deferred component image, image variant, and font
|
// Save the contents of each deferred component image, image variant, and font
|
||||||
|
@ -459,11 +463,11 @@ class ManifestAssetBundle implements AssetBundle {
|
||||||
for (final _Asset variant in assetsMap[asset]!) {
|
for (final _Asset variant in assetsMap[asset]!) {
|
||||||
final File variantFile = variant.lookupAssetFile(_fileSystem);
|
final File variantFile = variant.lookupAssetFile(_fileSystem);
|
||||||
assert(variantFile.existsSync());
|
assert(variantFile.existsSync());
|
||||||
deferredComponentsEntries[componentName]![variant.entryUri.path] ??= AssetBundleEntry(
|
_setIfConfigurationChanged(deferredComponentsEntries[componentName]!, variant.entryUri.path, AssetBundleEntry(
|
||||||
DevFSFileContent(variantFile),
|
DevFSFileContent(variantFile),
|
||||||
kind: AssetKind.regular,
|
kind: AssetKind.regular,
|
||||||
transformers: variant.transformers,
|
transformers: variant.transformers,
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,6 +567,13 @@ class ManifestAssetBundle implements AssetBundle {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setIfConfigurationChanged(Map<String, AssetBundleEntry> entryMap, String key, AssetBundleEntry entry,) {
|
||||||
|
final AssetBundleEntry? existingEntry = entryMap[key];
|
||||||
|
if (existingEntry == null || !entry.hasEquivalentConfigurationWith(existingEntry)) {
|
||||||
|
entryMap[key] = entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _setLicenseIfChanged(
|
void _setLicenseIfChanged(
|
||||||
String combinedLicenses,
|
String combinedLicenses,
|
||||||
TargetPlatform? targetPlatform,
|
TargetPlatform? targetPlatform,
|
||||||
|
|
|
@ -428,6 +428,73 @@ flutter:
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWithoutContext("AssetBundleEntry::content::isModified is true when an asset's transformers change in between builds", () async {
|
||||||
|
final FileSystem fileSystem = MemoryFileSystem.test();
|
||||||
|
|
||||||
|
fileSystem.file('my-asset.txt').createSync();
|
||||||
|
|
||||||
|
final BufferLogger logger = BufferLogger.test();
|
||||||
|
final FakePlatform platform = FakePlatform();
|
||||||
|
fileSystem.file('.packages').createSync();
|
||||||
|
fileSystem.file('pubspec.yaml')
|
||||||
|
..createSync()
|
||||||
|
..writeAsStringSync(r'''
|
||||||
|
name: example
|
||||||
|
flutter:
|
||||||
|
assets:
|
||||||
|
- path: my-asset.txt
|
||||||
|
transformers:
|
||||||
|
- package: my-transformer-one
|
||||||
|
''');
|
||||||
|
final ManifestAssetBundle bundle = ManifestAssetBundle(
|
||||||
|
logger: logger,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
platform: platform,
|
||||||
|
flutterRoot: Cache.defaultFlutterRoot(
|
||||||
|
platform: platform,
|
||||||
|
fileSystem: fileSystem,
|
||||||
|
userMessages: UserMessages(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await bundle.build(
|
||||||
|
packagesPath: '.packages',
|
||||||
|
flutterProject: FlutterProject.fromDirectoryTest(
|
||||||
|
fileSystem.currentDirectory,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(bundle.entries['my-asset.txt']!.content.isModified, isTrue);
|
||||||
|
|
||||||
|
await bundle.build(
|
||||||
|
packagesPath: '.packages',
|
||||||
|
flutterProject: FlutterProject.fromDirectoryTest(
|
||||||
|
fileSystem.currentDirectory,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(bundle.entries['my-asset.txt']!.content.isModified, isFalse);
|
||||||
|
|
||||||
|
fileSystem.file('pubspec.yaml').writeAsStringSync(r'''
|
||||||
|
name: example
|
||||||
|
flutter:
|
||||||
|
assets:
|
||||||
|
- path: my-asset.txt
|
||||||
|
transformers:
|
||||||
|
- package: my-transformer-one
|
||||||
|
- package: my-transformer-two
|
||||||
|
''');
|
||||||
|
|
||||||
|
await bundle.build(
|
||||||
|
packagesPath: '.packages',
|
||||||
|
flutterProject: FlutterProject.fromDirectoryTest(
|
||||||
|
fileSystem.currentDirectory,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(bundle.entries['my-asset.txt']!.content.isModified, isTrue);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('AssetBundle.build (web builds)', () {
|
group('AssetBundle.build (web builds)', () {
|
||||||
|
|
Loading…
Reference in a new issue