run method

  1. @override
Future<void> run()
override

Runs this command.

The return value is wrapped in a Future if necessary and returned by CommandRunner.runCommand.

Implementation

@override
Future<void> run() async {
  final args = argResults!;
  final client = _apiClientFrom(args);
  try {
    final nodes = await _selectNodes(client, args, positional: args.rest);
    var drifted = 0;
    for (final node in nodes) {
      try {
        final plan = await client.drift(node);
        if (plan == null) {
          stderr.writeln('${node.padRight(20)} nothing declared');
          continue;
        }
        if (plan.converged) {
          stdout.writeln('${node.padRight(20)} converged');
          continue;
        }
        drifted++;
        // A node declared by a blueprint answers in resource changes; one
        // declared by steps answers in actions. Exactly one is filled.
        final pending = [
          for (final c in plan.changes)
            if (c.kind != ChangeKind.noop) '${c.kind.name} ${c.id}',
          for (final s in plan.actions) '${s.action.name} ${s.formula.value}',
        ];
        stdout.writeln(
          '${node.padRight(20)} DRIFTED — ${pending.length} to run',
        );
        for (final line in pending) {
          stdout.writeln('  $line');
        }
      } on HubApiException catch (e) {
        stderr.writeln('${node.padRight(20)} ${e.message}');
      }
    }
    // Exit non-zero when anything has drifted, so this is usable as a check in
    // a pipeline — "is the fleet still what we said it was?"
    if (drifted > 0) exitCode = 1;
  } finally {
    client.close();
  }
}