runCommand method

Future<ProcessResult> runCommand(
  1. String executable,
  2. List<String> arguments, {
  3. String? workingDirectory,
  4. bool showOutput = false,
})

Runs a shell command and returns the results. Throws a CliException if the process returns a non-zero exit code.

Implementation

Future<ProcessResult> runCommand(
  String executable,
  List<String> arguments, {
  String? workingDirectory,
  bool showOutput = false,
}) async {
  try {
    if (showOutput) {
      Logger.boldInfo('Running: $executable ${arguments.join(' ')}');
      final process = await Process.start(
        executable,
        arguments,
        workingDirectory: workingDirectory,
        runInShell: true,
      );

      // Stream stdout and stderr
      final stdoutFuture = process.stdout
          .transform(utf8.decoder)
          .listen((data) => stdout.write(data))
          .asFuture();
      final stderrFuture = process.stderr
          .transform(utf8.decoder)
          .listen((data) => stderr.write(data))
          .asFuture();

      final exitCode = await process.exitCode;
      await Future.wait([stdoutFuture, stderrFuture]);

      if (exitCode != 0) {
        throw CliException(
          'Command failed with exit code $exitCode: $executable ${arguments.join(' ')}',
        );
      }

      return ProcessResult(process.pid, exitCode, '', '');
    } else {
      final result = await Process.run(
        executable,
        arguments,
        workingDirectory: workingDirectory,
        runInShell: true,
      );

      if (result.exitCode != 0) {
        throw CliException(
          'Command failed: $executable ${arguments.join(' ')}\nError: ${result.stderr}',
        );
      }
      return result;
    }
  } catch (e) {
    if (e is CliException) rethrow;
    throw CliException('Failed to execute command: $executable ${arguments.join(' ')}', e);
  }
}