Unverified Commit 92f7e163 authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tools] Make OperatingSystemUtils context-free (#49740)

parent 52df5994
......@@ -7,7 +7,6 @@ import 'package:meta/meta.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/version.dart';
import '../convert.dart';
......@@ -51,7 +50,7 @@ String getAdbPath([ AndroidSdk existingSdk ]) {
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
if (sdk?.latestVersion == null) {
return os.which('adb')?.path;
return globals.os.which('adb')?.path;
} else {
return sdk?.adbPath;
}
......@@ -331,7 +330,7 @@ class AndroidSdk {
}
// in build-tools/$version/aapt
final List<File> aaptBins = os.whichAll('aapt');
final List<File> aaptBins = globals.os.whichAll('aapt');
for (File aaptBin in aaptBins) {
// Make sure we're using the aapt from the SDK.
aaptBin = globals.fs.file(aaptBin.resolveSymbolicLinksSync());
......@@ -342,7 +341,7 @@ class AndroidSdk {
}
// in platform-tools/adb
final List<File> adbBins = os.whichAll('adb');
final List<File> adbBins = globals.os.whichAll('adb');
for (File adbBin in adbBins) {
// Make sure we're using the adb from the SDK.
adbBin = globals.fs.file(adbBin.resolveSymbolicLinksSync());
......@@ -566,7 +565,7 @@ class AndroidSdk {
}
// Fallback to PATH based lookup.
return os.which(_javaExecutable)?.path;
return globals.os.which(_javaExecutable)?.path;
}
Map<String, String> _sdkManagerEnv;
......@@ -578,8 +577,9 @@ class AndroidSdk {
_sdkManagerEnv = <String, String>{};
final String javaBinary = findJavaBinary();
if (javaBinary != null) {
_sdkManagerEnv['PATH'] =
globals.fs.path.dirname(javaBinary) + os.pathVarSeparator + globals.platform.environment['PATH'];
_sdkManagerEnv['PATH'] = globals.fs.path.dirname(javaBinary) +
globals.os.pathVarSeparator +
globals.platform.environment['PATH'];
}
}
return _sdkManagerEnv;
......
......@@ -8,7 +8,6 @@ import '../android/android_sdk.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/os.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../base/version.dart';
......@@ -172,7 +171,7 @@ bool _hasAnyExecutableFlagSet(File executable) {
void _giveExecutePermissionIfNeeded(File executable) {
if (!_hasAllExecutableFlagSet(executable)) {
globals.printTrace('Trying to give execute permission to ${executable.path}.');
os.makeExecutable(executable);
globals.os.makeExecutable(executable);
}
}
......
......@@ -14,7 +14,6 @@ import 'base/common.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/io.dart';
import 'base/os.dart' show os;
import 'base/process.dart';
import 'base/user_messages.dart';
import 'build_info.dart';
......@@ -291,7 +290,7 @@ abstract class IOSApp extends ApplicationPackage {
shutdownHooks.addShutdownHook(() async {
await tempDir.delete(recursive: true);
}, ShutdownStage.STILL_RECORDING);
os.unzip(globals.fs.file(applicationBinary), tempDir);
globals.os.unzip(globals.fs.file(applicationBinary), tempDir);
final Directory payloadDir = globals.fs.directory(
globals.fs.path.join(tempDir.path, 'Payload'),
);
......
......@@ -3,26 +3,60 @@
// found in the LICENSE file.
import 'package:archive/archive.dart';
import 'package:file/file.dart';
import 'package:meta/meta.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';
import '../globals.dart' as globals;
import 'context.dart';
import 'file_system.dart';
import 'io.dart';
import 'logger.dart';
import 'process.dart';
/// Returns [OperatingSystemUtils] active in the current app context (i.e. zone).
OperatingSystemUtils get os => context.get<OperatingSystemUtils>();
abstract class OperatingSystemUtils {
factory OperatingSystemUtils() {
if (globals.platform.isWindows) {
return _WindowsUtils();
factory OperatingSystemUtils({
@required FileSystem fileSystem,
@required Logger logger,
@required Platform platform,
@required ProcessManager processManager,
}) {
if (platform.isWindows) {
return _WindowsUtils(
fileSystem: fileSystem,
logger: logger,
platform: platform,
processManager: processManager,
);
} else {
return _PosixUtils();
return _PosixUtils(
fileSystem: fileSystem,
logger: logger,
platform: platform,
processManager: processManager,
);
}
}
OperatingSystemUtils._private();
OperatingSystemUtils._private({
@required FileSystem fileSystem,
@required Logger logger,
@required Platform platform,
@required ProcessManager processManager,
}) : _fileSystem = fileSystem,
_logger = logger,
_platform = platform,
_processManager = processManager,
_processUtils = ProcessUtils(
logger: logger,
processManager: processManager,
);
final FileSystem _fileSystem;
final Logger _logger;
final Platform _platform;
final ProcessManager _processManager;
final ProcessUtils _processUtils;
/// Make the given file executable. This may be a no-op on some platforms.
void makeExecutable(File file);
......@@ -73,7 +107,7 @@ abstract class OperatingSystemUtils {
'linux': 'Linux',
'windows': 'Windows',
};
final String osName = globals.platform.operatingSystem;
final String osName = _platform.operatingSystem;
return osNames.containsKey(osName) ? osNames[osName] : osName;
}
......@@ -101,10 +135,10 @@ abstract class OperatingSystemUtils {
if (!ipv6) {
return findFreePort(ipv6: true);
}
globals.printTrace('findFreePort failed: $e');
_logger.printTrace('findFreePort failed: $e');
} catch (e) {
// Failures are signaled by a return value of 0 from this function.
globals.printTrace('findFreePort failed: $e');
_logger.printTrace('findFreePort failed: $e');
} finally {
if (serverSocket != null) {
await serverSocket.close();
......@@ -115,7 +149,17 @@ abstract class OperatingSystemUtils {
}
class _PosixUtils extends OperatingSystemUtils {
_PosixUtils() : super._private();
_PosixUtils({
@required FileSystem fileSystem,
@required Logger logger,
@required Platform platform,
@required ProcessManager processManager,
}) : super._private(
fileSystem: fileSystem,
logger: logger,
platform: platform,
processManager: processManager,
);
@override
void makeExecutable(File file) {
......@@ -125,16 +169,20 @@ class _PosixUtils extends OperatingSystemUtils {
@override
void chmod(FileSystemEntity entity, String mode) {
try {
final ProcessResult result = globals.processManager.runSync(<String>['chmod', mode, entity.path]);
final ProcessResult result = _processManager.runSync(
<String>['chmod', mode, entity.path],
);
if (result.exitCode != 0) {
globals.printTrace(
_logger.printTrace(
'Error trying to run chmod on ${entity.absolute.path}'
'\nstdout: ${result.stdout}'
'\nstderr: ${result.stderr}',
);
}
} on ProcessException catch (error) {
globals.printTrace('Error trying to run chmod on ${entity.absolute.path}: $error');
_logger.printTrace(
'Error trying to run chmod on ${entity.absolute.path}: $error',
);
}
}
......@@ -145,17 +193,19 @@ class _PosixUtils extends OperatingSystemUtils {
if (all) '-a',
execName,
];
final ProcessResult result = globals.processManager.runSync(command);
final ProcessResult result = _processManager.runSync(command);
if (result.exitCode != 0) {
return const <File>[];
}
final String stdout = result.stdout as String;
return stdout.trim().split('\n').map<File>((String path) => globals.fs.file(path.trim())).toList();
return stdout.trim().split('\n').map<File>(
(String path) => _fileSystem.file(path.trim()),
).toList();
}
@override
void zip(Directory data, File zipFile) {
processUtils.runSync(
_processUtils.runSync(
<String>['zip', '-r', '-q', zipFile.path, '.'],
workingDirectory: data.path,
throwOnError: true,
......@@ -165,7 +215,7 @@ class _PosixUtils extends OperatingSystemUtils {
// unzip -o -q zipfile -d dest
@override
void unzip(File file, Directory targetDirectory) {
processUtils.runSync(
_processUtils.runSync(
<String>['unzip', '-o', '-q', file.path, '-d', targetDirectory.path],
throwOnError: true,
);
......@@ -173,12 +223,12 @@ class _PosixUtils extends OperatingSystemUtils {
@override
bool verifyZip(File zipFile) =>
processUtils.exitsHappySync(<String>['zip', '-T', zipFile.path]);
_processUtils.exitsHappySync(<String>['zip', '-T', zipFile.path]);
// tar -xzf tarball -C dest
@override
void unpack(File gzippedTarFile, Directory targetDirectory) {
processUtils.runSync(
_processUtils.runSync(
<String>['tar', '-xzf', gzippedTarFile.path, '-C', targetDirectory.path],
throwOnError: true,
);
......@@ -186,15 +236,15 @@ class _PosixUtils extends OperatingSystemUtils {
@override
bool verifyGzip(File gzippedFile) =>
processUtils.exitsHappySync(<String>['gzip', '-t', gzippedFile.path]);
_processUtils.exitsHappySync(<String>['gzip', '-t', gzippedFile.path]);
@override
File makePipe(String path) {
processUtils.runSync(
_processUtils.runSync(
<String>['mkfifo', path],
throwOnError: true,
);
return globals.fs.file(path);
return _fileSystem.file(path);
}
String _name;
......@@ -202,11 +252,11 @@ class _PosixUtils extends OperatingSystemUtils {
@override
String get name {
if (_name == null) {
if (globals.platform.isMacOS) {
if (_platform.isMacOS) {
final List<RunResult> results = <RunResult>[
processUtils.runSync(<String>['sw_vers', '-productName']),
processUtils.runSync(<String>['sw_vers', '-productVersion']),
processUtils.runSync(<String>['sw_vers', '-buildVersion']),
_processUtils.runSync(<String>['sw_vers', '-productName']),
_processUtils.runSync(<String>['sw_vers', '-productVersion']),
_processUtils.runSync(<String>['sw_vers', '-buildVersion']),
];
if (results.every((RunResult result) => result.exitCode == 0)) {
_name = '${results[0].stdout.trim()} ${results[1].stdout
......@@ -223,7 +273,17 @@ class _PosixUtils extends OperatingSystemUtils {
}
class _WindowsUtils extends OperatingSystemUtils {
_WindowsUtils() : super._private();
_WindowsUtils({
@required FileSystem fileSystem,
@required Logger logger,
@required Platform platform,
@required ProcessManager processManager,
}) : super._private(
fileSystem: fileSystem,
logger: logger,
platform: platform,
processManager: processManager,
);
@override
void makeExecutable(File file) {}
......@@ -234,15 +294,15 @@ class _WindowsUtils extends OperatingSystemUtils {
@override
List<File> _which(String execName, { bool all = false }) {
// `where` always returns all matches, not just the first one.
final ProcessResult result = globals.processManager.runSync(<String>['where', execName]);
final ProcessResult result = _processManager.runSync(<String>['where', execName]);
if (result.exitCode != 0) {
return const <File>[];
}
final List<String> lines = (result.stdout as String).trim().split('\n');
if (all) {
return lines.map<File>((String path) => globals.fs.file(path.trim())).toList();
return lines.map<File>((String path) => _fileSystem.file(path.trim())).toList();
}
return <File>[globals.fs.file(lines.first.trim())];
return <File>[_fileSystem.file(lines.first.trim())];
}
@override
......@@ -305,7 +365,10 @@ class _WindowsUtils extends OperatingSystemUtils {
continue;
}
final File destFile = globals.fs.file(globals.fs.path.join(targetDirectory.path, archiveFile.name));
final File destFile = _fileSystem.file(_fileSystem.path.join(
targetDirectory.path,
archiveFile.name,
));
if (!destFile.parent.existsSync()) {
destFile.parent.createSync(recursive: true);
}
......@@ -323,7 +386,7 @@ class _WindowsUtils extends OperatingSystemUtils {
@override
String get name {
if (_name == null) {
final ProcessResult result = globals.processManager.runSync(
final ProcessResult result = _processManager.runSync(
<String>['ver'], runInShell: true);
if (result.exitCode == 0) {
_name = (result.stdout as String).trim();
......
......@@ -18,7 +18,6 @@ import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/net.dart';
import '../base/os.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
import '../build_info.dart';
......@@ -403,7 +402,7 @@ class _ExperimentalResidentWebRunner extends ResidentWebRunner {
);
final String effectiveHostname = debuggingOptions.hostname ?? 'localhost';
final int hostPort = debuggingOptions.port == null
? await os.findFreePort()
? await globals.os.findFreePort()
: int.tryParse(debuggingOptions.port);
device.devFS = WebDevFS(
effectiveHostname,
......
......@@ -27,7 +27,6 @@ import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/net.dart';
import '../base/os.dart';
import '../build_info.dart';
import '../bundle.dart';
import '../cache.dart';
......@@ -225,7 +224,7 @@ class WebFs {
// Initialize the dwds server.
final String effectiveHostname = hostname ?? _kHostName;
final int hostPort = port == null ? await os.findFreePort() : int.tryParse(port);
final int hostPort = port == null ? await globals.os.findFreePort() : int.tryParse(port);
final Pipeline pipeline = const Pipeline().addMiddleware((Handler innerHandler) {
return (Request request) async {
......
......@@ -13,7 +13,7 @@ import 'base/file_system.dart';
import 'base/io.dart' show SocketException;
import 'base/logger.dart';
import 'base/net.dart';
import 'base/os.dart';
import 'base/os.dart' show OperatingSystemUtils;
import 'base/process.dart';
import 'features.dart';
import 'globals.dart' as globals;
......@@ -102,7 +102,7 @@ class Cache {
_logger = logger ?? globals.logger,
_fileSystem = fileSystem ?? globals.fs,
_platform = platform ?? globals.platform ,
_osUtils = osUtils ?? os {
_osUtils = osUtils ?? globals.os {
// TODO(zra): Move to initializer list once logger and platform parameters
// are required.
_net = Net(logger: _logger, platform: _platform);
......@@ -600,12 +600,12 @@ abstract class CachedArtifact extends ArtifactSet {
/// Download a zip archive from the given [url] and unzip it to [location].
Future<void> _downloadZipArchive(String message, Uri url, Directory location) {
return _downloadArchive(message, url, location, os.verifyZip, os.unzip);
return _downloadArchive(message, url, location, globals.os.verifyZip, globals.os.unzip);
}
/// Download a gzipped tarball from the given [url] and unpack it to [location].
Future<void> _downloadZippedTarball(String message, Uri url, Directory location) {
return _downloadArchive(message, url, location, os.verifyGzip, os.unpack);
return _downloadArchive(message, url, location, globals.os.verifyGzip, globals.os.unpack);
}
/// Create a temporary file and invoke [onTemporaryFile] with the file as
......@@ -748,7 +748,7 @@ abstract class EngineCachedArtifact extends CachedArtifact {
if (frameworkZip.existsSync()) {
final Directory framework = globals.fs.directory(globals.fs.path.join(dir.path, '$frameworkName.framework'));
framework.createSync();
os.unzip(frameworkZip, framework);
globals.os.unzip(frameworkZip, framework);
}
}
}
......@@ -786,14 +786,14 @@ abstract class EngineCachedArtifact extends CachedArtifact {
}
void _makeFilesExecutable(Directory dir) {
os.chmod(dir, 'a+r,a+x');
globals.os.chmod(dir, 'a+r,a+x');
for (final FileSystemEntity entity in dir.listSync(recursive: true)) {
if (entity is File) {
final FileStat stat = entity.statSync();
final bool isUserExecutable = ((stat.mode >> 6) & 0x1) == 1;
if (entity.basename == 'flutter_tester' || isUserExecutable) {
// Make the file readable and executable by all users.
os.chmod(entity, 'a+r,a+x');
globals.os.chmod(entity, 'a+r,a+x');
}
}
}
......
......@@ -15,7 +15,6 @@ import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/net.dart';
import '../base/os.dart';
import '../base/utils.dart';
import '../cache.dart';
import '../convert.dart';
......@@ -667,7 +666,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi
filesCreated++;
final String modes = sourceFile.statSync().modeString();
if (modes != null && modes.contains('x')) {
os.makeExecutable(destinationFile);
globals.os.makeExecutable(destinationFile);
}
},
);
......
......@@ -125,7 +125,12 @@ Future<T> runInContext<T>(
),
MacOSWorkflow: () => const MacOSWorkflow(),
MDnsObservatoryDiscovery: () => MDnsObservatoryDiscovery(),
OperatingSystemUtils: () => OperatingSystemUtils(),
OperatingSystemUtils: () => OperatingSystemUtils(
fileSystem: globals.fs,
logger: globals.logger,
platform: globals.platform,
processManager: globals.processManager,
),
PersistentToolState: () => PersistentToolState(),
ProcessInfo: () => ProcessInfo(),
ProcessUtils: () => ProcessUtils(
......
......@@ -9,7 +9,6 @@ import 'package:meta/meta.dart';
import 'application_package.dart';
import 'base/common.dart';
import 'base/io.dart';
import 'base/os.dart';
import 'build_info.dart';
import 'cache.dart';
import 'convert.dart';
......@@ -61,7 +60,7 @@ abstract class DesktopDevice extends Device {
DevicePortForwarder get portForwarder => const NoOpDevicePortForwarder();
@override
Future<String> get sdkNameAndVersion async => os.name;
Future<String> get sdkNameAndVersion async => globals.os.name;
@override
DeviceLogReader getLogReader({ ApplicationPackage app }) {
......
......@@ -12,7 +12,6 @@ import 'base/common.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
import 'base/os.dart';
import 'base/process.dart';
import 'base/terminal.dart';
import 'base/user_messages.dart';
......@@ -636,9 +635,15 @@ class FlutterValidator extends DoctorValidator {
valid = ValidationType.partial;
}
return ValidationResult(valid, messages,
return ValidationResult(
valid,
messages,
statusInfo: userMessages.flutterStatusInfo(
versionChannel, frameworkVersion, os.name, globals.platform.localeName),
versionChannel,
frameworkVersion,
globals.os.name,
globals.platform.localeName,
),
);
}
}
......
......@@ -14,7 +14,6 @@ import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/net.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/time.dart';
import '../build_info.dart';
......@@ -257,7 +256,7 @@ class FuchsiaDevice extends Device {
return LaunchResult.failed();
}
// Find out who the device thinks we are.
final int port = await os.findFreePort();
final int port = await globals.os.findFreePort();
if (port == 0) {
globals.printError('Failed to find a free port');
return LaunchResult.failed();
......@@ -733,7 +732,7 @@ class _FuchsiaPortForwarder extends DevicePortForwarder {
@override
Future<int> forward(int devicePort, {int hostPort}) async {
hostPort ??= await os.findFreePort();
hostPort ??= await globals.os.findFreePort();
if (hostPort == 0) {
throwToolExit('Failed to forward port $devicePort. No free host-side ports');
}
......
......@@ -12,16 +12,18 @@ import 'base/error_handling_file_system.dart';
import 'base/file_system.dart';
import 'base/io.dart';
import 'base/logger.dart';
import 'base/os.dart';
import 'base/terminal.dart';
import 'cache.dart';
import 'ios/mac.dart';
import 'macos/xcode.dart';
import 'version.dart';
Logger get logger => context.get<Logger>();
Artifacts get artifacts => context.get<Artifacts>();
Cache get cache => context.get<Cache>();
Config get config => context.get<Config>();
Artifacts get artifacts => context.get<Artifacts>();
Logger get logger => context.get<Logger>();
OperatingSystemUtils get os => context.get<OperatingSystemUtils>();
const FileSystem _kLocalFs = LocalFileSystem();
......
......@@ -12,7 +12,6 @@ import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/utils.dart';
import '../build_info.dart';
......@@ -419,7 +418,7 @@ Future<XcodeBuildResult> buildXcodeProject({
if (globals.logger.hasTerminal) {
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_build_log_pipe.');
scriptOutputPipeFile = tempDir.childFile('pipe_to_stdout');
os.makePipe(scriptOutputPipeFile.path);
globals.os.makePipe(scriptOutputPipeFile.path);
Future<void> listenToScriptOutputLine() async {
final List<String> lines = await scriptOutputPipeFile.readAsLines();
......
......@@ -14,7 +14,6 @@ import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/terminal.dart';
import '../base/utils.dart';
......@@ -118,7 +117,7 @@ void _updateGeneratedEnvironmentVariablesScript({
: project.ios.generatedEnvironmentVariableExportScript;
generatedModuleBuildPhaseScript.createSync(recursive: true);
generatedModuleBuildPhaseScript.writeAsStringSync(localsBuffer.toString());
os.chmod(generatedModuleBuildPhaseScript, '755');
globals.os.chmod(generatedModuleBuildPhaseScript, '755');
}
/// Build name parsed and validated from build info and manifest. Used for CFBundleShortVersionString.
......
......@@ -104,7 +104,7 @@ class CrashReportSender {
req.fields['product'] = _kProductId;
req.fields['version'] = flutterVersion;
req.fields['osName'] = globals.platform.operatingSystem;
req.fields['osVersion'] = os.name; // this actually includes version
req.fields['osVersion'] = globals.os.name; // this actually includes version
req.fields['type'] = _kDartTypeId;
req.fields['error_runtime_type'] = '${error.runtimeType}';
req.fields['error_message'] = '$error';
......
......@@ -14,7 +14,6 @@ import '../base/bot_detector.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/os.dart';
import '../base/time.dart';
import '../doctor.dart';
import '../features.dart';
......
......@@ -200,20 +200,28 @@ class _DefaultUsage implements Usage {
assert(_analytics != null);
// Report a more detailed OS version string than package:usage does by default.
_analytics.setSessionValue(cdKey(CustomDimensions.sessionHostOsDetails), os.name);
_analytics.setSessionValue(
cdKey(CustomDimensions.sessionHostOsDetails),
globals.os.name,
);
// Send the branch name as the "channel".
_analytics.setSessionValue(cdKey(CustomDimensions.sessionChannelName),
flutterVersion.getBranchName(redactUnknownBranches: true));
_analytics.setSessionValue(
cdKey(CustomDimensions.sessionChannelName),
flutterVersion.getBranchName(redactUnknownBranches: true),
);
// For each flutter experimental feature, record a session value in a comma
// separated list.
final String enabledFeatures = allFeatures
.where((Feature feature) {
return feature.configSetting != null &&
globals.config.getValue(feature.configSetting) == true;
})
.map((Feature feature) => feature.configSetting)
.join(',');
_analytics.setSessionValue(cdKey(CustomDimensions.enabledFlutterFeatures), enabledFeatures);
.where((Feature feature) {
return feature.configSetting != null &&
globals.config.getValue(feature.configSetting) == true;
})
.map((Feature feature) => feature.configSetting)
.join(',');
_analytics.setSessionValue(
cdKey(CustomDimensions.enabledFlutterFeatures),
enabledFeatures,
);
// Record the host as the application installer ID - the context that flutter_tools is running in.
if (globals.platform.environment.containsKey('FLUTTER_HOST')) {
......
......@@ -9,7 +9,6 @@ import 'package:coverage/coverage.dart' as coverage;
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/process.dart';
import '../base/utils.dart';
import '../dart/package_map.dart';
......@@ -139,7 +138,7 @@ class CoverageCollector extends TestWatcher {
return false;
}
if (os.which('lcov') == null) {
if (globals.os.which('lcov') == null) {
String installMessage = 'Please install lcov.';
if (globals.platform.isLinux) {
installMessage = 'Consider running "sudo apt-get install lcov".';
......
......@@ -11,7 +11,6 @@ import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/os.dart';
import '../convert.dart';
import '../globals.dart' as globals;
......@@ -118,7 +117,7 @@ class ChromeLauncher {
}
}
final int port = await os.findFreePort();
final int port = await globals.os.findFreePort();
final List<String> args = <String>[
chromeExecutable,
// Using a tmp directory ensures that a new instance of chrome launches
......
......@@ -46,7 +46,7 @@ void main() {
expect(errorCount, 0);
}, overrides: <Type, Generator>{
OperatingSystemUtils: () => os,
OperatingSystemUtils: () => globals.os,
Pub: () => const Pub(),
});
});
......@@ -69,7 +69,7 @@ void main() {
expect(errorCount, greaterThan(0));
}, overrides: <Type, Generator>{
OperatingSystemUtils: () => os,
OperatingSystemUtils: () => globals.os,
Pub: () => const Pub(),
});
......@@ -87,7 +87,7 @@ void main() {
await onDone;
expect(errorCount, 0);
}, overrides: <Type, Generator>{
OperatingSystemUtils: () => os,
OperatingSystemUtils: () => globals.os,
Pub: () => const Pub(),
});
}
......
......@@ -206,12 +206,13 @@ void main() {
});
group('PrebuiltIOSApp', () {
final MockOperatingSystemUtils os = MockOperatingSystemUtils();
final Map<Type, Generator> overrides = <Type, Generator>{
FileSystem: () => MemoryFileSystem(),
ProcessManager: () => FakeProcessManager.any(),
PlistParser: () => MockPlistUtils(),
Platform: _kNoColorTerminalPlatform,
OperatingSystemUtils: () => MockOperatingSystemUtils(),
OperatingSystemUtils: () => os,
};
testUsingContext('Error on non-existing file', () {
......
......@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
......@@ -16,82 +19,73 @@ const String kExecutable = 'foo';
const String kPath1 = '/bar/bin/$kExecutable';
const String kPath2 = '/another/bin/$kExecutable';
class MockLogger extends Mock implements Logger {}
void main() {
ProcessManager mockProcessManager;
MockProcessManager mockProcessManager;
setUp(() {
mockProcessManager = MockProcessManager();
});
group('which on POSIX', () {
OperatingSystemUtils createOSUtils(Platform platform) {
return OperatingSystemUtils(
fileSystem: MemoryFileSystem(),
logger: MockLogger(),
platform: platform,
processManager: mockProcessManager,
);
}
testUsingContext('returns null when executable does not exist', () async {
group('which on POSIX', () {
testWithoutContext('returns null when executable does not exist', () async {
when(mockProcessManager.runSync(<String>['which', kExecutable]))
.thenReturn(ProcessResult(0, 1, null, null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'linux'));
expect(utils.which(kExecutable), isNull);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
testUsingContext('returns exactly one result', () async {
testWithoutContext('returns exactly one result', () async {
when(mockProcessManager.runSync(<String>['which', 'foo']))
.thenReturn(ProcessResult(0, 0, kPath1, null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'linux'));
expect(utils.which(kExecutable).path, kPath1);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
testUsingContext('returns all results for whichAll', () async {
testWithoutContext('returns all results for whichAll', () async {
when(mockProcessManager.runSync(<String>['which', '-a', kExecutable]))
.thenReturn(ProcessResult(0, 0, '$kPath1\n$kPath2', null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'linux'));
final List<File> result = utils.whichAll(kExecutable);
expect(result, hasLength(2));
expect(result[0].path, kPath1);
expect(result[1].path, kPath2);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
});
group('which on Windows', () {
testUsingContext('returns null when executable does not exist', () async {
testWithoutContext('returns null when executable does not exist', () async {
when(mockProcessManager.runSync(<String>['where', kExecutable]))
.thenReturn(ProcessResult(0, 1, null, null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'windows'));
expect(utils.which(kExecutable), isNull);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'windows'),
});
testUsingContext('returns exactly one result', () async {
testWithoutContext('returns exactly one result', () async {
when(mockProcessManager.runSync(<String>['where', 'foo']))
.thenReturn(ProcessResult(0, 0, '$kPath1\n$kPath2', null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'windows'));
expect(utils.which(kExecutable).path, kPath1);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'windows'),
});
testUsingContext('returns all results for whichAll', () async {
testWithoutContext('returns all results for whichAll', () async {
when(mockProcessManager.runSync(<String>['where', kExecutable]))
.thenReturn(ProcessResult(0, 0, '$kPath1\n$kPath2', null));
final OperatingSystemUtils utils = OperatingSystemUtils();
final OperatingSystemUtils utils = createOSUtils(FakePlatform(operatingSystem: 'windows'));
final List<File> result = utils.whichAll(kExecutable);
expect(result, hasLength(2));
expect(result[0].path, kPath1);
expect(result[1].path, kPath2);
}, overrides: <Type, Generator>{
ProcessManager: () => mockProcessManager,
Platform: () => FakePlatform(operatingSystem: 'windows'),
});
});
}
......
......@@ -24,7 +24,7 @@ void main() {
testUsingContext('makeExecutable', () async {
final File file = globals.fs.file(globals.fs.path.join(tempDir.path, 'foo.script'));
file.writeAsStringSync('hello world');
os.makeExecutable(file);
globals.os.makeExecutable(file);
// Skip this test on windows.
if (!globals.platform.isWindows) {
......@@ -33,7 +33,12 @@ void main() {
expect(mode.substring(0, 3), endsWith('x'));
}
}, overrides: <Type, Generator>{
OperatingSystemUtils: () => OperatingSystemUtils(),
OperatingSystemUtils: () => OperatingSystemUtils(
fileSystem: globals.fs,
logger: globals.logger,
platform: globals.platform,
processManager: globals.processManager,
),
});
});
}
......@@ -9,10 +9,10 @@ import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/os.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/desktop_device.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
import 'package:process/process.dart';
......@@ -95,7 +95,7 @@ void main() {
testUsingContext('Uses OS name as SDK name', () async {
final FakeDesktopDevice device = FakeDesktopDevice();
expect(await device.sdkNameAndVersion, os.name);
expect(await device.sdkNameAndVersion, globals.os.name);
});
});
......
......@@ -23,12 +23,13 @@ void main() {
setUp(() {
final MockPlatform platform = MockPlatform();
final MockOperatingSystemUtils os = MockOperatingSystemUtils();
exitCompleter = Completer<int>.sync();
when(platform.isWindows).thenReturn(false);
testbed = Testbed(overrides: <Type, Generator>{
ProcessManager: () => MockProcessManager(),
Platform: () => platform,
OperatingSystemUtils: () => MockOperatingSystemUtils(),
OperatingSystemUtils: () => os,
}, setup: () {
when(os.findFreePort()).thenAnswer((Invocation invocation) async {
return 1234;
......
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