Merge pull request #1483 from collinjackson/engine_safety
In addition to checking for the existence of the engine, ensure that it’s the correct version
diff --git a/bin/flutter b/bin/flutter
index 3803576..1ec69b6 100755
--- a/bin/flutter
+++ b/bin/flutter
@@ -7,6 +7,7 @@
export FLUTTER_ROOT=$(dirname $(dirname "${BASH_SOURCE[0]}"))
FLUTTER_TOOLS_DIR="$FLUTTER_ROOT/packages/flutter_tools"
+FLUTTER_DIR="$FLUTTER_ROOT/packages/flutter"
SNAPSHOT_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.snapshot"
STAMP_PATH="$FLUTTER_ROOT/bin/cache/flutter_tools.stamp"
SCRIPT_PATH="$FLUTTER_TOOLS_DIR/bin/flutter_tools.dart"
@@ -18,6 +19,7 @@
if [ ! -f "$SNAPSHOT_PATH" ] || [ ! -f "$STAMP_PATH" ] || [ `cat "$STAMP_PATH"` != "$REVISION" ] || [ "$FLUTTER_TOOLS_DIR/pubspec.yaml" -nt "$FLUTTER_TOOLS_DIR/pubspec.lock" ]; then
echo Updating flutter tool...
(cd "$FLUTTER_TOOLS_DIR"; pub get > /dev/null)
+ (cd "$FLUTTER_DIR"; pub get > /dev/null) # Allows us to check if sky_engine's REVISION is correct
$DART --snapshot="$SNAPSHOT_PATH" --package-root="$FLUTTER_TOOLS_DIR/packages" "$SCRIPT_PATH"
echo -n $REVISION > "$STAMP_PATH"
fi
diff --git a/bin/flutter.bat b/bin/flutter.bat
index 4d8580e..d047aa6 100644
--- a/bin/flutter.bat
+++ b/bin/flutter.bat
@@ -6,6 +6,7 @@
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%i IN ("%~dp0..") DO SET "flutter_root=%%~fi" REM Get the parent directory
SET flutter_tools_dir=%flutter_root%\packages\flutter_tools
+SET flutter_dir=%flutter_root%\packages\flutter
SET snapshot_path=%flutter_root%\bin\cache\flutter_tools.snapshot
SET stamp_path=%flutter_root%\bin\cache\flutter_tools.stamp
SET script_path=%flutter_tools_dir%\bin\flutter_tools.dart
@@ -33,6 +34,9 @@
CD "%flutter_tools_dir%"
ECHO Updating flutter tool...
CALL pub.bat get
+CD "%flutter_dir"
+REM Allows us to check if sky_engine's REVISION is correct
+CALL pub.bat get
CD "%flutter_root%"
CALL %dart% --snapshot="%snapshot_path%" --package-root="%flutter_tools_dir%\packages" "%script_path%"
<nul SET /p=%revision%> "%stamp_path%"
diff --git a/packages/flutter_tools/lib/src/artifacts.dart b/packages/flutter_tools/lib/src/artifacts.dart
index 5af0f3c..123b752 100644
--- a/packages/flutter_tools/lib/src/artifacts.dart
+++ b/packages/flutter_tools/lib/src/artifacts.dart
@@ -192,12 +192,15 @@
}
}
- static void ensureHasSkyEnginePackage() {
- Directory skyEnginePackage = new Directory(path.join(packageRoot, 'sky_engine'));
- if (!skyEnginePackage.existsSync()) {
+ static void validateSkyEnginePackage() {
+ if (engineRevision == null) {
printError("Cannot locate the sky_engine package; did you include 'flutter' in your pubspec.yaml file?");
throw new ProcessExit(2);
}
+ if (engineRevision != expectedEngineRevision) {
+ printError("Error: incompatible sky_engine package; please run 'pub get' to get the correct one.\n");
+ throw new ProcessExit(2);
+ }
}
static String _engineRevision;
@@ -211,6 +214,18 @@
return _engineRevision;
}
+ static String _expectedEngineRevision;
+
+ static String get expectedEngineRevision {
+ if (_expectedEngineRevision == null) {
+ // TODO(jackson): Parse the .packages file and use the path from there instead
+ File revisionFile = new File(path.join(flutterRoot, 'packages', 'flutter', 'packages', 'sky_engine', 'REVISION'));
+ if (revisionFile.existsSync())
+ _expectedEngineRevision = revisionFile.readAsStringSync();
+ }
+ return _expectedEngineRevision;
+ }
+
static String getCloudStorageBaseUrl(String platform) {
return _getCloudStorageBaseUrl(
platform: platform,
@@ -295,7 +310,7 @@
}
static Directory _getCacheDirForPlatform(String platform) {
- ensureHasSkyEnginePackage();
+ validateSkyEnginePackage();
Directory baseDir = _getBaseCacheDir();
// TODO(jamesr): Add support for more configurations.
String config = 'Release';
diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart
index 4ca8119..127391b 100644
--- a/packages/flutter_tools/lib/src/commands/test.dart
+++ b/packages/flutter_tools/lib/src/commands/test.dart
@@ -20,13 +20,18 @@
bool get requiresProjectRoot => false;
- String get projectRootValidationErrorMessage {
- return 'Error: No pubspec.yaml file found.\n'
- 'If you wish to run the tests in the Flutter repository\'s \'flutter\' package,\n'
- 'pass --flutter-repo before any test paths. Otherwise, run this command from the\n'
- 'root of your project. Test files must be called *_test.dart and must reside in\n'
- 'the package\'s \'test\' directory (or one of its subdirectories).';
- }
+ @override
+ Validator projectRootValidator = () {
+ if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
+ printError('Error: No pubspec.yaml file found.\n'
+ 'If you wish to run the tests in the Flutter repository\'s \'flutter\' package,\n'
+ 'pass --flutter-repo before any test paths. Otherwise, run this command from the\n'
+ 'root of your project. Test files must be called *_test.dart and must reside in\n'
+ 'the package\'s \'test\' directory (or one of its subdirectories).');
+ return false;
+ }
+ return true;
+ };
Future<String> _getShellPath(BuildConfiguration config) async {
if (config.type == BuildType.prebuilt) {
@@ -80,7 +85,7 @@
List<String> testArgs = argResults.rest.map((String testPath) => path.absolute(testPath)).toList();
final bool runFlutterTests = argResults['flutter-repo'];
- if (!runFlutterTests && !validateProjectRoot())
+ if (!runFlutterTests && !projectRootValidator())
return 1;
// If we're running the flutter tests, we want to use the packages directory
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index 5cab91d..4df0131 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -10,22 +10,19 @@
import '../application_package.dart';
import '../base/context.dart';
import '../build_configuration.dart';
+import '../artifacts.dart';
import '../device.dart';
import '../toolchain.dart';
import 'flutter_command_runner.dart';
+typedef bool Validator();
+
abstract class FlutterCommand extends Command {
FlutterCommandRunner get runner => super.runner;
/// Whether this command needs to be run from the root of a project.
bool get requiresProjectRoot => true;
- String get projectRootValidationErrorMessage {
- return 'Error: No pubspec.yaml file found.\n'
- 'This command should be run from the root of your Flutter project. Do not run\n'
- 'this command from the root of your git clone of Flutter.';
- }
-
List<BuildConfiguration> get buildConfigurations => runner.buildConfigurations;
Future downloadApplicationPackages() async {
@@ -49,18 +46,22 @@
}
Future<int> run() async {
- if (requiresProjectRoot && !validateProjectRoot())
+ if (requiresProjectRoot && !projectRootValidator())
return 1;
return await runInProject();
}
- bool validateProjectRoot() {
+ // This is a field so that you can modify the value for testing.
+ Validator projectRootValidator = () {
if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
- printError(projectRootValidationErrorMessage);
+ printError('Error: No pubspec.yaml file found.\n'
+ 'This command should be run from the root of your Flutter project.\n'
+ 'Do not run this command from the root of your git clone of Flutter.');
return false;
}
+ ArtifactStore.validateSkyEnginePackage();
return true;
- }
+ };
Future<int> runInProject();
diff --git a/packages/flutter_tools/test/src/mocks.dart b/packages/flutter_tools/test/src/mocks.dart
index 9af0463..99161d6 100644
--- a/packages/flutter_tools/test/src/mocks.dart
+++ b/packages/flutter_tools/test/src/mocks.dart
@@ -48,5 +48,6 @@
command
..applicationPackages = new MockApplicationPackageStore()
..toolchain = new MockToolchain()
- ..devices = new MockDeviceStore();
+ ..devices = new MockDeviceStore()
+ ..projectRootValidator = () => true;
}