Unverified Commit e8ec8a0d authored by Christopher Fujino's avatar Christopher Fujino Committed by GitHub

[flutter_tools] Catch lack of flutter tools source missing (#93168)

parent d21bb197
......@@ -54,6 +54,7 @@ import 'src/globals.dart' as globals;
// Files in `isolated` are intentionally excluded from google3 tooling.
import 'src/isolated/mustache_template.dart';
import 'src/isolated/resident_web_runner.dart';
import 'src/pre_run_validator.dart';
import 'src/resident_runner.dart';
import 'src/runner/flutter_command.dart';
import 'src/web/web_runner.dart';
......@@ -126,6 +127,7 @@ Future<void> main(List<String> args) async {
windows: globals.platform.isWindows,
);
},
PreRunValidator: () => PreRunValidator(fileSystem: globals.fs),
},
);
}
......
......@@ -39,6 +39,7 @@ import 'macos/cocoapods_validator.dart';
import 'macos/xcdevice.dart';
import 'macos/xcode.dart';
import 'persistent_tool_state.dart';
import 'pre_run_validator.dart';
import 'project.dart';
import 'reporting/crash_reporting.dart';
import 'reporting/reporting.dart';
......@@ -257,3 +258,5 @@ FlutterProjectFactory get projectFactory {
}
CustomDevicesConfig get customDevicesConfig => context.get<CustomDevicesConfig>()!;
PreRunValidator get preRunValidator => context.get<PreRunValidator>() ?? const NoOpPreRunValidator();
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'base/common.dart';
import 'base/file_system.dart';
import 'cache.dart';
/// A validator that runs before the tool runs any command.
abstract class PreRunValidator {
factory PreRunValidator({
required FileSystem fileSystem,
}) => _DefaultPreRunValidator(fileSystem: fileSystem);
void validate();
}
class _DefaultPreRunValidator implements PreRunValidator {
_DefaultPreRunValidator({
required this.fileSystem,
});
final FileSystem fileSystem;
late final Directory _toolsDir = fileSystem.directory(
fileSystem.path.join(Cache.flutterRoot!, 'packages', 'flutter_tools'),
);
@override
void validate() {
// If a user downloads the Flutter SDK via a pre-built archive and there is
// an error during extraction, the user could have a valid Dart snapshot of
// the tool but not the source directory. We still need the source, so
// validate the source directory exists and toolExit if not.
if (!_toolsDir.existsSync()) {
throwToolExit(
'Flutter SDK installation appears corrupted: expected to find the '
'directory ${_toolsDir.path} but it does not exist! Please go to '
'https://flutter.dev/setup for instructions on how to re-install '
'Flutter.',
);
}
}
}
class NoOpPreRunValidator implements PreRunValidator {
const NoOpPreRunValidator();
@override
void validate() {}
}
......@@ -1251,6 +1251,7 @@ abstract class FlutterCommand extends Command<void> {
/// rather than calling [runCommand] directly.
@mustCallSuper
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
globals.preRunValidator.validate();
// Populate the cache. We call this before pub get below so that the
// sky_engine package is available in the flutter cache for pub to find.
if (shouldUpdateCache) {
......
......@@ -31,6 +31,8 @@ void main() {
expect(fakeStdio.writtenToStdout.length, equals(1));
expect(fakeStdio.writtenToStdout.first, contains('__flutter_completion'));
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => fakeStdio,
});
......@@ -40,6 +42,8 @@ void main() {
expect(fakeStdio.writtenToStdout.length, equals(1));
expect(fakeStdio.writtenToStdout.first, contains('__flutter_completion'));
}, overrides: <Type, Generator>{
FileSystem: () => MemoryFileSystem.test(),
ProcessManager: () => FakeProcessManager.any(),
Stdio: () => fakeStdio,
});
......
......@@ -449,6 +449,7 @@ void main() {
testUsingContext('test without bot', () async {
Cache.flutterRoot = '';
globals.fs.directory('/packages/flutter_tools').createSync(recursive: true);
globals.fs.file('pubspec.yaml').createSync();
processManager.addCommand(
const FakeCommand(command: <String>['/bin/cache/dart-sdk/bin/dart', '__deprecated_pub', 'run', 'test']),
......
......@@ -162,6 +162,7 @@ void test(String description, FutureOr<void> Function() body, {
addTearDown(() async {
await globals.localFileSystem.dispose();
});
return body();
},
skip: skip,
......
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