Skip to content

Commit 3d38ae7

Browse files
authored
feat: Add validation to non-interactive mode and better error messages (#21)
1 parent 76172c4 commit 3d38ae7

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

lib/commands/create_command.dart

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ 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", '
31+
'as it conflicts with the Dart package',
32+
_ => null,
33+
},
2834
);
2935

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

4151
final versions = FlameVersionManager.singleton.versions;

lib/commands/version_command.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Future<void> versionCommand() async {
88
await runExecutableArguments('dart', ['--version'], verbose: true);
99
print('');
1010
await runExecutableArguments('flutter', ['--version'], verbose: true);
11-
}
11+
}

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)