diff --git a/packages/shorebird_cli/lib/src/command_runner.dart b/packages/shorebird_cli/lib/src/command_runner.dart index d9118ea8..f0cd739e 100644 --- a/packages/shorebird_cli/lib/src/command_runner.dart +++ b/packages/shorebird_cli/lib/src/command_runner.dart @@ -1,11 +1,11 @@ import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:cli_completion/cli_completion.dart'; -import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:pub_updater/pub_updater.dart'; import 'package:shorebird_cli/src/commands/commands.dart'; import 'package:shorebird_cli/src/version.dart'; +import 'package:shorebird_code_push_api_client/shorebird_code_push_api_client.dart'; const executableName = 'shorebird'; const packageName = 'shorebird_cli'; @@ -22,7 +22,7 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner { /// {@macro shorebird_cli_command_runner} ShorebirdCliCommandRunner({ Logger? logger, - http.Client? httpClient, + ShorebirdCodePushApiClient? codePushApiClient, PubUpdater? pubUpdater, }) : _logger = logger ?? Logger(), _pubUpdater = pubUpdater ?? PubUpdater(), @@ -41,7 +41,9 @@ class ShorebirdCliCommandRunner extends CompletionCommandRunner { ); // Add sub commands - addCommand(PublishCommand(logger: _logger, httpClient: httpClient)); + addCommand( + PublishCommand(logger: _logger, codePushApiClient: codePushApiClient), + ); addCommand(UpdateCommand(logger: _logger, pubUpdater: _pubUpdater)); } diff --git a/packages/shorebird_cli/lib/src/commands/publish_command.dart b/packages/shorebird_cli/lib/src/commands/publish_command.dart index 726a324e..fbeae08d 100644 --- a/packages/shorebird_cli/lib/src/commands/publish_command.dart +++ b/packages/shorebird_cli/lib/src/commands/publish_command.dart @@ -1,19 +1,21 @@ import 'dart:io'; import 'package:args/command_runner.dart'; -import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; +import 'package:shorebird_code_push_api_client/shorebird_code_push_api_client.dart'; -/// {@template sample_command} +/// {@template publish_command} /// -/// `shorebird sample` -/// A [Command] to exemplify a sub command +/// `shorebird publish ` +/// Publish new releases to the Shorebird CodePush server. /// {@endtemplate} class PublishCommand extends Command { - /// {@macro sample_command} - PublishCommand({required Logger logger, http.Client? httpClient}) - : _logger = logger, - _httpClient = httpClient ?? http.Client(); + /// {@macro publish_command} + PublishCommand({ + required Logger logger, + ShorebirdCodePushApiClient? codePushApiClient, + }) : _logger = logger, + _codePushApiClient = codePushApiClient ?? ShorebirdCodePushApiClient(); @override String get description => 'Publish an update.'; @@ -22,7 +24,7 @@ class PublishCommand extends Command { String get name => 'publish'; final Logger _logger; - final http.Client _httpClient; + final ShorebirdCodePushApiClient _codePushApiClient; @override Future run() async { @@ -37,23 +39,14 @@ class PublishCommand extends Command { return ExitCode.noInput.code; } - final request = http.MultipartRequest( - 'POST', - Uri.parse('http://localhost:8080/api/v1/releases'), - ); - final file = await http.MultipartFile.fromPath('file', artifact.path); - request.files.add(file); - final response = await _httpClient.send(request); - - if (response.statusCode != HttpStatus.created) { - _logger.err( - 'Failed to deploy: ${response.statusCode} ${response.reasonPhrase}', - ); + try { + await _codePushApiClient.createRelease(artifact.path); + } catch (error) { + _logger.err('Failed to deploy: $error'); return ExitCode.software.code; } _logger.success('Deployed ${artifact.path}!'); - return ExitCode.success.code; } } diff --git a/packages/shorebird_cli/pubspec.yaml b/packages/shorebird_cli/pubspec.yaml index 62341185..5a88de0d 100644 --- a/packages/shorebird_cli/pubspec.yaml +++ b/packages/shorebird_cli/pubspec.yaml @@ -2,16 +2,19 @@ name: shorebird_cli description: The shorebird command-line tool version: 0.0.1 +publish_to: none + environment: sdk: ">=2.19.0 <3.0.0" dependencies: args: ^2.3.1 cli_completion: ^0.2.0 - http: ^0.13.5 mason_logger: ^0.2.4 path: ^1.8.3 pub_updater: ^0.2.4 + shorebird_code_push_api_client: + path: ../shorebird_code_push_api_client dev_dependencies: build_runner: ^2.0.0 diff --git a/packages/shorebird_cli/test/src/commands/publish_command_test.dart b/packages/shorebird_cli/test/src/commands/publish_command_test.dart index 01854242..9488eb7b 100644 --- a/packages/shorebird_cli/test/src/commands/publish_command_test.dart +++ b/packages/shorebird_cli/test/src/commands/publish_command_test.dart @@ -1,34 +1,27 @@ -import 'dart:io'; - -import 'package:http/http.dart' as http; import 'package:mason_logger/mason_logger.dart'; import 'package:mocktail/mocktail.dart'; import 'package:path/path.dart' as p; import 'package:shorebird_cli/src/command_runner.dart'; +import 'package:shorebird_code_push_api_client/shorebird_code_push_api_client.dart'; import 'package:test/test.dart'; class _MockLogger extends Mock implements Logger {} -class _MockHttpClient extends Mock implements http.Client {} - -class _FakeBaseRequest extends Fake implements http.BaseRequest {} +class _MockShorebirdCodePushApiClient extends Mock + implements ShorebirdCodePushApiClient {} void main() { group('publish', () { late Logger logger; - late http.Client httpClient; + late _MockShorebirdCodePushApiClient codePushApiClient; late ShorebirdCliCommandRunner commandRunner; - setUpAll(() { - registerFallbackValue(_FakeBaseRequest()); - }); - setUp(() { logger = _MockLogger(); - httpClient = _MockHttpClient(); + codePushApiClient = _MockShorebirdCodePushApiClient(); commandRunner = ShorebirdCliCommandRunner( logger: logger, - httpClient: httpClient, + codePushApiClient: codePushApiClient, ); }); @@ -58,30 +51,18 @@ void main() { }); test('throws error when release fails.', () async { - const statusCode = HttpStatus.internalServerError; - const reasonPhrase = 'something went wrong'; - when(() => httpClient.send(any())).thenAnswer( - (_) async => http.StreamedResponse( - const Stream.empty(), - statusCode, - reasonPhrase: reasonPhrase, - ), - ); + const error = 'something went wrong'; + when(() => codePushApiClient.createRelease(any())).thenThrow(error); final release = p.join('test', 'fixtures', 'release.txt'); final exitCode = await commandRunner.run(['publish', release]); - verify( - () => logger.err('Failed to deploy: $statusCode $reasonPhrase'), - ).called(1); + verify(() => logger.err('Failed to deploy: $error')).called(1); expect(exitCode, ExitCode.software.code); }); test('succeeds when release is successful.', () async { - when(() => httpClient.send(any())).thenAnswer( - (_) async => http.StreamedResponse( - const Stream.empty(), - HttpStatus.created, - ), - ); + when( + () => codePushApiClient.createRelease(any()), + ).thenAnswer((_) async {}); final release = p.join('test', 'fixtures', 'release.txt'); final exitCode = await commandRunner.run(['publish', release]); verify(() => logger.success('Deployed $release!')).called(1);