From 52e4214dbb67e9b9e02134be1951c6b1ab5e6bae Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Wed, 6 Mar 2019 09:14:39 -0800 Subject: [PATCH] Fix crash on flutter update-packages (#28922) When running git update-packages, if the goldens repo is dirty, the flutter tool currently crashes and logs the failure from git pull. This adds a check for a dirty git client and emits a friendlier error message in the case where it's not clean, and avoid the crash by catching the NonZeroExitCode exception and rethrowing as toolExit instead. Fixes: https://github.com/flutter/flutter/issues/28915 --- .../flutter_goldens_client/lib/client.dart | 20 ++++++++++++++++++- .../lib/src/commands/update_packages.dart | 8 ++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/flutter_goldens_client/lib/client.dart b/packages/flutter_goldens_client/lib/client.dart index 961b383097a..6c290ed7939 100644 --- a/packages/flutter_goldens_client/lib/client.dart +++ b/packages/flutter_goldens_client/lib/client.dart @@ -80,6 +80,7 @@ class GoldensClient { if (currentCommit == null) { await _initRepository(); } + await _checkCanSync(); await _syncTo(goldensCommit); } } finally { @@ -117,6 +118,23 @@ class GoldensClient { ); } + Future _checkCanSync() async { + final io.ProcessResult result = await process.run( + ['git', 'status', '--porcelain'], + workingDirectory: repositoryRoot.path, + ); + if (result.stdout.trim().isNotEmpty) { + final StringBuffer buf = StringBuffer(); + buf + ..writeln('flutter_goldens git checkout at ${repositoryRoot.path} has local changes and cannot be synced.') + ..writeln('To reset your client to a clean state, and lose any local golden test changes:') + ..writeln('cd ${repositoryRoot.path}') + ..writeln('git reset --hard HEAD') + ..writeln('git clean -x -d -f -f'); + throw NonZeroExitCode(1, buf.toString()); + } + } + Future _syncTo(String commit) async { await _runCommands( [ @@ -163,7 +181,7 @@ class NonZeroExitCode implements Exception { /// The first argument must be non-zero. const NonZeroExitCode(this.exitCode, this.stderr) : assert(exitCode != 0); - /// The code that the process will signal to th eoperating system. + /// The code that the process will signal to the operating system. /// /// By definiton, this is not zero. final int exitCode; diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart index 9eb7ce8b8c5..76de4327389 100644 --- a/packages/flutter_tools/lib/src/commands/update_packages.dart +++ b/packages/flutter_tools/lib/src/commands/update_packages.dart @@ -132,8 +132,12 @@ class UpdatePackagesCommand extends FlutterCommand { // package that is in the goldens repository. We need to make sure that the goldens // repository is cloned locally before we verify or update pubspecs. printStatus('Cloning goldens repository...'); - final GoldensClient goldensClient = GoldensClient(); - await goldensClient.prepare(); + try { + final GoldensClient goldensClient = GoldensClient(); + await goldensClient.prepare(); + } on NonZeroExitCode catch (e) { + throwToolExit(e.stderr, exitCode: e.exitCode); + } if (isVerifyOnly) { bool needsUpdate = false;