[flutter_tools] refactor FlutterManifest to be context-free (#54555)

diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart
index c2c33d1..6db13de 100644
--- a/packages/flutter_tools/lib/src/asset.dart
+++ b/packages/flutter_tools/lib/src/asset.dart
@@ -128,7 +128,11 @@
     packagesPath ??= globals.fs.path.absolute(PackageMap.globalPackagesPath);
     FlutterManifest flutterManifest;
     try {
-      flutterManifest = FlutterManifest.createFromPath(manifestPath);
+      flutterManifest = FlutterManifest.createFromPath(
+        manifestPath,
+        logger: globals.logger,
+        fileSystem: globals.fs,
+      );
     } on Exception catch (e) {
       globals.printStatus('Error detected in pubspec.yaml:', emphasis: true);
       globals.printError('$e');
@@ -187,7 +191,11 @@
       final Uri packageUri = package.packageUriRoot;
       if (packageUri != null && packageUri.scheme == 'file') {
         final String packageManifestPath = globals.fs.path.fromUri(packageUri.resolve('../pubspec.yaml'));
-        final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath(packageManifestPath);
+        final FlutterManifest packageFlutterManifest = FlutterManifest.createFromPath(
+          packageManifestPath,
+          logger: globals.logger,
+          fileSystem: globals.fs,
+        );
         if (packageFlutterManifest == null) {
           continue;
         }
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart
index b86ca76..aa3e9b4 100644
--- a/packages/flutter_tools/lib/src/flutter_manifest.dart
+++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -7,42 +7,45 @@
 import 'package:yaml/yaml.dart';
 
 import 'base/file_system.dart';
+import 'base/logger.dart';
 import 'base/user_messages.dart';
 import 'base/utils.dart';
 import 'cache.dart';
-import 'globals.dart' as globals;
 import 'plugins.dart';
 
 /// A wrapper around the `flutter` section in the `pubspec.yaml` file.
 class FlutterManifest {
-  FlutterManifest._();
+  FlutterManifest._(this._logger);
 
   /// Returns an empty manifest.
-  static FlutterManifest empty() {
-    final FlutterManifest manifest = FlutterManifest._();
+  factory FlutterManifest.empty({ @required Logger logger }) {
+    final FlutterManifest manifest = FlutterManifest._(logger);
     manifest._descriptor = const <String, dynamic>{};
     manifest._flutterDescriptor = const <String, dynamic>{};
     return manifest;
   }
 
   /// Returns null on invalid manifest. Returns empty manifest on missing file.
-  static FlutterManifest createFromPath(String path) {
-    if (path == null || !globals.fs.isFileSync(path)) {
-      return _createFromYaml(null);
+  static FlutterManifest createFromPath(String path, {
+    @required FileSystem fileSystem,
+    @required Logger logger,
+  }) {
+    if (path == null || !fileSystem.isFileSync(path)) {
+      return _createFromYaml(null, logger);
     }
-    final String manifest = globals.fs.file(path).readAsStringSync();
-    return createFromString(manifest);
+    final String manifest = fileSystem.file(path).readAsStringSync();
+    return FlutterManifest.createFromString(manifest, logger: logger);
   }
 
   /// Returns null on missing or invalid manifest
   @visibleForTesting
-  static FlutterManifest createFromString(String manifest) {
-    return _createFromYaml(loadYaml(manifest) as YamlMap);
+  static FlutterManifest createFromString(String manifest, { @required Logger logger }) {
+    return _createFromYaml(loadYaml(manifest) as YamlMap, logger);
   }
 
-  static FlutterManifest _createFromYaml(YamlMap yamlDocument) {
-    final FlutterManifest pubspec = FlutterManifest._();
-    if (yamlDocument != null && !_validate(yamlDocument)) {
+  static FlutterManifest _createFromYaml(YamlMap yamlDocument, Logger logger) {
+    final FlutterManifest pubspec = FlutterManifest._(logger);
+    if (yamlDocument != null && !_validate(yamlDocument, logger)) {
       return null;
     }
 
@@ -63,6 +66,8 @@
     return pubspec;
   }
 
+  final Logger _logger;
+
   /// A map representation of the entire `pubspec.yaml` file.
   Map<String, dynamic> _descriptor;
 
@@ -91,7 +96,7 @@
       version = Version.parse(verStr);
     } on Exception {
       if (!_hasShowInvalidVersionMsg) {
-        globals.printStatus(userMessages.invalidVersionSettingHintMessage(verStr), emphasis: true);
+        _logger.printStatus(userMessages.invalidVersionSettingHintMessage(verStr), emphasis: true);
         _hasShowInvalidVersionMsg = true;
       }
     }
@@ -203,14 +208,14 @@
     final List<Uri> results = <Uri>[];
     for (final Object asset in assets) {
       if (asset is! String || asset == null || asset == '') {
-        globals.printError('Asset manifest contains a null or empty uri.');
+        _logger.printError('Asset manifest contains a null or empty uri.');
         continue;
       }
       final String stringAsset = asset as String;
       try {
         results.add(Uri(pathSegments: stringAsset.split('/')));
       } on FormatException {
-        globals.printError('Asset manifest contains invalid uri: $asset.');
+        _logger.printError('Asset manifest contains invalid uri: $asset.');
       }
     }
     return results;
@@ -233,11 +238,11 @@
       final YamlList fontFiles = fontFamily['fonts'] as YamlList;
       final String familyName = fontFamily['family'] as String;
       if (familyName == null) {
-        globals.printError('Warning: Missing family name for font.', emphasis: true);
+        _logger.printError('Warning: Missing family name for font.', emphasis: true);
         continue;
       }
       if (fontFiles == null) {
-        globals.printError('Warning: No fonts specified for font $familyName', emphasis: true);
+        _logger.printError('Warning: No fonts specified for font $familyName', emphasis: true);
         continue;
       }
 
@@ -245,7 +250,7 @@
       for (final Map<dynamic, dynamic> fontFile in fontFiles.cast<Map<dynamic, dynamic>>()) {
         final String asset = fontFile['asset'] as String;
         if (asset == null) {
-          globals.printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
+          _logger.printError('Warning: Missing asset in fonts for $familyName', emphasis: true);
           continue;
         }
 
@@ -310,16 +315,16 @@
 }
 
 @visibleForTesting
-String buildSchemaDir(FileSystem fs) {
-  return globals.fs.path.join(
-    globals.fs.path.absolute(Cache.flutterRoot), 'packages', 'flutter_tools', 'schema',
+String buildSchemaDir(FileSystem fileSystem) {
+  return fileSystem.path.join(
+    fileSystem.path.absolute(Cache.flutterRoot), 'packages', 'flutter_tools', 'schema',
   );
 }
 
 @visibleForTesting
-String buildSchemaPath(FileSystem fs) {
-  return globals.fs.path.join(
-    buildSchemaDir(fs),
+String buildSchemaPath(FileSystem fileSystem) {
+  return fileSystem.path.join(
+    buildSchemaDir(fileSystem),
     'pubspec_yaml.json',
   );
 }
@@ -327,7 +332,7 @@
 /// This method should be kept in sync with the schema in
 /// `$FLUTTER_ROOT/packages/flutter_tools/schema/pubspec_yaml.json`,
 /// but avoid introducing dependencies on packages for simple validation.
-bool _validate(YamlMap manifest) {
+bool _validate(YamlMap manifest, Logger logger) {
   final List<String> errors = <String>[];
   for (final MapEntry<dynamic, dynamic> kvp in manifest.entries) {
     if (kvp.key is! String) {
@@ -357,8 +362,8 @@
   }
 
   if (errors.isNotEmpty) {
-    globals.printStatus('Error detected in pubspec.yaml:', emphasis: true);
-    globals.printError(errors.join('\n'));
+    logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
+    logger.printError(errors.join('\n'));
     return false;
   }
 
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index 43a743b..5031e3e 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -43,7 +43,10 @@
 OperatingSystemUtils get os => context.get<OperatingSystemUtils>();
 PersistentToolState get persistentToolState => PersistentToolState.instance;
 Usage get flutterUsage => context.get<Usage>();
-FlutterProjectFactory get projectFactory => context.get<FlutterProjectFactory>() ?? FlutterProjectFactory();
+FlutterProjectFactory get projectFactory => context.get<FlutterProjectFactory>() ?? FlutterProjectFactory(
+  logger: logger,
+  fileSystem: fs,
+);
 
 const FileSystem _kLocalFs = LocalFileSystem();
 
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index 4efd7c5..9928c96 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -12,6 +12,7 @@
 import 'artifacts.dart';
 import 'base/common.dart';
 import 'base/file_system.dart';
+import 'base/logger.dart';
 import 'build_info.dart';
 import 'bundle.dart' as bundle;
 import 'features.dart';
@@ -24,7 +25,14 @@
 import 'template.dart';
 
 class FlutterProjectFactory {
-  FlutterProjectFactory();
+  FlutterProjectFactory({
+    @required Logger logger,
+    @required FileSystem fileSystem,
+  }) : _logger = logger,
+       _fileSystem = fileSystem;
+
+  final Logger _logger;
+  final FileSystem _fileSystem;
 
   @visibleForTesting
   final Map<String, FlutterProject> projects =
@@ -34,14 +42,18 @@
   /// if `pubspec.yaml` or `example/pubspec.yaml` is invalid.
   FlutterProject fromDirectory(Directory directory) {
     assert(directory != null);
-    return projects.putIfAbsent(directory.path, /* ifAbsent */ () {
+    return projects.putIfAbsent(directory.path, () {
       final FlutterManifest manifest = FlutterProject._readManifest(
         directory.childFile(bundle.defaultManifestPath).path,
+        logger: _logger,
+        fileSystem: _fileSystem,
       );
       final FlutterManifest exampleManifest = FlutterProject._readManifest(
         FlutterProject._exampleDirectory(directory)
             .childFile(bundle.defaultManifestPath)
             .path,
+        logger: _logger,
+        fileSystem: _fileSystem,
       );
       return FlutterProject(directory, manifest, exampleManifest);
     });
@@ -167,7 +179,7 @@
   FlutterProject get example => FlutterProject(
     _exampleDirectory(directory),
     _exampleManifest,
-    FlutterManifest.empty(),
+    FlutterManifest.empty(logger: globals.logger),
   );
 
   /// True if this project is a Flutter module project.
@@ -187,13 +199,20 @@
   ///
   /// Completes with an empty [FlutterManifest], if the file does not exist.
   /// Completes with a ToolExit on validation error.
-  static FlutterManifest _readManifest(String path) {
+  static FlutterManifest _readManifest(String path, {
+    @required Logger logger,
+    @required FileSystem fileSystem,
+  }) {
     FlutterManifest manifest;
     try {
-      manifest = FlutterManifest.createFromPath(path);
+      manifest = FlutterManifest.createFromPath(
+        path,
+        logger: logger,
+        fileSystem: fileSystem,
+      );
     } on YamlException catch (e) {
-      globals.printStatus('Error detected in pubspec.yaml:', emphasis: true);
-      globals.printError('$e');
+      logger.printStatus('Error detected in pubspec.yaml:', emphasis: true);
+      logger.printError('$e');
     }
     if (manifest == null) {
       throwToolExit('Please correct the pubspec.yaml file at $path');