mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Migrate linux_doctor to null safety (#79804)
This commit is contained in:
parent
32440ce165
commit
b481d4b237
@ -2,9 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:process/process.dart';
|
||||
|
||||
import '../base/io.dart';
|
||||
@ -19,7 +16,7 @@ class _VersionInfo {
|
||||
/// This should contain a version number. For example:
|
||||
/// "clang version 9.0.1-6+build1"
|
||||
_VersionInfo(this.description) {
|
||||
final String versionString = RegExp(r'[0-9]+\.[0-9]+(?:\.[0-9]+)?').firstMatch(description).group(0);
|
||||
final String? versionString = RegExp(r'[0-9]+\.[0-9]+(?:\.[0-9]+)?').firstMatch(description)?.group(0);
|
||||
number = Version.parse(versionString);
|
||||
}
|
||||
|
||||
@ -27,14 +24,14 @@ class _VersionInfo {
|
||||
String description;
|
||||
|
||||
// The parsed Version.
|
||||
Version number;
|
||||
Version? number;
|
||||
}
|
||||
|
||||
/// A validator that checks for Clang and Make build dependencies.
|
||||
class LinuxDoctorValidator extends DoctorValidator {
|
||||
LinuxDoctorValidator({
|
||||
@required ProcessManager processManager,
|
||||
@required UserMessages userMessages,
|
||||
required ProcessManager processManager,
|
||||
required UserMessages userMessages,
|
||||
}) : _processManager = processManager,
|
||||
_userMessages = userMessages,
|
||||
super('Linux toolchain - develop for Linux desktop');
|
||||
@ -65,29 +62,30 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
ValidationType validationType = ValidationType.installed;
|
||||
final List<ValidationMessage> messages = <ValidationMessage>[];
|
||||
|
||||
final Map<String, _VersionInfo> installedVersions = <String, _VersionInfo>{
|
||||
final Map<String, _VersionInfo?> installedVersions = <String, _VersionInfo?>{
|
||||
// Sort the check to make the call order predictable for unit tests.
|
||||
for (String binary in _requiredBinaryVersions.keys.toList()..sort())
|
||||
binary: await _getBinaryVersion(binary)
|
||||
};
|
||||
|
||||
// Determine overall validation level.
|
||||
if (installedVersions.values.contains(null)) {
|
||||
if (installedVersions.values.any((_VersionInfo? versionInfo) => versionInfo?.number == null)) {
|
||||
validationType = ValidationType.missing;
|
||||
} else if (installedVersions.keys.any((String binary) =>
|
||||
installedVersions[binary].number < _requiredBinaryVersions[binary])) {
|
||||
installedVersions[binary]!.number! < _requiredBinaryVersions[binary]!)) {
|
||||
validationType = ValidationType.partial;
|
||||
}
|
||||
|
||||
// Message for Clang.
|
||||
{
|
||||
final _VersionInfo version = installedVersions[kClangBinary];
|
||||
if (version == null) {
|
||||
final _VersionInfo? version = installedVersions[kClangBinary];
|
||||
if (version == null || version.number == null) {
|
||||
messages.add(ValidationMessage.error(_userMessages.clangMissing));
|
||||
} else {
|
||||
assert(_requiredBinaryVersions.containsKey(kClangBinary));
|
||||
messages.add(ValidationMessage(version.description));
|
||||
final Version requiredVersion = _requiredBinaryVersions[kClangBinary];
|
||||
if (version.number < requiredVersion) {
|
||||
final Version requiredVersion = _requiredBinaryVersions[kClangBinary]!;
|
||||
if (version.number! < requiredVersion) {
|
||||
messages.add(ValidationMessage.error(_userMessages.clangTooOld(requiredVersion.toString())));
|
||||
}
|
||||
}
|
||||
@ -95,13 +93,14 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
|
||||
// Message for CMake.
|
||||
{
|
||||
final _VersionInfo version = installedVersions[kCmakeBinary];
|
||||
if (version == null) {
|
||||
final _VersionInfo? version = installedVersions[kCmakeBinary];
|
||||
if (version == null || version.number == null) {
|
||||
messages.add(ValidationMessage.error(_userMessages.cmakeMissing));
|
||||
} else {
|
||||
assert(_requiredBinaryVersions.containsKey(kCmakeBinary));
|
||||
messages.add(ValidationMessage(version.description));
|
||||
final Version requiredVersion = _requiredBinaryVersions[kCmakeBinary];
|
||||
if (version.number < requiredVersion) {
|
||||
final Version requiredVersion = _requiredBinaryVersions[kCmakeBinary]!;
|
||||
if (version.number! < requiredVersion) {
|
||||
messages.add(ValidationMessage.error(_userMessages.cmakeTooOld(requiredVersion.toString())));
|
||||
}
|
||||
}
|
||||
@ -109,14 +108,15 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
|
||||
// Message for ninja.
|
||||
{
|
||||
final _VersionInfo version = installedVersions[kNinjaBinary];
|
||||
if (version == null) {
|
||||
final _VersionInfo? version = installedVersions[kNinjaBinary];
|
||||
if (version == null || version.number == null) {
|
||||
messages.add(ValidationMessage.error(_userMessages.ninjaMissing));
|
||||
} else {
|
||||
assert(_requiredBinaryVersions.containsKey(kNinjaBinary));
|
||||
// The full version description is just the number, so add context.
|
||||
messages.add(ValidationMessage(_userMessages.ninjaVersion(version.description)));
|
||||
final Version requiredVersion = _requiredBinaryVersions[kNinjaBinary];
|
||||
if (version.number < requiredVersion) {
|
||||
final Version requiredVersion = _requiredBinaryVersions[kNinjaBinary]!;
|
||||
if (version.number! < requiredVersion) {
|
||||
messages.add(ValidationMessage.error(_userMessages.ninjaTooOld(requiredVersion.toString())));
|
||||
}
|
||||
}
|
||||
@ -124,14 +124,15 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
|
||||
// Message for pkg-config.
|
||||
{
|
||||
final _VersionInfo version = installedVersions[kPkgConfigBinary];
|
||||
if (version == null) {
|
||||
final _VersionInfo? version = installedVersions[kPkgConfigBinary];
|
||||
if (version == null || version.number == null) {
|
||||
messages.add(ValidationMessage.error(_userMessages.pkgConfigMissing));
|
||||
} else {
|
||||
assert(_requiredBinaryVersions.containsKey(kPkgConfigBinary));
|
||||
// The full version description is just the number, so add context.
|
||||
messages.add(ValidationMessage(_userMessages.pkgConfigVersion(version.description)));
|
||||
final Version requiredVersion = _requiredBinaryVersions[kPkgConfigBinary];
|
||||
if (version.number < requiredVersion) {
|
||||
final Version requiredVersion = _requiredBinaryVersions[kPkgConfigBinary]!;
|
||||
if (version.number! < requiredVersion) {
|
||||
messages.add(ValidationMessage.error(_userMessages.pkgConfigTooOld(requiredVersion.toString())));
|
||||
}
|
||||
}
|
||||
@ -159,8 +160,8 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
///
|
||||
/// Requires tha [binary] take a '--version' flag, and print a version of the
|
||||
/// form x.y.z somewhere on the first line of output.
|
||||
Future<_VersionInfo> _getBinaryVersion(String binary) async {
|
||||
ProcessResult result;
|
||||
Future<_VersionInfo?> _getBinaryVersion(String binary) async {
|
||||
ProcessResult? result;
|
||||
try {
|
||||
result = await _processManager.run(<String>[
|
||||
binary,
|
||||
@ -178,7 +179,7 @@ class LinuxDoctorValidator extends DoctorValidator {
|
||||
|
||||
/// Checks that [library] is available via pkg-config.
|
||||
Future<bool> _libraryIsPresent(String library) async {
|
||||
ProcessResult result;
|
||||
ProcessResult? result;
|
||||
try {
|
||||
result = await _processManager.run(<String>[
|
||||
'pkg-config',
|
||||
|
||||
@ -236,6 +236,30 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when CMake version is unparsable', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
_cmakePresentCommand('bogus'),
|
||||
_ninjaPresentCommand('1.10.0'),
|
||||
_pkgConfigPresentCommand('0.29'),
|
||||
..._gtkLibrariesPresentCommands(),
|
||||
]);
|
||||
final UserMessages userMessages = UserMessages();
|
||||
final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
|
||||
processManager: processManager,
|
||||
userMessages: userMessages,
|
||||
);
|
||||
final ValidationResult result = await linuxDoctorValidator.validate();
|
||||
|
||||
expect(result.type, ValidationType.missing);
|
||||
expect(result.messages, <ValidationMessage>[
|
||||
const ValidationMessage('clang version 4.0.1-6+build1'),
|
||||
ValidationMessage.error(userMessages.cmakeMissing),
|
||||
const ValidationMessage('ninja version 1.10.0'),
|
||||
const ValidationMessage('pkg-config version 0.29'),
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when clang++ is not available', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_missingBinaryCommand('clang++'),
|
||||
@ -260,6 +284,30 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when clang++ version is unparsable', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('bogus'),
|
||||
_cmakePresentCommand('3.16.3'),
|
||||
_ninjaPresentCommand('1.10.0'),
|
||||
_pkgConfigPresentCommand('0.29'),
|
||||
..._gtkLibrariesPresentCommands(),
|
||||
]);
|
||||
final UserMessages userMessages = UserMessages();
|
||||
final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
|
||||
processManager: processManager,
|
||||
userMessages: userMessages,
|
||||
);
|
||||
final ValidationResult result = await linuxDoctorValidator.validate();
|
||||
|
||||
expect(result.type, ValidationType.missing);
|
||||
expect(result.messages, <ValidationMessage>[
|
||||
ValidationMessage.error(userMessages.clangMissing),
|
||||
const ValidationMessage('cmake version 3.16.3'),
|
||||
const ValidationMessage('ninja version 1.10.0'),
|
||||
const ValidationMessage('pkg-config version 0.29'),
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when ninja is not available', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
@ -284,6 +332,30 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when ninja version is unparsable', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
_cmakePresentCommand('3.16.3'),
|
||||
_ninjaPresentCommand('bogus'),
|
||||
_pkgConfigPresentCommand('0.29'),
|
||||
..._gtkLibrariesPresentCommands(),
|
||||
]);
|
||||
final UserMessages userMessages = UserMessages();
|
||||
final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
|
||||
processManager: processManager,
|
||||
userMessages: userMessages,
|
||||
);
|
||||
final ValidationResult result = await linuxDoctorValidator.validate();
|
||||
|
||||
expect(result.type, ValidationType.missing);
|
||||
expect(result.messages, <ValidationMessage>[
|
||||
const ValidationMessage('clang version 4.0.1-6+build1'),
|
||||
const ValidationMessage('cmake version 3.16.3'),
|
||||
ValidationMessage.error(userMessages.ninjaMissing),
|
||||
const ValidationMessage('pkg-config version 0.29'),
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when pkg-config is not available', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
@ -308,6 +380,30 @@ void main() {
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when pkg-config version is unparsable', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
_cmakePresentCommand('3.16.3'),
|
||||
_ninjaPresentCommand('1.10.0'),
|
||||
_pkgConfigPresentCommand('bogus'),
|
||||
..._gtkLibrariesPresentCommands(),
|
||||
]);
|
||||
final UserMessages userMessages = UserMessages();
|
||||
final DoctorValidator linuxDoctorValidator = LinuxDoctorValidator(
|
||||
processManager: processManager,
|
||||
userMessages: userMessages,
|
||||
);
|
||||
final ValidationResult result = await linuxDoctorValidator.validate();
|
||||
|
||||
expect(result.type, ValidationType.missing);
|
||||
expect(result.messages, <ValidationMessage>[
|
||||
const ValidationMessage('clang version 4.0.1-6+build1'),
|
||||
const ValidationMessage('cmake version 3.16.3'),
|
||||
const ValidationMessage('ninja version 1.10.0'),
|
||||
ValidationMessage.error(userMessages.pkgConfigMissing),
|
||||
]);
|
||||
});
|
||||
|
||||
testWithoutContext('Missing validation when GTK libraries are not available', () async {
|
||||
final ProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
|
||||
_clangPresentCommand('4.0.1'),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user