resolveCiStages function
Expands all into stages, keeps the given order and drops repeats.
Unknown names throw.
inAll decides which stages all takes — every one by default; a stage
that can only run on some hosts is left out of all elsewhere and still
runs when named on its own.
Implementation
List<String> resolveCiStages(
Iterable<String> requested, {
required List<String> stages,
bool Function(String stage)? inAll,
}) {
final out = <String>[];
for (final name in requested) {
if (name == 'all') {
out.addAll(
stages.where((s) => !out.contains(s) && (inAll?.call(s) ?? true)),
);
} else if (stages.contains(name)) {
if (!out.contains(name)) out.add(name);
} else {
throw ArgumentError.value(name, 'stage', 'not a stage');
}
}
return out;
}