Support transitive asset dependency (#12032)
This commit is contained in:
parent
a1f03977ca
commit
0b95e9c278
@ -137,7 +137,7 @@ class AssetBundle {
|
|||||||
packageMap,
|
packageMap,
|
||||||
packageManifestDescriptor['flutter'],
|
packageManifestDescriptor['flutter'],
|
||||||
packageBasePath,
|
packageBasePath,
|
||||||
packageKey: packageName,
|
packageName: packageName,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,7 +434,7 @@ Map<_Asset, List<_Asset>> _parseAssets(
|
|||||||
Map<String, dynamic> manifestDescriptor,
|
Map<String, dynamic> manifestDescriptor,
|
||||||
String assetBase, {
|
String assetBase, {
|
||||||
List<String> excludeDirs: const <String>[],
|
List<String> excludeDirs: const <String>[],
|
||||||
String packageKey
|
String packageName
|
||||||
}) {
|
}) {
|
||||||
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
|
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
|
||||||
|
|
||||||
@ -444,11 +444,13 @@ Map<_Asset, List<_Asset>> _parseAssets(
|
|||||||
if (manifestDescriptor.containsKey('assets')) {
|
if (manifestDescriptor.containsKey('assets')) {
|
||||||
final _AssetDirectoryCache cache = new _AssetDirectoryCache(excludeDirs);
|
final _AssetDirectoryCache cache = new _AssetDirectoryCache(excludeDirs);
|
||||||
for (String assetName in manifestDescriptor['assets']) {
|
for (String assetName in manifestDescriptor['assets']) {
|
||||||
final _Asset asset = packageKey != null
|
final _Asset asset = _resolveAsset(
|
||||||
? _resolvePackageAsset(assetBase, packageKey, assetName)
|
packageMap,
|
||||||
: _resolveAsset(packageMap, assetBase, assetName);
|
assetBase,
|
||||||
|
assetName,
|
||||||
|
packageName,
|
||||||
|
);
|
||||||
final List<_Asset> variants = <_Asset>[];
|
final List<_Asset> variants = <_Asset>[];
|
||||||
|
|
||||||
for (String path in cache.variantsFor(asset.assetFile.path)) {
|
for (String path in cache.variantsFor(asset.assetFile.path)) {
|
||||||
final String key = fs.path.relative(path, from: asset.base);
|
final String key = fs.path.relative(path, from: asset.base);
|
||||||
String assetEntry;
|
String assetEntry;
|
||||||
@ -473,7 +475,12 @@ Map<_Asset, List<_Asset>> _parseAssets(
|
|||||||
if (asset == null)
|
if (asset == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
final _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
|
final _Asset baseAsset = _resolveAsset(
|
||||||
|
packageMap,
|
||||||
|
assetBase,
|
||||||
|
asset,
|
||||||
|
packageName
|
||||||
|
);
|
||||||
if (!baseAsset.assetFileExists) {
|
if (!baseAsset.assetFileExists) {
|
||||||
printError('Error: unable to locate asset entry in pubspec.yaml: "$asset".');
|
printError('Error: unable to locate asset entry in pubspec.yaml: "$asset".');
|
||||||
return null;
|
return null;
|
||||||
@ -487,42 +494,46 @@ Map<_Asset, List<_Asset>> _parseAssets(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Asset _resolvePackageAsset(
|
|
||||||
String assetBase,
|
|
||||||
String packageName,
|
|
||||||
String asset,
|
|
||||||
) {
|
|
||||||
return new _Asset(
|
|
||||||
base: assetBase,
|
|
||||||
assetEntry: 'packages/$packageName/$asset',
|
|
||||||
relativePath: asset,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_Asset _resolveAsset(
|
_Asset _resolveAsset(
|
||||||
PackageMap packageMap,
|
PackageMap packageMap,
|
||||||
String assetBase,
|
String assetBase,
|
||||||
String asset,
|
String asset,
|
||||||
|
String packageName,
|
||||||
) {
|
) {
|
||||||
if (asset.startsWith('packages/') && !fs.isFileSync(fs.path.join(assetBase, asset))) {
|
if (asset.startsWith('packages/') && !fs.isFileSync(fs.path.join(assetBase, asset))) {
|
||||||
// Convert packages/flutter_gallery_assets/clouds-0.png to clouds-0.png.
|
// The asset is referenced in the pubspec.yaml as
|
||||||
String packageKey = asset.substring(9);
|
// 'packages/PACKAGE_NAME/PATH/TO/ASSET
|
||||||
String relativeAsset = asset;
|
final _Asset packageAsset = _resolvePackageAsset(asset, packageMap);
|
||||||
|
if (packageAsset != null)
|
||||||
final int index = packageKey.indexOf('/');
|
return packageAsset;
|
||||||
if (index != -1) {
|
|
||||||
relativeAsset = packageKey.substring(index + 1);
|
|
||||||
packageKey = packageKey.substring(0, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Uri uri = packageMap.map[packageKey];
|
|
||||||
if (uri != null && uri.scheme == 'file') {
|
|
||||||
final File file = fs.file(uri);
|
|
||||||
return new _Asset(base: file.path, assetEntry: asset, relativePath: relativeAsset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new _Asset(base: assetBase, relativePath: asset);
|
final String assetEntry = packageName != null
|
||||||
|
? 'packages/$packageName/$asset' // Asset from, and declared in $packageName
|
||||||
|
: null; // Asset from the current application
|
||||||
|
return new _Asset(base: assetBase, assetEntry: assetEntry, relativePath: asset);
|
||||||
|
}
|
||||||
|
|
||||||
|
_Asset _resolvePackageAsset(String asset, PackageMap packageMap) {
|
||||||
|
assert(asset.startsWith('packages/'));
|
||||||
|
String packageKey = asset.substring(9);
|
||||||
|
String relativeAsset = asset;
|
||||||
|
|
||||||
|
final int index = packageKey.indexOf('/');
|
||||||
|
if (index != -1) {
|
||||||
|
relativeAsset = packageKey.substring(index + 1);
|
||||||
|
packageKey = packageKey.substring(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Uri uri = packageMap.map[packageKey];
|
||||||
|
if (uri != null && uri.scheme == 'file') {
|
||||||
|
final File file = fs.file(uri);
|
||||||
|
final String base = file.path.substring(0, file.path.length - 1);
|
||||||
|
return new _Asset(base: base, assetEntry: asset, relativePath: relativeAsset);
|
||||||
|
}
|
||||||
|
printStatus('Error detected in pubspec.yaml:', emphasis: true);
|
||||||
|
printError('Could not resolve $packageKey for asset $asset.\n');
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic _loadFlutterManifest(String manifestPath) {
|
dynamic _loadFlutterManifest(String manifestPath) {
|
||||||
|
@ -133,6 +133,32 @@ $assetsSection
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => new MemoryFileSystem(),
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('One package with one asset not specified', () async {
|
||||||
|
establishFlutterRoot();
|
||||||
|
|
||||||
|
final List<String> assetEntries = <String>['packages/test_package/a/foo'];
|
||||||
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
assets: assetEntries,
|
||||||
|
);
|
||||||
|
writePackagesFile('test_package:p/p/lib/');
|
||||||
|
writePubspecFile('p/p/pubspec.yaml', 'test_package');
|
||||||
|
|
||||||
|
final List<String> assets = <String>['a/foo'];
|
||||||
|
writeAssets('p/p/lib/', assets);
|
||||||
|
|
||||||
|
final String expectedAssetManifest = '{"packages/test_package/a/foo":'
|
||||||
|
'["packages/test_package/a/foo"]}';
|
||||||
|
await buildAndVerifyAssets(
|
||||||
|
assets,
|
||||||
|
<String>['test_package'],
|
||||||
|
expectedAssetManifest,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('One package with asset variants', () async {
|
testUsingContext('One package with asset variants', () async {
|
||||||
establishFlutterRoot();
|
establishFlutterRoot();
|
||||||
@ -160,6 +186,35 @@ $assetsSection
|
|||||||
FileSystem: () => new MemoryFileSystem(),
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('One package with asset variants not specified', () async {
|
||||||
|
establishFlutterRoot();
|
||||||
|
|
||||||
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
assets: <String>['packages/test_package/a/foo'],
|
||||||
|
);
|
||||||
|
writePackagesFile('test_package:p/p/lib/');
|
||||||
|
writePubspecFile(
|
||||||
|
'p/p/pubspec.yaml',
|
||||||
|
'test_package',
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<String> assets = <String>['a/foo', 'a/v/foo'];
|
||||||
|
writeAssets('p/p/lib/', assets);
|
||||||
|
|
||||||
|
final String expectedManifest = '{"packages/test_package/a/foo":'
|
||||||
|
'["packages/test_package/a/foo","packages/test_package/a/v/foo"]}';
|
||||||
|
|
||||||
|
await buildAndVerifyAssets(
|
||||||
|
assets,
|
||||||
|
<String>['test_package'],
|
||||||
|
expectedManifest,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('One package with two assets', () async {
|
testUsingContext('One package with two assets', () async {
|
||||||
establishFlutterRoot();
|
establishFlutterRoot();
|
||||||
|
|
||||||
@ -187,10 +242,47 @@ $assetsSection
|
|||||||
FileSystem: () => new MemoryFileSystem(),
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('One package with two assets not specified', () async {
|
||||||
|
establishFlutterRoot();
|
||||||
|
|
||||||
|
final List<String> assetEntries = <String>[
|
||||||
|
'packages/test_package/a/foo',
|
||||||
|
'packages/test_package/a/bar',
|
||||||
|
];
|
||||||
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
assets: assetEntries,
|
||||||
|
);
|
||||||
|
writePackagesFile('test_package:p/p/lib/');
|
||||||
|
|
||||||
|
final List<String> assets = <String>['a/foo', 'a/bar'];
|
||||||
|
writePubspecFile(
|
||||||
|
'p/p/pubspec.yaml',
|
||||||
|
'test_package',
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAssets('p/p/lib/', assets);
|
||||||
|
final String expectedAssetManifest =
|
||||||
|
'{"packages/test_package/a/foo":["packages/test_package/a/foo"],'
|
||||||
|
'"packages/test_package/a/bar":["packages/test_package/a/bar"]}';
|
||||||
|
|
||||||
|
await buildAndVerifyAssets(
|
||||||
|
assets,
|
||||||
|
<String>['test_package'],
|
||||||
|
expectedAssetManifest,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
});
|
||||||
|
|
||||||
testUsingContext('Two packages with assets', () async {
|
testUsingContext('Two packages with assets', () async {
|
||||||
establishFlutterRoot();
|
establishFlutterRoot();
|
||||||
|
|
||||||
writePubspecFile('pubspec.yaml', 'test');
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
);
|
||||||
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
|
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
|
||||||
writePubspecFile(
|
writePubspecFile(
|
||||||
'p/p/pubspec.yaml',
|
'p/p/pubspec.yaml',
|
||||||
@ -221,5 +313,79 @@ $assetsSection
|
|||||||
}, overrides: <Type, Generator>{
|
}, overrides: <Type, Generator>{
|
||||||
FileSystem: () => new MemoryFileSystem(),
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testUsingContext('Two packages with assets not specified', () async {
|
||||||
|
establishFlutterRoot();
|
||||||
|
|
||||||
|
final List<String> assetEntries = <String>[
|
||||||
|
'packages/test_package/a/foo',
|
||||||
|
'packages/test_package2/a/foo',
|
||||||
|
];
|
||||||
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
assets: assetEntries,
|
||||||
|
);
|
||||||
|
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
|
||||||
|
writePubspecFile(
|
||||||
|
'p/p/pubspec.yaml',
|
||||||
|
'test_package',
|
||||||
|
);
|
||||||
|
writePubspecFile(
|
||||||
|
'p2/p/pubspec.yaml',
|
||||||
|
'test_package2',
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<String> assets = <String>['a/foo', 'a/v/foo'];
|
||||||
|
writeAssets('p/p/lib/', assets);
|
||||||
|
writeAssets('p2/p/lib/', assets);
|
||||||
|
|
||||||
|
final String expectedAssetManifest =
|
||||||
|
'{"packages/test_package/a/foo":'
|
||||||
|
'["packages/test_package/a/foo","packages/test_package/a/v/foo"],'
|
||||||
|
'"packages/test_package2/a/foo":'
|
||||||
|
'["packages/test_package2/a/foo","packages/test_package2/a/v/foo"]}';
|
||||||
|
|
||||||
|
await buildAndVerifyAssets(
|
||||||
|
assets,
|
||||||
|
<String>['test_package', 'test_package2'],
|
||||||
|
expectedAssetManifest,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
});
|
||||||
|
|
||||||
|
testUsingContext('Transitive asset dependency', () async {
|
||||||
|
establishFlutterRoot();
|
||||||
|
writePubspecFile(
|
||||||
|
'pubspec.yaml',
|
||||||
|
'test',
|
||||||
|
);
|
||||||
|
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
|
||||||
|
writePubspecFile(
|
||||||
|
'p/p/pubspec.yaml',
|
||||||
|
'test_package',
|
||||||
|
assets: <String>['packages/test_package2/a/foo']
|
||||||
|
);
|
||||||
|
writePubspecFile(
|
||||||
|
'p2/p/pubspec.yaml',
|
||||||
|
'test_package2',
|
||||||
|
);
|
||||||
|
|
||||||
|
final List<String> assets = <String>['a/foo', 'a/v/foo'];
|
||||||
|
writeAssets('p2/p/lib/', assets);
|
||||||
|
|
||||||
|
final String expectedAssetManifest =
|
||||||
|
'{"packages/test_package2/a/foo":'
|
||||||
|
'["packages/test_package2/a/foo","packages/test_package2/a/v/foo"]}';
|
||||||
|
|
||||||
|
await buildAndVerifyAssets(
|
||||||
|
assets,
|
||||||
|
<String>['test_package2'],
|
||||||
|
expectedAssetManifest,
|
||||||
|
);
|
||||||
|
}, overrides: <Type, Generator>{
|
||||||
|
FileSystem: () => new MemoryFileSystem(),
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user