Commit 0b95e9c2 authored by Sarah Zakarias's avatar Sarah Zakarias Committed by GitHub

Support transitive asset dependency (#12032)

parent a1f03977
......@@ -137,7 +137,7 @@ class AssetBundle {
packageMap,
packageManifestDescriptor['flutter'],
packageBasePath,
packageKey: packageName,
packageName: packageName,
));
}
}
......@@ -434,7 +434,7 @@ Map<_Asset, List<_Asset>> _parseAssets(
Map<String, dynamic> manifestDescriptor,
String assetBase, {
List<String> excludeDirs: const <String>[],
String packageKey
String packageName
}) {
final Map<_Asset, List<_Asset>> result = <_Asset, List<_Asset>>{};
......@@ -444,11 +444,13 @@ Map<_Asset, List<_Asset>> _parseAssets(
if (manifestDescriptor.containsKey('assets')) {
final _AssetDirectoryCache cache = new _AssetDirectoryCache(excludeDirs);
for (String assetName in manifestDescriptor['assets']) {
final _Asset asset = packageKey != null
? _resolvePackageAsset(assetBase, packageKey, assetName)
: _resolveAsset(packageMap, assetBase, assetName);
final _Asset asset = _resolveAsset(
packageMap,
assetBase,
assetName,
packageName,
);
final List<_Asset> variants = <_Asset>[];
for (String path in cache.variantsFor(asset.assetFile.path)) {
final String key = fs.path.relative(path, from: asset.base);
String assetEntry;
......@@ -473,7 +475,12 @@ Map<_Asset, List<_Asset>> _parseAssets(
if (asset == null)
continue;
final _Asset baseAsset = _resolveAsset(packageMap, assetBase, asset);
final _Asset baseAsset = _resolveAsset(
packageMap,
assetBase,
asset,
packageName
);
if (!baseAsset.assetFileExists) {
printError('Error: unable to locate asset entry in pubspec.yaml: "$asset".');
return null;
......@@ -487,42 +494,46 @@ Map<_Asset, List<_Asset>> _parseAssets(
return result;
}
_Asset _resolvePackageAsset(
String assetBase,
String packageName,
String asset,
) {
return new _Asset(
base: assetBase,
assetEntry: 'packages/$packageName/$asset',
relativePath: asset,
);
}
_Asset _resolveAsset(
PackageMap packageMap,
String assetBase,
String asset,
String packageName,
) {
if (asset.startsWith('packages/') && !fs.isFileSync(fs.path.join(assetBase, asset))) {
// Convert packages/flutter_gallery_assets/clouds-0.png to clouds-0.png.
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);
}
// The asset is referenced in the pubspec.yaml as
// 'packages/PACKAGE_NAME/PATH/TO/ASSET
final _Asset packageAsset = _resolvePackageAsset(asset, packageMap);
if (packageAsset != null)
return packageAsset;
}
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);
}
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);
}
return new _Asset(base: assetBase, relativePath: asset);
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) {
......
......@@ -133,6 +133,32 @@ $assetsSection
}, overrides: <Type, Generator>{
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 {
establishFlutterRoot();
......@@ -160,6 +186,35 @@ $assetsSection
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 {
establishFlutterRoot();
......@@ -187,10 +242,47 @@ $assetsSection
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 {
establishFlutterRoot();
writePubspecFile('pubspec.yaml', 'test');
writePubspecFile(
'pubspec.yaml',
'test',
);
writePackagesFile('test_package:p/p/lib/\ntest_package2:p2/p/lib/');
writePubspecFile(
'p/p/pubspec.yaml',
......@@ -221,5 +313,79 @@ $assetsSection
}, overrides: <Type, Generator>{
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(),
});
});
}
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