step method

Future<void> step(
  1. String stage,
  2. String subject,
  3. String logName,
  4. List<CiCommand> commands, {
  5. bool needsFlutter = false,
  6. bool counts = false,
  7. String? produces,
})

Runs commands as one step into the log logName, recording its outcome. counts reads the test counts of the last progress line into the detail; produces is a file the step must leave behind, so an exit code of 0 with nothing built is red.

Implementation

Future<void> step(
  String stage,
  String subject,
  String logName,
  List<CiCommand> commands, {
  bool needsFlutter = false,
  bool counts = false,
  String? produces,
}) async {
  final logPath = p.join(runDir, logName);
  final label = subject == stage ? '[$stage]' : '[$stage] $subject';
  console.write('$label …');
  if (needsFlutter && flutter == null) {
    console.writeln();
    fail(
      stage,
      subject,
      logName,
      'flutter not found — put it on PATH or set FLUTTER_ROOT',
    );
    return;
  }
  final result = await runner.run(commands, logPath: logPath);
  var ok = result.ok;
  var detail = '';
  if (counts) {
    final c = parseCiTestCounts(result.tail);
    detail = c?.toString() ?? 'no test progress line';
  }
  if (ok && produces != null && !File(produces).existsSync()) {
    ok = false;
    detail = 'exit 0 but no ${relative(produces)}';
  }
  if (!ok && detail.isEmpty) detail = 'exit ${result.exitCode}';
  if (!ok && counts && result.exitCode != 0) {
    detail = '$detail, exit ${result.exitCode}';
  }
  _record(stage, subject, logPath, ok, detail, result.elapsed);
  console.writeln(
    ' ${ok ? 'green' : 'RED'} $detail '
    '(${formatCiDuration(result.elapsed)})'
    '${ok ? '' : ' -> ${relative(logPath)}'}',
  );
}