ripGrepFileCount function

Future<int> ripGrepFileCount(
  1. List<String> args,
  2. String target, {
  3. Duration? timeout,
})

Stream-count lines from rg --files without buffering stdout.

On large repos (e.g. 247k files, 16MB of paths), calling ripGrep just to read .length materializes the full stdout string plus a 247k-element array. This counts newline bytes per chunk instead; peak memory is one stream chunk (~64KB).

Implementation

Future<int> ripGrepFileCount(
  List<String> args,
  String target, {
  Duration? timeout,
}) async {
  await _codesignRipgrepIfNecessary();
  final (:rgPath, :rgArgs, :argv0) = ripgrepCommand();

  final process = await Process.start(rgPath, [
    ...rgArgs,
    ...args,
    target,
  ], environment: argv0 != null ? {'ARGV0': argv0} : null);

  int lines = 0;
  await process.stdout.forEach((chunk) {
    for (final byte in chunk) {
      if (byte == 0x0A) lines++; // '\n'
    }
  });

  final exitCode = await process.exitCode;
  if (exitCode != 0 && exitCode != 1) {
    throw Exception('rg --files exited $exitCode');
  }
  return lines;
}