load method
Parses udara.yaml. Returns an empty map when the file is absent and
throws a BuildException for malformed content or unknown hook names,
so a typo fails fast instead of being silently ignored.
Implementation
Map<HookPoint, List<String>> load() {
final file = configFile;
if (!file.existsSync()) return const {};
final Object? yaml;
try {
yaml = loadYaml(file.readAsStringSync());
} catch (e) {
throw BuildException(
'$configFileName could not be parsed: $e',
fix: 'Check $configFileName for YAML syntax errors.',
);
}
if (yaml == null) return const {};
if (yaml is! YamlMap) {
throw BuildException(
'$configFileName must be a YAML map with a "hooks:" key.',
fix: _exampleFix,
);
}
final hooks = yaml['hooks'];
if (hooks == null) return const {};
if (hooks is! YamlMap) {
throw BuildException('"hooks" in $configFileName must be a map.',
fix: _exampleFix);
}
final result = <HookPoint, List<String>>{};
for (final entry in hooks.entries) {
final key = entry.key.toString();
final point = HookPoint.fromKey(key);
if (point == null) {
throw BuildException(
'Unknown hook "$key" in $configFileName.',
fix: 'Supported hooks: '
'${HookPoint.values.map((h) => h.key).join(', ')}.',
);
}
final value = entry.value;
final commands = switch (value) {
null => <String>[],
String s => [s],
YamlList l => l.map((c) => c.toString()).toList(),
_ => throw BuildException(
'Hook "$key" must be a command string or a list of commands.',
fix: _exampleFix,
),
};
result[point] = commands.where((c) => c.trim().isNotEmpty).toList();
}
return result;
}