renderSeedRuns function
Adds each run in a seeders.run payload to block: its changes, its
messages and how it ended. After seeding, it ends with how to undo it
with rollback.
verbs name what an up run did: Seeding and Seeded for seeders,
Importing and Imported for snapshots.
Returns why a run failed, or null when every run succeeded.
Implementation
String? renderSeedRuns(
LiveBlock block,
Object? payload, {
String rollback = 'seed:rollback',
({String running, String done}) verbs = (running: 'Seeding', done: 'Seeded'),
}) {
final Object? runs = payload is Map ? payload['runs'] : null;
if (runs is! List || runs.isEmpty) {
block.note('Nothing ran');
return null;
}
String? failure;
final List<String> seeded = [];
for (final Object? run in runs) {
if (run is! Map) continue;
final String name = '${run['name']}';
final bool down = run['direction'] == 'down';
final List<Map<Object?, Object?>> log = [
if (run['log'] case final List entries)
for (final Object? entry in entries)
if (entry is Map) entry,
];
final Iterable<Map<Object?, Object?>> changes = log.where(
(entry) => entry['level'] == 'change',
);
final int storeWidth = changes.fold(
0,
(width, entry) => max(width, '${entry['store']}'.length),
);
final int keyWidth = changes.fold(
0,
(width, entry) => max(width, '${entry['key']}'.length),
);
block.plain(down ? 'Rolling back $name' : '${verbs.running} $name');
for (final Map<Object?, Object?> entry in log) {
final String message = '${entry['message'] ?? ''}';
switch (entry['level']) {
case 'change':
final String change = '${entry['change']}';
final (String symbol, LiveTone tone) = switch (change) {
'added' => ('+', LiveTone.success),
'removed' => ('-', LiveTone.failure),
_ => ('~', LiveTone.warning),
};
block.add(
' $symbol ${'${entry['store']}'.padRight(storeWidth + 2)}'
'${'${entry['key']}'.padRight(keyWidth + 2)}'
'${change == 'restored' ? 'put back' : change}',
tone,
);
case 'success':
block.add(' ✓ $message', LiveTone.success);
case 'error':
block.add(' ✗ $message', LiveTone.failure);
case 'warning':
block.add(' ! $message', LiveTone.warning);
default:
block.plain(' $message');
}
}
if (run['failed'] == true) {
failure = '$name failed: ${run['error'] ?? 'unknown error'}';
block.failure('$name failed');
} else {
if (!down) seeded.add(name);
block.success(
'${down ? 'Rolled back' : verbs.done} $name in ${run['ms'] ?? 0}ms',
);
}
}
if (seeded.isNotEmpty && failure == null) {
block.note('Undo with $rollback ${seeded.join(' ')}');
}
return failure;
}