Skip to content

Commit 74e1674

Browse files
committed
chore: improve error logging
1 parent c192e6c commit 74e1674

File tree

7 files changed

+75
-38
lines changed

7 files changed

+75
-38
lines changed

bin/script_runner.dart

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import 'package:script_runner/utils.dart';
66
/// Main entrypoint for CMD script runner.
77
Future<void> main(List<String> args) async {
88
if (args.isEmpty) {
9-
printColor('No script command provided. Use -h to see available commands.', [TerminalColor.red]);
9+
printColor(
10+
'No script command provided. Use -h or -ls to see available commands.',
11+
[TerminalColor.red]);
1012
return;
1113
}
1214
final scriptCmd = args.first;
@@ -15,13 +17,15 @@ Future<void> main(List<String> args) async {
1517
final code = await runScript(scriptCmd, scriptArgs);
1618
io.exit(code);
1719
} catch (e, stack) {
18-
if (e is ScriptStateError) {
20+
if (e is ScriptError) {
1921
printColor(e.toString(), [TerminalColor.red]);
20-
} else {
21-
printColor('$e\n$stack', [TerminalColor.red]);
22-
}
23-
if (e is io.ProcessException) {
22+
} else if (e is io.ProcessException) {
23+
printColor(
24+
'Error in script "$scriptCmd": ${e.message}', [TerminalColor.red]);
2425
io.exit(e.errorCode);
26+
} else {
27+
printColor('Error executing script: $e\n$stack', [TerminalColor.red]);
28+
io.exit(1);
2529
}
2630
}
2731
}

lib/base.dart

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Future<int> runScript(String entryName, List<String> args) async {
77
final config = await ScriptRunnerConfig.get();
88

99
if (config.scripts.isEmpty) {
10-
throw ScriptStateError('No scripts found');
10+
throw ScriptNotFoundError('No scripts found');
1111
}
1212

1313
if (['-h', '--help'].contains(entryName)) {
@@ -24,27 +24,32 @@ Future<int> runScript(String entryName, List<String> args) async {
2424
final entry = config.scriptsMap[entryName];
2525

2626
if (entry == null) {
27-
final suggestions =
28-
config.scriptsMap.keys.where((key) => key.toLowerCase().startsWith(entryName.toLowerCase())).toList();
27+
final suggestions = config.scriptsMap.keys
28+
.where((key) => key.toLowerCase().startsWith(entryName.toLowerCase()))
29+
.toList();
2930

3031
if (suggestions.isNotEmpty) {
3132
if (suggestions.length == 1) {
32-
throw ScriptStateError(
33+
throw ScriptNotFoundError(
3334
'No script named "$entryName" found. Did you mean "${suggestions.single}"?',
3435
);
3536
} else {
36-
throw ScriptStateError(
37+
throw ScriptNotFoundError(
3738
'No script named "$entryName" found.\n'
3839
'Did you mean one of: "${suggestions.join('", "')}"?',
3940
);
4041
}
4142
} else {
42-
throw ScriptStateError(
43+
throw ScriptNotFoundError(
4344
'No script named "$entryName" found.\n'
4445
'Available scripts: ${config.scriptsMap.keys.join('", "')}',
4546
);
4647
}
4748
}
4849

49-
return entry.run(args);
50+
try {
51+
return entry.run(args);
52+
} catch (e, stack) {
53+
throw ScriptError('Error running script "$entryName": $e\n$stack');
54+
}
5055
}

lib/config.dart

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ class ScriptRunnerConfig {
7575
final sourceMap = await _tryFindConfig(fs, startDir);
7676

7777
if (sourceMap.isEmpty) {
78-
throw ScriptStateError('Must provide scripts in either pubspec.yaml or script_runner.yaml');
78+
throw ScriptStateError(
79+
'Must provide scripts in either pubspec.yaml or script_runner.yaml');
7980
}
8081

8182
final source = sourceMap.values.first;
@@ -100,7 +101,9 @@ class ScriptRunnerConfig {
100101
List<dynamic>? scriptsRaw, {
101102
FileSystem? fileSystem,
102103
}) {
103-
final scripts = (scriptsRaw ?? []).map((script) => RunnableScript.fromMap(script, fileSystem: fileSystem)).toList();
104+
final scripts = (scriptsRaw ?? [])
105+
.map((script) => RunnableScript.fromMap(script, fileSystem: fileSystem))
106+
.toList();
104107
return scripts.map((s) => s..preloadScripts = scripts).toList();
105108
}
106109

@@ -138,7 +141,8 @@ class ScriptRunnerConfig {
138141
(configSource?.isNotEmpty == true
139142
? [
140143
colorize(' on ', titleStyle),
141-
colorize(configSource!, [...titleStyle, TerminalColor.underline]),
144+
colorize(
145+
configSource!, [...titleStyle, TerminalColor.underline]),
142146
colorize(':', titleStyle)
143147
].join('')
144148
: ':'),
@@ -165,10 +169,15 @@ class ScriptRunnerConfig {
165169

166170
final filtered = search.isEmpty
167171
? scripts
168-
: scripts.where((scr) => [scr.name, scr.description].any((s) => s != null && s.contains(search))).toList();
172+
: scripts
173+
.where((scr) => [scr.name, scr.description]
174+
.any((s) => s != null && s.contains(search)))
175+
.toList();
169176

170-
final mapped =
171-
filtered.map((scr) => TableRow(scr.name, scr.description ?? '\$ ${[scr.cmd, ...scr.args].join(' ')}')).toList();
177+
final mapped = filtered
178+
.map((scr) => TableRow(scr.name,
179+
scr.description ?? '\$ ${[scr.cmd, ...scr.args].join(' ')}'))
180+
.toList();
172181

173182
final padLen = _getPadLen(mapped.map((r) => r.name).toList(), maxLen);
174183

@@ -180,7 +189,8 @@ class ScriptRunnerConfig {
180189
/// If [search] is provided, it filters the scripts to only those that contain the search string.
181190
void printBuiltins([String search = '']) {
182191
final builtins = [
183-
TableRow('-ls, --list [search]', 'List available scripts. Add search term to filter.'),
192+
TableRow('-ls, --list [search]',
193+
'List available scripts. Add search term to filter.'),
184194
TableRow('-h, --help', 'Print this help message'),
185195
];
186196

@@ -197,15 +207,17 @@ class ScriptRunnerConfig {
197207
stripColors: true,
198208
wrapLine: (line) => colorize(line, [TerminalColor.gray]),
199209
);
200-
printColor(' ${scr.name.padRight(padLen, ' ')} ${lines.first}', [TerminalColor.yellow]);
210+
printColor(' ${scr.name.padRight(padLen, ' ')} ${lines.first}',
211+
[TerminalColor.yellow]);
201212
for (final line in lines.sublist(1)) {
202213
print(' ${''.padRight(padLen, ' ')} $line');
203214
}
204215
print('');
205216
}
206217
}
207218

208-
static Future<Map<String, Map>> _tryFindConfig(FileSystem fs, String startDir) async {
219+
static Future<Map<String, Map>> _tryFindConfig(
220+
FileSystem fs, String startDir) async {
209221
final explorer = Unaconfig('script_runner', fs: fs);
210222
final config = await explorer.search();
211223
if (config != null) {

lib/runnable_script.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class RunnableScript {
100100
env: map['env'] as Map<String, String>? ?? {},
101101
);
102102
} catch (e) {
103-
throw ScriptStateError('Failed to parse script, arguments: $map, $fileSystem. Error: $e');
103+
throw ScriptStateError(
104+
'Failed to parse script, arguments: $map, $fileSystem. Error: $e');
104105
}
105106
}
106107

@@ -162,7 +163,8 @@ class RunnableScript {
162163
return exitCode;
163164
}
164165

165-
String _getScriptPath() => _fileSystem.path.join(_fileSystem.systemTempDirectory.path, 'script_runner_$name.sh');
166+
String _getScriptPath() => _fileSystem.path
167+
.join(_fileSystem.systemTempDirectory.path, 'script_runner_$name.sh');
166168

167169
String _getScriptContents(
168170
ScriptRunnerConfig config, {
@@ -182,8 +184,11 @@ class RunnableScript {
182184
].join('\n');
183185
case OS.linux:
184186
case OS.macos:
185-
return [...preloadScripts.map((e) => "[[ ! \$(which ${e.name}) ]] && alias ${e.name}='scr ${e.name}'"), script]
186-
.join('\n');
187+
return [
188+
...preloadScripts.map((e) =>
189+
"[[ ! \$(which ${e.name}) ]] && alias ${e.name}='scr ${e.name}'"),
190+
script
191+
].join('\n');
187192
}
188193
}
189194
}

lib/utils.dart

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,20 @@ class TerminalColor {
135135
static const TerminalColor underline = TerminalColor._(4);
136136
}
137137

138-
class ScriptStateError extends StateError {
139-
ScriptStateError(super.message);
138+
/// An error that occurs that is related to a script.
139+
class ScriptError extends StateError {
140+
ScriptError(super.message);
140141

141142
@override
142143
String toString() => message;
143144
}
145+
146+
/// An error that occurs during script execution.
147+
class ScriptStateError extends ScriptError {
148+
ScriptStateError(super.message);
149+
}
150+
151+
/// An error that occurs when a script is not found.
152+
class ScriptNotFoundError extends ScriptError {
153+
ScriptNotFoundError(super.message);
154+
}

pubspec.yaml

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ dev_dependencies:
2020
btool: any
2121

2222
script_runner:
23-
# line_length: 100
2423
scripts:
24+
# ================================================================================
2525
# Real
26+
# ================================================================================
2627
- auto-fix: dart fix --apply
27-
- publish: dart format .; dart pub publish; format
28+
- publish: dart format .; dart pub publish
2829
- publish:dry: dart pub publish --dry-run
2930
- doc: dart doc
3031
- name: version
@@ -33,15 +34,13 @@ script_runner:
3334
- name: 'version:set'
3435
cmd: dart run btool set packageVersion
3536
display_cmd: false
36-
- format: dart format --line-length 120 .
37-
- name: clean
38-
cmd: rm -rf .dart_tool/pub/bin/script_runner/script_runner.dart-*.snapshot
39-
- name: activate-local
40-
cmd: scr clean && dart pub global deactivate script_runner; dart pub global activate --source path ./
41-
- name: activate-global
42-
cmd: scr clean && dart pub global deactivate script_runner; dart pub global activate script_runner
37+
- clean: rm -rf .dart_tool/pub/bin/script_runner/script_runner.dart-*.snapshot
38+
- activate-local: scr clean && dart pub global deactivate script_runner; dart pub global activate --source path ./
39+
- activate-global: scr clean && dart pub global deactivate script_runner; dart pub global activate script_runner
4340

41+
# ================================================================================
4442
# Examples
43+
# ================================================================================
4544
- name: echo1
4645
cmd: echo "Hello World" $SHELL
4746
description: Interdum a scelerisque arcu felis taciti ligula pellentesque curabitur, suspendisse adipiscing quisque sed luctus elementum in imperdiet id, praesent enim sem justo sapien diam nec. Quisque erat risus sagittis penatibus per, vehicula sociosqu cubilia convallis, sollicitudin scelerisque cras aptent. Natoque ornare dictumst netus litora mollis suspendisse cubilia proin morbi primis consequat eu massa, cursus non urna ridiculus dolor duis tempus ut nam velit lacus viverra. A interdum senectus eu mus leo aptent facilisi augue tristique ante purus condimentum pulvinar porta viverra morbi, et tellus gravida porttitor non euismod suscipit neque egestas praesent arcu luctus pharetra fusce. Luctus mauris a venenatis tempus cras ante efficitur massa ultricies mollis lacus, volutpat nisi lacinia himenaeos facilisi in aliquet sodales purus integer vitae quisque, libero torquent enim mattis placerat tortor mi dignissim viverra sem.

test/config_test.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ Future<void> _writeCustomConf(FileSystem fs, [String? contents]) async {
184184
final homeDir = fs.directory(Platform.environment['HOME']!);
185185
homeDir.create(recursive: true);
186186
fs.currentDirectory = homeDir;
187-
final pubFile = fs.file(path.join(fs.currentDirectory.path, 'script_runner.yaml'));
187+
final pubFile =
188+
fs.file(path.join(fs.currentDirectory.path, 'script_runner.yaml'));
188189
pubFile.create(recursive: true);
189190
print('writing custom conf to ${pubFile.path}');
190191
await pubFile.writeAsString(

0 commit comments

Comments
 (0)