Skip to content

Commit 2f08a2f

Browse files
authored
chore(cli): Minor fixes (#331)
- Fix control character handling on secret input - Make repos into extension types - Ensure cloud commands are try/catch'd
1 parent caa76b1 commit 2f08a2f

File tree

6 files changed

+41
-32
lines changed

6 files changed

+41
-32
lines changed

apps/cli/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.0.11-wip
2+
3+
- fix: Handle control characters when prompting for secrets
4+
-
5+
16
## 1.0.10
27

38
- feat: Add templates to `celest init`

apps/cli/lib/src/frontend/celest_frontend.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,8 +672,8 @@ final class CelestFrontend {
672672
/// Deploys the current project to Celest Cloud.
673673
Future<int> deploy({required bool migrateProject}) async {
674674
Progress? currentProgress;
675-
var projectId = await _loadProjectId();
676675
try {
676+
var projectId = await _loadProjectId();
677677
while (!stopped) {
678678
if (projectId != null) {
679679
currentProgress ??= cliLogger.progress('🔥 Warming up the engines');

apps/cli/lib/src/logging/cli_logger.dart

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:io';
22

33
import 'package:celest_cli/src/context.dart';
4+
import 'package:celest_cli/src/exceptions.dart';
45
import 'package:cli_util/cli_logging.dart' as cli_logging;
56
import 'package:dart_console/dart_console.dart';
67
import 'package:mason_logger/mason_logger.dart' as mason_logger;
@@ -192,33 +193,41 @@ class CliLogger implements mason_logger.Logger {
192193
}
193194

194195
String _readLineHiddenSync() {
195-
const lineFeed = '\n';
196-
const carriageReturn = '\r';
197-
final value = <String>[];
198-
199196
try {
200197
stdin
201198
..echoMode = false
202199
..lineMode = false;
203-
Key key;
204-
String char;
205-
do {
206-
key = console.readKey();
207-
char = key.char;
208-
if (char != lineFeed && char != carriageReturn) {
209-
final shouldDelete = key.isControl &&
210-
key.controlChar == ControlCharacter.delete &&
211-
value.isNotEmpty;
212-
shouldDelete ? value.removeLast() : value.add(char);
200+
201+
final value = <String>[];
202+
while (true) {
203+
final key = console.readKey();
204+
final char = key.char;
205+
if (key.isControl) {
206+
switch (key.controlChar) {
207+
case ControlCharacter.backspace:
208+
if (value.isNotEmpty) {
209+
value.removeLast();
210+
stdout.write('\b \b');
211+
}
212+
case ControlCharacter.enter:
213+
return value.join();
214+
case ControlCharacter.escape:
215+
return '';
216+
case ControlCharacter.ctrlC || ControlCharacter.ctrlD:
217+
throw const CancellationException('Cancelled input');
218+
default:
219+
break;
220+
}
221+
} else {
222+
stdout.write('*');
223+
value.add(char);
213224
}
214-
} while (char != lineFeed && char != carriageReturn);
225+
}
215226
} finally {
216227
stdin
217228
..lineMode = true
218229
..echoMode = true;
219230
}
220-
stdout.writeln();
221-
return value.join();
222231
}
223232
}
224233

apps/cli/lib/src/repositories/organization_repository.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import 'package:celest_cloud/celest_cloud.dart' as cloud;
22
import 'package:logging/logging.dart';
33

4-
final class OrganizationRepository {
5-
OrganizationRepository(this._cloud);
6-
7-
final cloud.CelestCloud _cloud;
8-
4+
extension type OrganizationRepository(cloud.CelestCloud _cloud) {
95
static final _logger = Logger('OrganizationRepository');
106

117
Future<cloud.Organization?> get(String organizationIdOrAlias) async {

apps/cli/lib/src/repositories/project_environment_repository.dart

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
import 'package:celest_cloud/celest_cloud.dart' as cloud;
22
import 'package:logging/logging.dart';
33

4-
final class ProjectEnvironmentRepository {
5-
ProjectEnvironmentRepository(this._cloud);
6-
7-
final cloud.CelestCloud _cloud;
8-
4+
extension type ProjectEnvironmentRepository(cloud.CelestCloud _cloud) {
95
static final _logger = Logger('ProjectEnvironmentRepository');
106

117
Future<cloud.ProjectEnvironment?> get(

apps/cli/lib/src/repositories/project_repository.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@ import 'package:celest_cli/src/repositories/organization_repository.dart';
22
import 'package:celest_cloud/celest_cloud.dart' as cloud;
33
import 'package:logging/logging.dart';
44

5-
final class ProjectRepository {
6-
ProjectRepository(this._cloud);
7-
8-
final cloud.CelestCloud _cloud;
5+
extension type ProjectRepository(cloud.CelestCloud _cloud) {
96
OrganizationRepository get _organizations => OrganizationRepository(_cloud);
107

118
static final _logger = Logger('ProjectRepository');
@@ -18,9 +15,15 @@ final class ProjectRepository {
1815
_logger.finest('No primary organization found');
1916
return null;
2017
}
18+
_logger.finest('Primary organization: ${organization.name}');
2119
final cloudPrj = await _cloud.projects.get(
2220
'${organization.name}/projects/$projectIdOrAlias',
2321
);
22+
if (cloudPrj == null) {
23+
_logger.finest('Project not found in cloud: $projectIdOrAlias');
24+
return null;
25+
}
26+
_logger.finest('Project found in cloud: ${cloudPrj.name}');
2427
return cloudPrj;
2528
} on Object catch (e, st) {
2629
_logger.fine('Failed to fetch project from cloud.', e, st);

0 commit comments

Comments
 (0)