Skip to content

Commit 5987ade

Browse files
committed
feat(cli): Add operations commands
Add commands for working with cloud operations.
1 parent 50dfc20 commit 5987ade

File tree

21 files changed

+411
-36
lines changed

21 files changed

+411
-36
lines changed

apps/cli/bin/celest.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:celest_cli/celest_cli.dart';
22
import 'package:celest_cli/src/commands/auth/auth_command.dart';
3+
import 'package:celest_cli/src/commands/cloud/operations/operations_command.dart';
34
import 'package:celest_cli/src/commands/cloud/organizations/organizations_command.dart';
45
import 'package:celest_cli/src/commands/cloud/project_environments/project_environments_command.dart';
56
import 'package:celest_cli/src/commands/cloud/projects/projects_command.dart';
@@ -32,7 +33,8 @@ void main(List<String> args) async {
3233
cli
3334
..addCommand(OrganizationsCommand())
3435
..addCommand(ProjectsCommand())
35-
..addCommand(ProjectEnvironmentsCommand());
36+
..addCommand(ProjectEnvironmentsCommand())
37+
..addCommand(OperationsCommand());
3638

3739
await cli.run(args);
3840
}

apps/cli/lib/src/commands/cloud/cloud_command.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ abstract base class CloudDeleteCommand<R extends GeneratedMessage>
484484

485485
extension type CloudCommandOptions(ArgResults argResults)
486486
implements ArgResults {
487+
String? get maybeResourceId => rest.elementAtOrNull(0);
488+
487489
String get resourceId {
488490
final id = rest.elementAtOrNull(0);
489491
if (id == null) {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:celest_cli/src/commands/cloud/cloud_command.dart';
2+
import 'package:celest_cli/src/context.dart' show cloud;
3+
import 'package:celest_cloud/celest_cloud.dart';
4+
5+
final class GetOperationCommand extends CloudGetCommand<Operation> {
6+
@override
7+
String get description => 'Gets an operation.';
8+
9+
@override
10+
String get name => 'get';
11+
12+
@override
13+
String get resourceType => 'Operation';
14+
15+
@override
16+
Operation createEmptyResource() => Operation();
17+
18+
@override
19+
Future<Operation?> callService() async {
20+
return cloud.operations.get(options.resourceId);
21+
}
22+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'package:celest_cli/src/commands/cloud/cloud_command.dart';
2+
import 'package:celest_cli/src/context.dart' show cloud;
3+
import 'package:celest_cloud/celest_cloud.dart';
4+
import 'package:celest_cloud_core/celest_cloud_core.dart';
5+
6+
final class ListOperationsCommand extends CloudListCommand<Operation> {
7+
@override
8+
String get description => 'Lists operations.';
9+
10+
@override
11+
String get name => 'list';
12+
13+
@override
14+
String get resourceType => 'Operation';
15+
16+
@override
17+
String? get parentResourceType => null;
18+
19+
@override
20+
Operation createEmptyResource() => Operation();
21+
22+
@override
23+
Future<CloudListResult<Operation>> callService() async {
24+
var filter = options.filter;
25+
if (options.maybeResourceId case final resourceId?) {
26+
final resourceName = ResourceName.parse(resourceId);
27+
final resourceFilter = 'resource_type = "${resourceName.uid.type}" AND '
28+
'resource_id = "${resourceName.uid.id}"';
29+
if (filter == null || filter.isEmpty) {
30+
filter = resourceFilter;
31+
} else {
32+
filter = '$filter AND $resourceFilter';
33+
}
34+
}
35+
final result = await cloud.operations.list(
36+
filter: filter,
37+
pageSize: options.pageSize,
38+
);
39+
return (
40+
items: result.operations,
41+
nextPageToken: result.hasNextPageToken() ? result.nextPageToken : null,
42+
);
43+
}
44+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'package:celest_cli/src/commands/celest_command.dart';
2+
import 'package:celest_cli/src/commands/cloud/operations/get_operation_command.dart';
3+
import 'package:celest_cli/src/commands/cloud/operations/list_operations_command.dart';
4+
5+
final class OperationsCommand extends CelestCommand {
6+
OperationsCommand() {
7+
addSubcommand(GetOperationCommand());
8+
addSubcommand(ListOperationsCommand());
9+
}
10+
11+
@override
12+
String get description => 'Manage Celest Cloud operations.';
13+
14+
@override
15+
String get name => 'operations';
16+
17+
@override
18+
String get category => 'Cloud';
19+
20+
@override
21+
bool get hidden => true;
22+
}

packages/celest_cloud/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
# 0.1.8
1+
# 0.1.8-wip
22

33
- feat: Add `ProjectAsset_Type.DART_EXECUTABLE`
4+
- fix: Incorrect route for `Operations.listOperations`
45

56
# 0.1.7
67

packages/celest_cloud/lib/src/cloud/operations/operations_protocol.http.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,14 @@ final class OperationsProtocolHttp
6565

6666
@override
6767
Future<ListOperationsResponse> list(ListOperationsRequest request) async {
68-
if (request.name == '') {
69-
throw ArgumentError.value(request.name, 'name', 'must not be empty');
68+
if (request.name.isNotEmpty) {
69+
throw ArgumentError.value(
70+
request.name,
71+
'name',
72+
'only empty name is allowed',
73+
);
7074
}
71-
final path = '/v1alpha1/${request.name}/operations';
75+
const path = '/v1alpha1/operations';
7276
final url = _baseUri.replace(
7377
path: path,
7478
queryParameters: {

packages/celest_cloud/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: celest_cloud
22
description: API contracts and Dart clients for the Celest Cloud platform.
3-
version: 0.1.8
3+
version: 0.1.8-wip
44
repository: https://github.com/celest-dev/celest
55

66
environment:

services/celest_cloud_core/lib/celest_cloud_core.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ library;
44
export 'src/model/filter.dart';
55
export 'src/model/order_by.dart';
66
export 'src/model/page_token.dart';
7-
export 'src/model/resource.dart';
7+
export 'src/model/resource_name.dart';
8+
export 'src/model/resource_table.dart';
9+
export 'src/model/resource_type.dart';

services/celest_cloud_core/lib/src/model/filter.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ sealed class Filter {
2828
String filter, {
2929
AnyDriftTable? table,
3030
}) {
31-
final parser = _createParser(table: table);
31+
final parser = _parserCache[table] ??= _createParser(table: table);
3232
final result = parser.parse(filter);
3333
switch (result) {
3434
case Success(:final value):
@@ -304,6 +304,8 @@ sealed class Filter {
304304
return expression.end();
305305
}
306306

307+
static final Map<AnyDriftTable?, Parser<Filter>> _parserCache = {};
308+
307309
/// Converts this filter to a [DriftFilter] function.
308310
DriftFilter<Tbl> toDrift<Tbl extends ResultSetImplementation<Tbl, Object?>>();
309311

0 commit comments

Comments
 (0)