Skip to content

Commit bd322eb

Browse files
committed
feat: Add validation to non-interactive mode and better error messages
1 parent 5dfb341 commit bd322eb

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

lib/commands/create_command.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ Future<void> createCommand(ArgResults command) async {
2424
'Choose a name for your project: ',
2525
desc: 'Note: this must be a valid dart identifier (no dashes). '
2626
'For example: my_game',
27-
validate: (it) => !it.contains('-') && it != 'test',
27+
validate: (it) => switch(it) {
28+
_ when it.isEmpty => 'Name cannot be empty',
29+
_ when it.contains('-') => 'Name cannot contain dashes',
30+
_ when it == 'test' => 'Name cannot be "test" as it conflicts with the Dart package',
31+
_ => null,
32+
},
2833
);
2934

3035
final org = getString(
@@ -35,7 +40,11 @@ Future<void> createCommand(ArgResults command) async {
3540
desc: 'Note: this is a dot separated list of "packages", '
3641
'normally in reverse domain notation. '
3742
'For example: org.flame_engine.games',
38-
validate: (it) => !it.contains('-'),
43+
validate: (it) => switch(it) {
44+
_ when it.isEmpty => 'Org cannot be empty',
45+
_ when it.contains('-') => 'Org cannot contain dashes',
46+
_ => null,
47+
},
3948
);
4049

4150
final versions = FlameVersionManager.singleton.versions;

lib/utils.dart

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,39 @@ String getString(
1717
String message, {
1818
required bool isInteractive,
1919
String? desc,
20-
bool Function(String)? validate,
20+
String? Function(String)? validate,
2121
}) {
2222
var value = results[name] as String?;
2323
if (!isInteractive) {
2424
if (value == null || value.isEmpty) {
2525
print('Missing parameter $name is required.');
2626
exit(1);
2727
}
28+
final error = validate?.call(value);
29+
if (error != null) {
30+
print('Invalid value $value provided: $error');
31+
exit(1);
32+
}
2833
}
2934
while (value == null || value.isEmpty) {
3035
if (desc != null) {
3136
stdout.write(ansi.darkGray.wrap('\n$desc\u{1B}[1A\r'));
3237
}
33-
value = prompts.get(message, validate: validate);
38+
value = prompts.get(
39+
message,
40+
validate: (e) {
41+
final error = validate?.call(e);
42+
if (error != null) {
43+
// clear the line
44+
stdout.write('\n\r\u{1B}[K');
45+
stdout.write(ansi.red.wrap('$error\u{1B}[1A\r'));
46+
return false;
47+
} else {
48+
stdout.write('\n\r\u{1B}[K');
49+
return true;
50+
}
51+
},
52+
);
3453
if (desc != null) {
3554
stdout.write('\r\u{1B}[K');
3655
}
@@ -77,14 +96,14 @@ String getOption(
7796
}
7897

7998
List<String> _unwrap(dynamic value) {
80-
return switch(value) {
99+
return switch (value) {
81100
null => [],
82101
String _ => [value],
83102
List<String> _ => value,
84103
List _ => value.map((e) => e.toString()).toList(),
85104
_ => throw ArgumentError(
86-
'Invalid type for value (${value.runtimeType}): $value',
87-
),
105+
'Invalid type for value (${value.runtimeType}): $value',
106+
),
88107
};
89108
}
90109

@@ -118,9 +137,7 @@ List<String> getMultiOption(
118137
if (desc != null) {
119138
stdout.write(ansi.darkGray.wrap('\n$desc\u{1B}[1A\r'));
120139
}
121-
final selectedOptions = value.isEmpty
122-
? startingOptions
123-
: value;
140+
final selectedOptions = value.isEmpty ? startingOptions : value;
124141
value = cbx(message, options, selectedOptions);
125142
if (desc != null) {
126143
stdout.write('\r\u{1B}[K');

0 commit comments

Comments
 (0)