Unverified Commit 52d49fb3 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] remove material design schema, use dart code (#69987)

Instead of loading the use-material-design asset data from a yaml file in the repo, leave it in dart code and simplify. Remove some of the globals, but not enough to update to testWithoutContext
parent 78778d29
...@@ -4,11 +4,10 @@ ...@@ -4,11 +4,10 @@
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart'; import 'package:package_config/package_config.dart';
import 'package:yaml/yaml.dart';
import 'base/context.dart'; import 'base/context.dart';
import 'base/file_system.dart'; import 'base/file_system.dart';
import 'base/utils.dart'; import 'base/logger.dart';
import 'build_info.dart'; import 'build_info.dart';
import 'cache.dart'; import 'cache.dart';
import 'convert.dart'; import 'convert.dart';
...@@ -18,18 +17,39 @@ import 'flutter_manifest.dart'; ...@@ -18,18 +17,39 @@ import 'flutter_manifest.dart';
import 'globals.dart' as globals; import 'globals.dart' as globals;
import 'project.dart'; import 'project.dart';
const AssetBundleFactory _kManifestFactory = _ManifestAssetBundleFactory();
const String defaultManifestPath = 'pubspec.yaml'; const String defaultManifestPath = 'pubspec.yaml';
const String kFontManifestJson = 'FontManifest.json'; const String kFontManifestJson = 'FontManifest.json';
/// The effect of adding `uses-material-design: true` to the pubspec is to insert
/// the following snippet into the asset manifest:
///
///```yaml
/// material:
/// - family: MaterialIcons
/// fonts:
/// - asset: fonts/MaterialIcons-Regular.otf
///```
const List<Map<String, Object>> kMaterialFonts = <Map<String, Object>>[
<String, Object>{
'family': 'MaterialIcons',
'fonts': <Map<String, Object>>[
<String, Object>{
'asset': 'fonts/MaterialIcons-Regular.otf',
},
],
},
];
/// Injected factory class for spawning [AssetBundle] instances. /// Injected factory class for spawning [AssetBundle] instances.
abstract class AssetBundleFactory { abstract class AssetBundleFactory {
/// The singleton instance, pulled from the [AppContext]. /// The singleton instance, pulled from the [AppContext].
static AssetBundleFactory get instance => context.get<AssetBundleFactory>(); static AssetBundleFactory get instance => context.get<AssetBundleFactory>();
static AssetBundleFactory get defaultInstance => _kManifestFactory; static AssetBundleFactory defaultInstance({
@required Logger logger,
@required FileSystem fileSystem,
}) => _ManifestAssetBundleFactory(logger: logger, fileSystem: fileSystem);
/// Creates a new [AssetBundle]. /// Creates a new [AssetBundle].
AssetBundle createBundle(); AssetBundle createBundle();
...@@ -57,17 +77,33 @@ abstract class AssetBundle { ...@@ -57,17 +77,33 @@ abstract class AssetBundle {
} }
class _ManifestAssetBundleFactory implements AssetBundleFactory { class _ManifestAssetBundleFactory implements AssetBundleFactory {
const _ManifestAssetBundleFactory(); _ManifestAssetBundleFactory({
@required Logger logger,
@required FileSystem fileSystem,
}) : _logger = logger,
_fileSystem = fileSystem;
final Logger _logger;
final FileSystem _fileSystem;
@override @override
AssetBundle createBundle() => ManifestAssetBundle(); AssetBundle createBundle() => ManifestAssetBundle(logger: _logger, fileSystem: _fileSystem);
} }
/// An asset bundle based on a pubspec.yaml file. /// An asset bundle based on a pubspec.yaml file.
class ManifestAssetBundle implements AssetBundle { class ManifestAssetBundle implements AssetBundle {
/// Constructs an [ManifestAssetBundle] that gathers the set of assets from the /// Constructs an [ManifestAssetBundle] that gathers the set of assets from the
/// pubspec.yaml manifest. /// pubspec.yaml manifest.
ManifestAssetBundle(); ManifestAssetBundle({
@required Logger logger,
@required FileSystem fileSystem,
}) : _logger = logger,
_fileSystem = fileSystem,
_licenseCollector = LicenseCollector(fileSystem: fileSystem);
final Logger _logger;
final FileSystem _fileSystem;
final LicenseCollector _licenseCollector;
@override @override
final Map<String, DevFSContent> entries = <String, DevFSContent>{}; final Map<String, DevFSContent> entries = <String, DevFSContent>{};
...@@ -77,12 +113,9 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -77,12 +113,9 @@ class ManifestAssetBundle implements AssetBundle {
// the current project. // the current project.
final Map<Uri, Directory> _wildcardDirectories = <Uri, Directory>{}; final Map<Uri, Directory> _wildcardDirectories = <Uri, Directory>{};
final LicenseCollector licenseCollector = LicenseCollector(fileSystem: globals.fs);
DateTime _lastBuildTimestamp; DateTime _lastBuildTimestamp;
static const String _kAssetManifestJson = 'AssetManifest.json'; static const String _kAssetManifestJson = 'AssetManifest.json';
static const String _kFontSetMaterial = 'material';
static const String _kNoticeFile = 'NOTICES'; static const String _kNoticeFile = 'NOTICES';
@override @override
...@@ -94,7 +127,7 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -94,7 +127,7 @@ class ManifestAssetBundle implements AssetBundle {
return true; return true;
} }
final FileStat stat = globals.fs.file(manifestPath).statSync(); final FileStat stat = _fileSystem.file(manifestPath).statSync();
if (stat.type == FileSystemEntityType.notFound) { if (stat.type == FileSystemEntityType.notFound) {
return true; return true;
} }
...@@ -128,10 +161,10 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -128,10 +161,10 @@ class ManifestAssetBundle implements AssetBundle {
assetDirPath ??= getAssetBuildDirectory(); assetDirPath ??= getAssetBuildDirectory();
FlutterProject flutterProject; FlutterProject flutterProject;
try { try {
flutterProject = FlutterProject.fromDirectory(globals.fs.file(manifestPath).parent); flutterProject = FlutterProject.fromDirectory(_fileSystem.file(manifestPath).parent);
} on Exception catch (e) { } on Exception catch (e) {
globals.printStatus('Error detected in pubspec.yaml:', emphasis: true); _logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
globals.printError('$e'); _logger.printError('$e');
return 1; return 1;
} }
if (flutterProject == null) { if (flutterProject == null) {
...@@ -147,10 +180,10 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -147,10 +180,10 @@ class ManifestAssetBundle implements AssetBundle {
return 0; return 0;
} }
final String assetBasePath = globals.fs.path.dirname(globals.fs.path.absolute(manifestPath)); final String assetBasePath = _fileSystem.path.dirname(_fileSystem.path.absolute(manifestPath));
final PackageConfig packageConfig = await loadPackageConfigWithLogging( final PackageConfig packageConfig = await loadPackageConfigWithLogging(
globals.fs.file(packagesPath), _fileSystem.file(packagesPath),
logger: globals.logger, logger: _logger,
); );
final List<Uri> wildcardDirectories = <Uri>[]; final List<Uri> wildcardDirectories = <Uri>[];
...@@ -193,11 +226,11 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -193,11 +226,11 @@ class ManifestAssetBundle implements AssetBundle {
for (final Package package in packageConfig.packages) { for (final Package package in packageConfig.packages) {
final Uri packageUri = package.packageUriRoot; final Uri packageUri = package.packageUriRoot;
if (packageUri != null && packageUri.scheme == 'file') { if (packageUri != null && packageUri.scheme == 'file') {
final String packageManifestPath = globals.fs.path.fromUri(packageUri.resolve('../pubspec.yaml')); final String packageManifestPath = _fileSystem.path.fromUri(packageUri.resolve('../pubspec.yaml'));
final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath( final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath(
packageManifestPath, packageManifestPath,
logger: globals.logger, logger: _logger,
fileSystem: globals.fs, fileSystem: _fileSystem,
); );
if (packageFlutterManifest == null) { if (packageFlutterManifest == null) {
continue; continue;
...@@ -206,7 +239,7 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -206,7 +239,7 @@ class ManifestAssetBundle implements AssetBundle {
if (packageFlutterManifest.appName == flutterManifest.appName) { if (packageFlutterManifest.appName == flutterManifest.appName) {
continue; continue;
} }
final String packageBasePath = globals.fs.path.dirname(packageManifestPath); final String packageBasePath = _fileSystem.path.dirname(packageManifestPath);
final Map<_Asset, List<_Asset>> packageAssets = _parseAssets( final Map<_Asset, List<_Asset>> packageAssets = _parseAssets(
packageConfig, packageConfig,
...@@ -223,7 +256,7 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -223,7 +256,7 @@ class ManifestAssetBundle implements AssetBundle {
} }
assetVariants.addAll(packageAssets); assetVariants.addAll(packageAssets);
if (!includesMaterialFonts && packageFlutterManifest.usesMaterialDesign) { if (!includesMaterialFonts && packageFlutterManifest.usesMaterialDesign) {
globals.printError( _logger.printError(
'package:${package.name} has `uses-material-design: true` set but ' 'package:${package.name} has `uses-material-design: true` set but '
'the primary pubspec contains `uses-material-design: false`. ' 'the primary pubspec contains `uses-material-design: false`. '
'If the application needs material icons, then `uses-material-design` ' 'If the application needs material icons, then `uses-material-design` '
...@@ -244,10 +277,10 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -244,10 +277,10 @@ class ManifestAssetBundle implements AssetBundle {
// asset in entries. // asset in entries.
for (final _Asset asset in assetVariants.keys) { for (final _Asset asset in assetVariants.keys) {
if (!asset.assetFileExists && assetVariants[asset].isEmpty) { if (!asset.assetFileExists && assetVariants[asset].isEmpty) {
globals.printStatus('Error detected in pubspec.yaml:', emphasis: true); _logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
globals.printError('No file or variants found for $asset.\n'); _logger.printError('No file or variants found for $asset.\n');
if (asset.package != null) { if (asset.package != null) {
globals.printError('This asset was included from package ${asset.package.name}.'); _logger.printError('This asset was included from package ${asset.package.name}.');
} }
return 1; return 1;
} }
...@@ -268,7 +301,7 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -268,7 +301,7 @@ class ManifestAssetBundle implements AssetBundle {
} }
final List<_Asset> materialAssets = <_Asset>[ final List<_Asset> materialAssets = <_Asset>[
if (flutterManifest.usesMaterialDesign && includeDefaultFonts) if (flutterManifest.usesMaterialDesign && includeDefaultFonts)
..._getMaterialAssets(_kFontSetMaterial), ..._getMaterialAssets(),
]; ];
for (final _Asset asset in materialAssets) { for (final _Asset asset in materialAssets) {
assert(asset.assetFileExists); assert(asset.assetFileExists);
...@@ -277,12 +310,12 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -277,12 +310,12 @@ class ManifestAssetBundle implements AssetBundle {
// Update wildcard directories we we can detect changes in them. // Update wildcard directories we we can detect changes in them.
for (final Uri uri in wildcardDirectories) { for (final Uri uri in wildcardDirectories) {
_wildcardDirectories[uri] ??= globals.fs.directory(uri); _wildcardDirectories[uri] ??= _fileSystem.directory(uri);
} }
final DevFSStringContent assetManifest = _createAssetManifest(assetVariants); final DevFSStringContent assetManifest = _createAssetManifest(assetVariants);
final DevFSStringContent fontManifest = DevFSStringContent(json.encode(fonts)); final DevFSStringContent fontManifest = DevFSStringContent(json.encode(fonts));
final LicenseResult licenseResult = licenseCollector.obtainLicenses(packageConfig); final LicenseResult licenseResult = _licenseCollector.obtainLicenses(packageConfig);
final DevFSStringContent licenses = DevFSStringContent(licenseResult.combinedLicenses); final DevFSStringContent licenses = DevFSStringContent(licenseResult.combinedLicenses);
additionalDependencies = licenseResult.dependencies; additionalDependencies = licenseResult.dependencies;
...@@ -290,13 +323,13 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -290,13 +323,13 @@ class ManifestAssetBundle implements AssetBundle {
// Force the depfile to contain missing files so that Gradle does not skip // Force the depfile to contain missing files so that Gradle does not skip
// the task. Wildcard directories are not compatible with full incremental // the task. Wildcard directories are not compatible with full incremental
// builds. For more context see https://github.com/flutter/flutter/issues/56466 . // builds. For more context see https://github.com/flutter/flutter/issues/56466 .
globals.printTrace( _logger.printTrace(
'Manifest contained wildcard assets. Inserting missing file into ' 'Manifest contained wildcard assets. Inserting missing file into '
'build graph to force rerun. for more information see #56466.' 'build graph to force rerun. for more information see #56466.'
); );
final int suffix = Object().hashCode; final int suffix = Object().hashCode;
additionalDependencies.add( additionalDependencies.add(
globals.fs.file('DOES_NOT_EXIST_RERUN_FOR_WILDCARD$suffix').absolute); _fileSystem.file('DOES_NOT_EXIST_RERUN_FOR_WILDCARD$suffix').absolute);
} }
_setIfChanged(_kAssetManifestJson, assetManifest); _setIfChanged(_kAssetManifestJson, assetManifest);
...@@ -318,6 +351,44 @@ class ManifestAssetBundle implements AssetBundle { ...@@ -318,6 +351,44 @@ class ManifestAssetBundle implements AssetBundle {
entries[key] = content; entries[key] = content;
} }
} }
List<_Asset> _getMaterialAssets() {
final List<_Asset> result = <_Asset>[];
for (final Map<String, Object> family in kMaterialFonts) {
for (final Map<String, Object> font in family['fonts'] as List<Map<String, Object>>) {
final Uri entryUri = _fileSystem.path.toUri(font['asset'] as String);
result.add(_Asset(
baseDir: _fileSystem.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
relativeUri: Uri(path: entryUri.pathSegments.last),
entryUri: entryUri,
package: null,
));
}
}
return result;
}
List<Map<String, dynamic>> _parseFonts(
FlutterManifest manifest,
bool includeDefaultFonts,
PackageConfig packageConfig, {
String packageName,
@required bool primary,
}) {
return <Map<String, dynamic>>[
if (primary && manifest.usesMaterialDesign && includeDefaultFonts)
...kMaterialFonts,
if (packageName == null)
...manifest.fontsDescriptor
else
for (Font font in _parsePackageFonts(
manifest,
packageName,
packageConfig,
)) font.descriptor,
];
}
} }
@immutable @immutable
...@@ -376,39 +447,6 @@ class _Asset { ...@@ -376,39 +447,6 @@ class _Asset {
} }
} }
Map<String, dynamic> _readMaterialFontsManifest() {
final String fontsPath = globals.fs.path.join(globals.fs.path.absolute(Cache.flutterRoot),
'packages', 'flutter_tools', 'schema', 'material_fonts.yaml');
return castStringKeyedMap(loadYaml(globals.fs.file(fontsPath).readAsStringSync()));
}
final Map<String, dynamic> _materialFontsManifest = _readMaterialFontsManifest();
List<Map<String, dynamic>> _getMaterialFonts(String fontSet) {
final List<dynamic> fontsList = _materialFontsManifest[fontSet] as List<dynamic>;
return fontsList?.map<Map<String, dynamic>>(castStringKeyedMap)?.toList();
}
List<_Asset> _getMaterialAssets(String fontSet) {
final List<_Asset> result = <_Asset>[];
for (final Map<String, dynamic> family in _getMaterialFonts(fontSet)) {
for (final Map<dynamic, dynamic> font in (family['fonts'] as List<dynamic>).cast<Map<dynamic, dynamic>>()) {
final Uri entryUri = globals.fs.path.toUri(font['asset'] as String);
result.add(_Asset(
baseDir: globals.fs.path.join(Cache.flutterRoot, 'bin', 'cache', 'artifacts', 'material_fonts'),
relativeUri: Uri(path: entryUri.pathSegments.last),
entryUri: entryUri,
package: null,
));
}
}
return result;
}
/// Processes dependencies into a string representing the NOTICES file. /// Processes dependencies into a string representing the NOTICES file.
/// ///
/// Reads the NOTICES or LICENSE file from each package in the .packages file, /// Reads the NOTICES or LICENSE file from each package in the .packages file,
...@@ -532,26 +570,6 @@ DevFSStringContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants) ...@@ -532,26 +570,6 @@ DevFSStringContent _createAssetManifest(Map<_Asset, List<_Asset>> assetVariants)
return DevFSStringContent(json.encode(jsonObject)); return DevFSStringContent(json.encode(jsonObject));
} }
List<Map<String, dynamic>> _parseFonts(
FlutterManifest manifest,
bool includeDefaultFonts,
PackageConfig packageConfig, {
String packageName,
@required bool primary,
}) {
return <Map<String, dynamic>>[
if (primary && manifest.usesMaterialDesign && includeDefaultFonts)
..._getMaterialFonts(ManifestAssetBundle._kFontSetMaterial),
if (packageName == null)
...manifest.fontsDescriptor
else
..._createFontsDescriptor(_parsePackageFonts(
manifest,
packageName,
packageConfig,
)),
];
}
/// Prefixes family names and asset paths of fonts included from packages with /// Prefixes family names and asset paths of fonts included from packages with
/// 'packages/<package_name>' /// 'packages/<package_name>'
...@@ -586,10 +604,6 @@ List<Font> _parsePackageFonts( ...@@ -586,10 +604,6 @@ List<Font> _parsePackageFonts(
return packageFonts; return packageFonts;
} }
List<Map<String, dynamic>> _createFontsDescriptor(List<Font> fonts) {
return fonts.map<Map<String, dynamic>>((Font font) => font.descriptor).toList();
}
// Given an assets directory like this: // Given an assets directory like this:
// //
// assets/foo // assets/foo
...@@ -668,7 +682,6 @@ class _AssetDirectoryCache { ...@@ -668,7 +682,6 @@ class _AssetDirectoryCache {
/// ], /// ],
/// } /// }
/// ``` /// ```
Map<_Asset, List<_Asset>> _parseAssets( Map<_Asset, List<_Asset>> _parseAssets(
PackageConfig packageConfig, PackageConfig packageConfig,
FlutterManifest flutterManifest, FlutterManifest flutterManifest,
......
...@@ -44,7 +44,10 @@ Future<Depfile> copyAssets(Environment environment, Directory outputDirectory, { ...@@ -44,7 +44,10 @@ Future<Depfile> copyAssets(Environment environment, Directory outputDirectory, {
final File pubspecFile = environment.projectDir.childFile('pubspec.yaml'); final File pubspecFile = environment.projectDir.childFile('pubspec.yaml');
// Only the default asset bundle style is supported in assemble. // Only the default asset bundle style is supported in assemble.
final AssetBundle assetBundle = AssetBundleFactory.defaultInstance.createBundle(); final AssetBundle assetBundle = AssetBundleFactory.defaultInstance(
logger: environment.logger,
fileSystem: environment.fileSystem,
).createBundle();
final int resultCode = await assetBundle.build( final int resultCode = await assetBundle.build(
manifestPath: pubspecFile.path, manifestPath: pubspecFile.path,
packagesPath: environment.projectDir.childFile('.packages').path, packagesPath: environment.projectDir.childFile('.packages').path,
......
...@@ -110,7 +110,12 @@ Future<T> runInContext<T>( ...@@ -110,7 +110,12 @@ Future<T> runInContext<T>(
cache: globals.cache, cache: globals.cache,
platform: globals.platform, platform: globals.platform,
), ),
AssetBundleFactory: () => AssetBundleFactory.defaultInstance, AssetBundleFactory: () {
return AssetBundleFactory.defaultInstance(
logger: globals.logger,
fileSystem: globals.fs,
);
},
BuildSystem: () => FlutterBuildSystem( BuildSystem: () => FlutterBuildSystem(
fileSystem: globals.fs, fileSystem: globals.fs,
logger: globals.logger, logger: globals.logger,
......
material:
- family: MaterialIcons
fonts:
- asset: fonts/MaterialIcons-Regular.otf
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