[flutter_tools] reduce globals in web validator and chrome launcher (#51443)
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index 922f45c..b9a3297 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -101,7 +101,13 @@
logger: globals.logger,
platform: globals.platform,
),
- ChromeLauncher: () => const ChromeLauncher(),
+ ChromeLauncher: () => ChromeLauncher(
+ fileSystem: globals.fs,
+ processManager: globals.processManager,
+ logger: globals.logger,
+ operatingSystemUtils: globals.os,
+ platform: globals.platform,
+ ),
CocoaPods: () => CocoaPods(),
CocoaPodsValidator: () => const CocoaPodsValidator(),
Config: () => Config(
diff --git a/packages/flutter_tools/lib/src/doctor.dart b/packages/flutter_tools/lib/src/doctor.dart
index 9078488..da35d54 100644
--- a/packages/flutter_tools/lib/src/doctor.dart
+++ b/packages/flutter_tools/lib/src/doctor.dart
@@ -73,7 +73,11 @@
if (iosWorkflow.appliesToHostPlatform || macOSWorkflow.appliesToHostPlatform)
GroupedValidator(<DoctorValidator>[xcodeValidator, cocoapodsValidator]),
if (webWorkflow.appliesToHostPlatform)
- const WebValidator(),
+ WebValidator(
+ chromeLauncher: globals.chromeLauncher,
+ platform: globals.platform,
+ fileSystem: globals.fs,
+ ),
if (linuxWorkflow.appliesToHostPlatform)
LinuxDoctorValidator(),
if (windowsWorkflow.appliesToHostPlatform)
diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart
index 68cda51..4342c73 100644
--- a/packages/flutter_tools/lib/src/globals.dart
+++ b/packages/flutter_tools/lib/src/globals.dart
@@ -25,6 +25,7 @@
import 'macos/xcode.dart';
import 'persistent_tool_state.dart';
import 'version.dart';
+import 'web/chrome.dart';
Artifacts get artifacts => context.get<Artifacts>();
Cache get cache => context.get<Cache>();
@@ -148,3 +149,6 @@
/// The global Stdio wrapper.
Stdio get stdio => context.get<Stdio>() ?? const Stdio();
+
+/// The [ChromeLauncher] instance.
+ChromeLauncher get chromeLauncher => context.get<ChromeLauncher>();
diff --git a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
index 9ee248a..30885f9 100644
--- a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
+++ b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart
@@ -642,7 +642,7 @@
bool headless = true,
}) async {
final Chrome chrome =
- await chromeLauncher.launch(url.toString(), headless: headless);
+ await globals.chromeLauncher.launch(url.toString(), headless: headless);
final Completer<BrowserManager> completer = Completer<BrowserManager>();
diff --git a/packages/flutter_tools/lib/src/web/chrome.dart b/packages/flutter_tools/lib/src/web/chrome.dart
index ee54401..f285496 100644
--- a/packages/flutter_tools/lib/src/web/chrome.dart
+++ b/packages/flutter_tools/lib/src/web/chrome.dart
@@ -5,17 +5,16 @@
import 'dart:async';
import 'package:meta/meta.dart';
+import 'package:platform/platform.dart';
+import 'package:process/process.dart';
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
import '../base/common.dart';
-import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
+import '../base/logger.dart';
+import '../base/os.dart';
import '../convert.dart';
-import '../globals.dart' as globals;
-
-/// The [ChromeLauncher] instance.
-ChromeLauncher get chromeLauncher => context.get<ChromeLauncher>();
/// An environment variable used to override the location of chrome.
const String kChromeEnvironment = 'CHROME_EXECUTABLE';
@@ -30,37 +29,36 @@
/// The expected executable name on Windows.
const String kWindowsExecutable = r'Google\Chrome\Application\chrome.exe';
-/// The possible locations where the chrome executable can be located on windows.
-final List<String> kWindowsPrefixes = <String>[
- globals.platform.environment['LOCALAPPDATA'],
- globals.platform.environment['PROGRAMFILES'],
- globals.platform.environment['PROGRAMFILES(X86)'],
-];
-
/// Find the chrome executable on the current platform.
///
/// Does not verify whether the executable exists.
-String findChromeExecutable() {
- if (globals.platform.environment.containsKey(kChromeEnvironment)) {
- return globals.platform.environment[kChromeEnvironment];
+String findChromeExecutable(Platform platform, FileSystem fileSystem) {
+ if (platform.environment.containsKey(kChromeEnvironment)) {
+ return platform.environment[kChromeEnvironment];
}
- if (globals.platform.isLinux) {
+ if (platform.isLinux) {
return kLinuxExecutable;
}
- if (globals.platform.isMacOS) {
+ if (platform.isMacOS) {
return kMacOSExecutable;
}
- if (globals.platform.isWindows) {
+ if (platform.isWindows) {
+ /// The possible locations where the chrome executable can be located on windows.
+ final List<String> kWindowsPrefixes = <String>[
+ platform.environment['LOCALAPPDATA'],
+ platform.environment['PROGRAMFILES'],
+ platform.environment['PROGRAMFILES(X86)'],
+ ];
final String windowsPrefix = kWindowsPrefixes.firstWhere((String prefix) {
if (prefix == null) {
return false;
}
- final String path = globals.fs.path.join(prefix, kWindowsExecutable);
- return globals.fs.file(path).existsSync();
+ final String path = fileSystem.path.join(prefix, kWindowsExecutable);
+ return fileSystem.file(path).existsSync();
}, orElse: () => '.');
- return globals.fs.path.join(windowsPrefix, kWindowsExecutable);
+ return fileSystem.path.join(windowsPrefix, kWindowsExecutable);
}
- throwToolExit('Platform ${globals.platform.operatingSystem} is not supported.');
+ throwToolExit('Platform ${platform.operatingSystem} is not supported.');
return null;
}
@@ -76,7 +74,23 @@
/// Responsible for launching chrome with devtools configured.
class ChromeLauncher {
- const ChromeLauncher();
+ const ChromeLauncher({
+ @required FileSystem fileSystem,
+ @required Platform platform,
+ @required ProcessManager processManager,
+ @required OperatingSystemUtils operatingSystemUtils,
+ @required Logger logger,
+ }) : _fileSystem = fileSystem,
+ _platform = platform,
+ _processManager = processManager,
+ _operatingSystemUtils = operatingSystemUtils,
+ _logger = logger;
+
+ final FileSystem _fileSystem;
+ final Platform _platform;
+ final ProcessManager _processManager;
+ final OperatingSystemUtils _operatingSystemUtils;
+ final Logger _logger;
static bool get hasChromeInstance => _currentCompleter.isCompleted;
@@ -84,9 +98,9 @@
/// Whether we can locate the chrome executable.
bool canFindChrome() {
- final String chrome = findChromeExecutable();
+ final String chrome = findChromeExecutable(_platform, _fileSystem);
try {
- return globals.processManager.canRun(chrome);
+ return _processManager.canRun(chrome);
} on ArgumentError {
return false;
}
@@ -105,14 +119,14 @@
// This is a JSON file which contains configuration from the
// browser session, such as window position. It is located
// under the Chrome data-dir folder.
- final String preferencesPath = globals.fs.path.join('Default', 'preferences');
+ final String preferencesPath = _fileSystem.path.join('Default', 'preferences');
- final String chromeExecutable = findChromeExecutable();
- final Directory activeDataDir = globals.fs.systemTempDirectory.createTempSync('flutter_tool.');
+ final String chromeExecutable = findChromeExecutable(_platform, _fileSystem);
+ final Directory activeDataDir = _fileSystem.systemTempDirectory.createTempSync('flutter_tool.');
// Seed data dir with previous state.
- final File savedPreferencesFile = globals.fs.file(globals.fs.path.join(dataDir?.path ?? '', preferencesPath));
- final File destinationFile = globals.fs.file(globals.fs.path.join(activeDataDir.path, preferencesPath));
+ final File savedPreferencesFile = _fileSystem.file(_fileSystem.path.join(dataDir?.path ?? '', preferencesPath));
+ final File destinationFile = _fileSystem.file(_fileSystem.path.join(activeDataDir.path, preferencesPath));
if (dataDir != null) {
if (savedPreferencesFile.existsSync()) {
destinationFile.parent.createSync(recursive: true);
@@ -120,7 +134,7 @@
}
}
- final int port = debugPort ?? await globals.os.findFreePort();
+ final int port = debugPort ?? await _operatingSystemUtils.findFreePort();
final List<String> args = <String>[
chromeExecutable,
// Using a tmp directory ensures that a new instance of chrome launches
@@ -143,7 +157,7 @@
url,
];
- final Process process = await globals.processManager.start(args);
+ final Process process = await _processManager.start(args);
// When the process exits, copy the user settings back to the provided
// data-dir.
@@ -164,7 +178,7 @@
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((String line) {
- globals.printTrace('[CHROME]: $line');
+ _logger.printTrace('[CHROME]: $line');
});
// Wait until the DevTools are listening before trying to connect.
@@ -172,7 +186,7 @@
.transform(utf8.decoder)
.transform(const LineSplitter())
.map((String line) {
- globals.printTrace('[CHROME]:$line');
+ _logger.printTrace('[CHROME]:$line');
return line;
})
.firstWhere((String line) => line.startsWith('DevTools listening'), orElse: () {
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart
index eb14642..d38e772 100644
--- a/packages/flutter_tools/lib/src/web/web_device.dart
+++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -80,7 +80,7 @@
Future<String> get emulatorId async => null;
@override
- bool isSupported() => featureFlags.isWebEnabled && chromeLauncher.canFindChrome();
+ bool isSupported() => featureFlags.isWebEnabled && globals.chromeLauncher.canFindChrome();
@override
String get name => 'Chrome';
@@ -109,7 +109,7 @@
}
}
} else {
- final String chrome = findChromeExecutable();
+ final String chrome = findChromeExecutable(globals.platform, globals.fs);
final ProcessResult result = await globals.processManager.run(<String>[
chrome,
'--version',
@@ -136,7 +136,7 @@
final String url = platformArgs['uri'] as String;
final bool launchChrome = platformArgs['no-launch-chrome'] != true;
if (launchChrome) {
- _chrome = await chromeLauncher.launch(
+ _chrome = await globals.chromeLauncher.launch(
url,
dataDir: globals.fs.currentDirectory
.childDirectory('.dart_tool')
@@ -177,7 +177,7 @@
class WebDevices extends PollingDeviceDiscovery {
WebDevices() : super('chrome');
- final bool _chromeIsAvailable = chromeLauncher.canFindChrome();
+ final bool _chromeIsAvailable = globals.chromeLauncher.canFindChrome();
final ChromeDevice _webDevice = ChromeDevice();
final WebServerDevice _webServerDevice = WebServerDevice();
diff --git a/packages/flutter_tools/lib/src/web/web_validator.dart b/packages/flutter_tools/lib/src/web/web_validator.dart
index b96ae3e..d18450d 100644
--- a/packages/flutter_tools/lib/src/web/web_validator.dart
+++ b/packages/flutter_tools/lib/src/web/web_validator.dart
@@ -2,20 +2,34 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:meta/meta.dart';
+import 'package:platform/platform.dart';
+
+import '../base/file_system.dart';
import '../doctor.dart';
-import '../globals.dart' as globals;
import 'chrome.dart';
/// A validator that checks whether chrome is installed and can run.
class WebValidator extends DoctorValidator {
- const WebValidator() : super('Chrome - develop for the web');
+ const WebValidator({
+ @required Platform platform,
+ @required ChromeLauncher chromeLauncher,
+ @required FileSystem fileSystem,
+ }) : _platform = platform,
+ _chromeLauncher = chromeLauncher,
+ _fileSystem = fileSystem,
+ super('Chrome - develop for the web');
+
+ final Platform _platform;
+ final ChromeLauncher _chromeLauncher;
+ final FileSystem _fileSystem;
@override
Future<ValidationResult> validate() async {
- final String chrome = findChromeExecutable();
- final bool canRunChrome = chromeLauncher.canFindChrome();
+ final String chrome = findChromeExecutable(_platform, _fileSystem);
+ final bool canRunChrome = _chromeLauncher.canFindChrome();
final List<ValidationMessage> messages = <ValidationMessage>[
- if (globals.platform.environment.containsKey(kChromeEnvironment))
+ if (_platform.environment.containsKey(kChromeEnvironment))
if (!canRunChrome)
ValidationMessage.hint('$chrome is not executable.')
else
diff --git a/packages/flutter_tools/test/general.shard/web/chrome_test.dart b/packages/flutter_tools/test/general.shard/web/chrome_test.dart
index 9ccea6e..56c6ac8 100644
--- a/packages/flutter_tools/test/general.shard/web/chrome_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/chrome_test.dart
@@ -71,7 +71,7 @@
}
test('can launch chrome and connect to the devtools', () => testbed.run(() async {
- await chromeLauncher.launch('example_url', skipCheck: true);
+ await globals.chromeLauncher.launch('example_url', skipCheck: true);
final VerificationResult result = verify(globals.processManager.start(captureAny));
expect(result.captured.single, containsAll(expectChromeArgs()));
@@ -79,7 +79,7 @@
}));
test('can launch chrome with a custom debug port', () => testbed.run(() async {
- await chromeLauncher.launch('example_url', skipCheck: true, debugPort: 10000);
+ await globals.chromeLauncher.launch('example_url', skipCheck: true, debugPort: 10000);
final VerificationResult result = verify(globals.processManager.start(captureAny));
expect(result.captured.single, containsAll(expectChromeArgs(debugPort: 10000)));
@@ -87,7 +87,7 @@
}));
test('can launch chrome headless', () => testbed.run(() async {
- await chromeLauncher.launch('example_url', skipCheck: true, headless: true);
+ await globals.chromeLauncher.launch('example_url', skipCheck: true, headless: true);
final VerificationResult result = verify(globals.processManager.start(captureAny));
expect(result.captured.single, containsAll(expectChromeArgs()));
@@ -104,7 +104,7 @@
..createSync(recursive: true)
..writeAsStringSync('example');
- await chromeLauncher.launch('example_url', skipCheck: true, dataDir: dataDir);
+ await globals.chromeLauncher.launch('example_url', skipCheck: true, dataDir: dataDir);
final VerificationResult result = verify(globals.processManager.start(captureAny));
final String arg = (result.captured.single as List<String>)
.firstWhere((String arg) => arg.startsWith('--user-data-dir='));
diff --git a/packages/flutter_tools/test/general.shard/web/web_validator_test.dart b/packages/flutter_tools/test/general.shard/web/web_validator_test.dart
index d9ed734..b2bb2ba 100644
--- a/packages/flutter_tools/test/general.shard/web/web_validator_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/web_validator_test.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:file/memory.dart';
+import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/doctor.dart';
import 'package:flutter_tools/src/web/chrome.dart';
import 'package:flutter_tools/src/web/web_validator.dart';
@@ -10,56 +12,63 @@
import 'package:platform/platform.dart';
import '../../src/common.dart';
-import '../../src/testbed.dart';
+import '../../src/fake_process_manager.dart';
void main() {
- group('WebValidator', () {
- Testbed testbed;
- WebValidator webValidator;
- MockPlatform mockPlatform;
- MockProcessManager mockProcessManager;
+ Platform platform;
+ ProcessManager processManager;
+ ChromeLauncher chromeLauncher;
+ FileSystem fileSystem;
+ WebValidator webValidator;
- setUp(() {
- mockProcessManager = MockProcessManager();
- testbed = Testbed(setup: () {
- when(mockProcessManager.canRun(kMacOSExecutable)).thenReturn(true);
- return null;
- }, overrides: <Type, Generator>{
- Platform: () => mockPlatform,
- ProcessManager: () => mockProcessManager,
- });
- webValidator = const WebValidator();
- mockPlatform = MockPlatform();
- when(mockPlatform.isMacOS).thenReturn(true);
- when(mockPlatform.isWindows).thenReturn(false);
- when(mockPlatform.isLinux).thenReturn(false);
- });
-
- test('Can find macOS executable ', () => testbed.run(() async {
- final ValidationResult result = await webValidator.validate();
- expect(result.type, ValidationType.installed);
- }));
-
- test('Can notice missing macOS executable ', () => testbed.run(() async {
- when(mockProcessManager.canRun(kMacOSExecutable)).thenReturn(false);
- final ValidationResult result = await webValidator.validate();
- expect(result.type, ValidationType.missing);
- }));
-
- test("Doesn't warn about CHROME_EXECUTABLE unless it cant find chrome ", () => testbed.run(() async {
- when(mockProcessManager.canRun(kMacOSExecutable)).thenReturn(false);
- final ValidationResult result = await webValidator.validate();
- expect(result.messages, <ValidationMessage>[
- ValidationMessage.hint('Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.'),
- ]);
- expect(result.type, ValidationType.missing);
- }));
+ setUp(() {
+ fileSystem = MemoryFileSystem.test();
+ processManager = MockProcessManager();
+ platform = FakePlatform(
+ operatingSystem: 'macos',
+ environment: <String, String>{},
+ );
+ chromeLauncher = ChromeLauncher(
+ fileSystem: fileSystem,
+ platform: platform,
+ processManager: processManager,
+ operatingSystemUtils: null,
+ logger: null,
+ );
+ webValidator = webValidator = WebValidator(
+ platform: platform,
+ chromeLauncher: chromeLauncher,
+ fileSystem: fileSystem,
+ );
});
-}
-class MockPlatform extends Mock implements Platform {
- @override
- Map<String, String> get environment => const <String, String>{};
+ testWithoutContext('WebValidator can find executable on macOS', () async {
+ when(processManager.canRun(kMacOSExecutable)).thenReturn(true);
+
+ final ValidationResult result = await webValidator.validate();
+
+ expect(result.type, ValidationType.installed);
+ });
+
+ testWithoutContext('WebValidator Can notice missing macOS executable ', () async {
+ when(processManager.canRun(kMacOSExecutable)).thenReturn(false);
+
+ final ValidationResult result = await webValidator.validate();
+
+ expect(result.type, ValidationType.missing);
+ });
+
+ testWithoutContext('WebValidator does not warn about CHROME_EXECUTABLE unless it cant find chrome ', () async {
+ when(processManager.canRun(kMacOSExecutable)).thenReturn(false);
+
+ final ValidationResult result = await webValidator.validate();
+
+ expect(result.messages, <ValidationMessage>[
+ ValidationMessage.hint(
+ 'Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.'),
+ ]);
+ expect(result.type, ValidationType.missing);
+ });
}
class MockProcessManager extends Mock implements ProcessManager {}