From a2f5364dc07e4f0e9ccae0b0a3f85b65d09b9bf0 Mon Sep 17 00:00:00 2001 From: Christopher Fujino Date: Thu, 14 May 2020 11:03:07 -0700 Subject: [PATCH] throw more specific toolexit when git fails during upgrade (#57162) --- .../lib/src/commands/upgrade.dart | 23 ++++++-- .../permeable/upgrade_test.dart | 56 ++++++++++++++++++- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 21d156936b4..3c0b1826519 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -219,12 +219,23 @@ class UpgradeCommandRunner { workingDirectory: workingDirectory, ); revision = result.stdout.trim(); - } on Exception { - throwToolExit( - 'Unable to upgrade Flutter: no origin repository configured. ' - "Run 'git remote add origin " - "https://github.com/flutter/flutter' in $workingDirectory", - ); + } on Exception catch (e) { + final String errorString = e.toString(); + if (errorString.contains('fatal: HEAD does not point to a branch')) { + throwToolExit( + 'You are not currently on a release branch. Use git to ' + 'check out an official branch (\'stable\', \'beta\', \'dev\', or \'master\') ' + 'and retry, for example:\n' + ' git checkout stable' + ); + } else if (errorString.contains('fatal: no upstream configured for branch')) { + throwToolExit( + 'Unable to upgrade Flutter: no origin repository configured. ' + 'Run \'git remote add origin ' + 'https://github.com/flutter/flutter\' in $workingDirectory'); + } else { + throwToolExit(errorString); + } } return revision; } diff --git a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart index 7943ec3fc76..3fce71866a5 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/upgrade_test.dart @@ -160,7 +160,7 @@ void main() { Platform: () => fakePlatform, }); - testUsingContext('fetchRemoteRevision', () async { + testUsingContext('fetchRemoteRevision returns revision if git succeeds', () async { const String revision = 'abc123'; when(processManager.run( ['git', 'fetch', '--tags'], @@ -185,6 +185,60 @@ void main() { Platform: () => fakePlatform, }); + testUsingContext('fetchRemoteRevision throws toolExit if HEAD is detached', () async { + when(processManager.run( + ['git', 'fetch', '--tags'], + environment:anyNamed('environment'), + workingDirectory: anyNamed('workingDirectory')), + ).thenAnswer((Invocation invocation) async { + return FakeProcessResult()..exitCode = 0; + }); + when(processManager.run( + ['git', 'rev-parse', '--verify', '@{u}'], + environment:anyNamed('environment'), + workingDirectory: anyNamed('workingDirectory')), + ).thenThrow(const ProcessException( + 'git', + ['rev-parse', '--verify', '@{u}'], + 'fatal: HEAD does not point to a branch', + )); + expect( + () async => await realCommandRunner.fetchRemoteRevision(), + throwsToolExit(message: 'You are not currently on a release branch.'), + ); + }, overrides: { + ProcessManager: () => processManager, + Platform: () => fakePlatform, + }); + + testUsingContext('fetchRemoteRevision throws toolExit if no upstream configured', () async { + when(processManager.run( + ['git', 'fetch', '--tags'], + environment:anyNamed('environment'), + workingDirectory: anyNamed('workingDirectory')), + ).thenAnswer((Invocation invocation) async { + return FakeProcessResult()..exitCode = 0; + }); + when(processManager.run( + ['git', 'rev-parse', '--verify', '@{u}'], + environment:anyNamed('environment'), + workingDirectory: anyNamed('workingDirectory')), + ).thenThrow(const ProcessException( + 'git', + ['rev-parse', '--verify', '@{u}'], + 'fatal: no upstream configured for branch', + )); + expect( + () async => await realCommandRunner.fetchRemoteRevision(), + throwsToolExit( + message: 'Unable to upgrade Flutter: no origin repository configured\.', + ), + ); + }, overrides: { + ProcessManager: () => processManager, + Platform: () => fakePlatform, + }); + testUsingContext('git exception during attemptReset throwsToolExit', () async { const String revision = 'abc123'; const String errorMessage = 'fatal: Could not parse object ´$revision´';