diff --git a/packages/shorebird_cli/lib/src/shorebird_flutter.dart b/packages/shorebird_cli/lib/src/shorebird_flutter.dart index 06b10104a..d72381adb 100644 --- a/packages/shorebird_cli/lib/src/shorebird_flutter.dart +++ b/packages/shorebird_cli/lib/src/shorebird_flutter.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:io'; import 'package:path/path.dart' as p; @@ -60,4 +61,15 @@ class ShorebirdFlutter { ); return status.isEmpty; } + + Future> getVersions({String? revision}) async { + final result = await git.forEachRef( + format: '%(refname:short)', + pattern: 'refs/remotes/origin/flutter_release/*', + directory: _workingDirectory(revision: revision), + ); + return LineSplitter.split(result) + .map((e) => e.replaceFirst('origin/flutter_release/', '')) + .toList(); + } } diff --git a/packages/shorebird_cli/test/src/shorebird_flutter_manager_test.dart b/packages/shorebird_cli/test/src/shorebird_flutter_test.dart similarity index 80% rename from packages/shorebird_cli/test/src/shorebird_flutter_manager_test.dart rename to packages/shorebird_cli/test/src/shorebird_flutter_test.dart index a221f0747..e22135582 100644 --- a/packages/shorebird_cli/test/src/shorebird_flutter_manager_test.dart +++ b/packages/shorebird_cli/test/src/shorebird_flutter_test.dart @@ -68,6 +68,79 @@ void main() { when(() => shorebirdEnv.flutterRevision).thenReturn(flutterRevision); }); + group('getVersions', () { + const format = '%(refname:short)'; + const pattern = 'refs/remotes/origin/flutter_release/*'; + test('returns a list of versions', () async { + const versions = [ + '3.10.0', + '3.10.1', + '3.10.2', + '3.10.3', + '3.10.4', + '3.10.5', + '3.10.6', + ]; + const output = ''' +origin/flutter_release/3.10.0 +origin/flutter_release/3.10.1 +origin/flutter_release/3.10.2 +origin/flutter_release/3.10.3 +origin/flutter_release/3.10.4 +origin/flutter_release/3.10.5 +origin/flutter_release/3.10.6'''; + when( + () => git.forEachRef( + directory: any(named: 'directory'), + format: any(named: 'format'), + pattern: any(named: 'pattern'), + ), + ).thenAnswer((_) async => output); + + await expectLater( + runWithOverrides(shorebirdFlutterManager.getVersions), + completion(equals(versions)), + ); + verify( + () => git.forEachRef( + directory: p.join(flutterDirectory.parent.path, flutterRevision), + format: format, + pattern: pattern, + ), + ).called(1); + }); + + test('throws ProcessException when git command exits non-zero code', + () async { + const errorMessage = 'oh no!'; + when( + () => git.forEachRef( + directory: any(named: 'directory'), + format: any(named: 'format'), + pattern: any(named: 'pattern'), + ), + ).thenThrow( + ProcessException( + 'git', + ['for-each-ref', '--format', format, pattern], + errorMessage, + ExitCode.software.code, + ), + ); + + expect( + runWithOverrides(shorebirdFlutterManager.getVersions), + throwsA( + isA().having( + (e) => e.message, + 'message', + errorMessage, + ), + ), + ); + }); + }); + group('installRevision', () { const revision = 'test-revision'; test('does nothing if the revision is already installed', () async { diff --git a/packages/shorebird_cli/test/src/shorebird_version_manager_test.dart b/packages/shorebird_cli/test/src/shorebird_version_test.dart similarity index 100% rename from packages/shorebird_cli/test/src/shorebird_version_manager_test.dart rename to packages/shorebird_cli/test/src/shorebird_version_test.dart