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 rest = args.rest;
  if (rest.isEmpty) {
    throw CliError(
      'usage: preset apply <preset.json|preset-id> [<node>] '
      '[--label env=prod | --all]',
    );
  }

  // A path if it exists on disk, otherwise the id of a preset saved on the Hub.
  // The saved form is the one worth using: a file is whatever copy *this*
  // caller happens to have, while an id is the one everybody agrees on.
  final source = rest.first;
  final file = File(source);
  final inline = await file.exists()
      ? Preset.fromJson(
          (jsonDecode(await file.readAsString()) as Map)
              .cast<String, dynamic>(),
        )
      : null;

  final client = _apiClientFrom(args);
  try {
    final nodes = await _selectNodes(
      client,
      args,
      positional: rest.skip(1).toList(),
    );
    final async = args['async'] as bool;
    await _fanOut(nodes, (node) async {
      if (async) {
        final operation = await client.applyPresetAsync(
          node,
          presetId: inline == null ? source : null,
          preset: inline,
        );
        return 'dispatched — ops show ${operation.id}';
      }
      final reply = await client.applyPreset(
        node,
        presetId: inline == null ? source : null,
        preset: inline,
      );
      final failed = reply.results.where((r) => !r.success).length;
      final changed = reply.results.where((r) => r.changed).length;
      return failed == 0
          ? 'applied ${reply.results.length} steps ($changed changed)'
          : 'FAILED $failed/${reply.results.length} steps';
    });
  } finally {
    client.close();
  }
}