runDoctorChecks function
List<DoctorCheck>
runDoctorChecks({
- ProcessProbe probe = _probe,
- String? locate(
- ExternalTool tool
- String? dartVersion,
- Directory? project,
Every check, in the order the report prints them.
probe runs a program; locate finds an external tool. Both are
parameters so a test can answer for a machine it is not running on.
project, when it has a pubspec.yaml, adds one more line: its data
files below the version this build writes, as a note, since the engine
still reads them.
Implementation
List<DoctorCheck> runDoctorChecks({
ProcessProbe probe = _probe,
String? Function(ExternalTool tool)? locate,
String? dartVersion,
Directory? project,
}) {
final find = locate ?? (ExternalTool t) => t.locate();
final checks = <DoctorCheck>[];
final dart = dartVersion ?? Platform.version.split(' ').first;
checks.add(
_versionCheck('Dart', dart, dartFloor, dartTested, required: true),
);
final machine = probe(
Platform.isWindows ? 'flutter.bat' : 'flutter',
const <String>['--version', '--machine'],
);
String? flutterRoot;
String? flutterDart;
if (machine == null) {
checks.add(
const DoctorCheck(
'Flutter',
DoctorStatus.missing,
'not found on PATH',
fix:
'a game needs Flutter $flutterFloor or later (https://docs.flutter.dev/get-started/install); '
'the plain Dart packages and this command do not',
),
);
} else {
final start = machine.indexOf('{');
final Object? info = start < 0 ? null : _tryJson(machine.substring(start));
final map = info is Map ? info : const <String, Object?>{};
final version = '${map['frameworkVersion'] ?? '?'}';
flutterRoot = map['flutterRoot'] as String?;
final channel = map['channel'] as String?;
checks.add(
_versionCheck(
'Flutter',
version,
flutterFloor,
flutterTested,
required: true,
extra: channel == null ? '' : ', $channel channel',
),
);
if (map['dartSdkVersion'] case final String bundled) {
flutterDart = bundled.split(' ').first;
checks.add(
_versionCheck(
"Flutter's Dart",
bundled,
dartFloor,
dartTested,
required: true,
),
);
}
}
// impellerc: what builds the Impeller shader bundles from source.
final impellerc = flutterRoot == null ? null : _impellerc(flutterRoot);
checks.add(
impellerc == null
? const DoctorCheck(
'impellerc',
DoctorStatus.missing,
'not found in the Flutter SDK\'s engine artifacts',
fix:
'run `flutter precache`; needed only to build shader bundles from a checkout',
)
: DoctorCheck('impellerc', DoctorStatus.ok, impellerc),
);
for (final (name, purpose, install) in const <(String, String, String)>[
(
'glslangValidator',
'the WebGPU section of a material bundle',
'install the Vulkan SDK or `brew install glslang`',
),
(
'naga',
'the WebGPU section of a material bundle',
'`cargo install naga-cli`',
),
]) {
final path = findOnPath(name);
checks.add(
path == null
? DoctorCheck(
name,
DoctorStatus.missing,
'not on PATH: materials build without $purpose',
fix: install,
)
: DoctorCheck(name, DoctorStatus.ok, path),
);
}
for (final tool in externalTools) {
final path = find(tool);
checks.add(
path == null
? DoctorCheck(
tool.name,
DoctorStatus.missing,
'not found: flutter3d convert cannot use it (${tool.purpose})',
fix: tool.install,
)
: DoctorCheck(tool.name, DoctorStatus.ok, '$path (${tool.purpose})'),
);
}
if (project != null && File('${project.path}/pubspec.yaml').existsSync()) {
checks.addAll(
projectShaderChecks(
project,
dart: flutterDart ?? dart,
engineRevision: flutterRoot == null
? null
: engineRevisionAt(flutterRoot),
),
);
checks
..addAll(projectAssetChecks(project))
..addAll(projectPlatformChecks(project));
final behind = dataFilesBehind(project);
checks.add(
behind.isEmpty
? const DoctorCheck(
'Data files',
DoctorStatus.ok,
'every one at the version this build writes',
)
: DoctorCheck(
'Data files',
DoctorStatus.note,
'${behind.length} below the version this build writes '
'(the engine still reads them): ${behind.join(', ')}',
fix: 'run `flutter3d migrate --data .` to lift them on disk',
),
);
}
return checks;
}