renderDoctorText function

String renderDoctorText(
  1. DoctorReport report,
  2. List<String> blocking, {
  3. CompatibilityResult? compatibility,
  4. bool useColor = false,
})

Renders the DoctorReport in human-readable text format.

useColor adds ANSI colour to the header and status tokens; it defaults to off so pipes, JSON callers, and tests stay plain.

Binds: R-009, FR-007, FR-009.

Implementation

String renderDoctorText(
  DoctorReport report,
  List<String> blocking, {
  CompatibilityResult? compatibility,
  bool useColor = false,
}) {
  final buffer = StringBuffer();

  buffer.writeln(
    ansiHeading(
      'FlutterStart ${report.flutterStartVersion.value ?? "unknown"}',
      color: useColor,
    ),
  );

  if (report.flutterExecutable.observed && report.flutterVersion.observed) {
    buffer.writeln(
      'Flutter    ${report.flutterVersion.value ?? "unknown"}    ${report.flutterExecutable.value ?? "unknown"}',
    );
  } else {
    buffer.writeln('Flutter    n/a');
  }

  if (report.dartExecutable.observed && report.dartVersion.observed) {
    buffer.writeln(
      'Dart       ${report.dartVersion.value ?? "unknown"}    ${report.dartExecutable.value ?? "unknown"}',
    );
  } else {
    buffer.writeln('Dart       n/a');
  }

  if (report.gitAvailable.observed) {
    buffer.writeln(
      'Git        ${ansiStatus(report.gitAvailable.value == true ? "available" : "not available", color: useColor)}',
    );
  } else {
    buffer.writeln('Git        ${ansiStatus("unknown", color: useColor)}');
  }

  final os = report.hostOs.value ?? 'unknown';
  final cs = report.caseSensitivity.observed
      ? (report.caseSensitivity.value == true
            ? 'case-sensitive'
            : 'case-insensitive')
      : 'unknown';
  buffer.writeln('Host       $os · filesystem $cs (probed)');

  final sAccess = report.stagingAccess.observed
      ? (report.stagingAccess.value == true ? 'ok' : 'failed')
      : 'unknown';
  final tAccess = report.tempAccess.observed
      ? (report.tempAccess.value == true ? 'ok' : 'failed')
      : 'unknown';
  buffer.writeln(
    'Staging    ${ansiStatus(sAccess, color: useColor)} · Temp ${ansiStatus(tAccess, color: useColor)}',
  );

  final rComp = report.recipeCompatibility.observed
      ? (report.recipeCompatibility.value == true ? 'ok' : 'incompatible')
      : 'unknown';
  final eComp = report.engineCompatibility.observed
      ? (report.engineCompatibility.value == true ? 'ok' : 'incompatible')
      : 'unknown';
  final rendererComp = report.rendererVersionCompatibility.observed
      ? (report.rendererVersionCompatibility.value == true
            ? 'ok'
            : 'incompatible')
      : 'unknown';
  buffer.writeln(
    'Recipe     ${ansiStatus(rComp, color: useColor)} · Engine ${ansiStatus(eComp, color: useColor)} · Renderer mason 0.1.2 ${ansiStatus(rendererComp, color: useColor)}',
  );

  final net = report.networkReachability.observed
      ? (report.networkReachability.value == true
            ? 'pub.dev reachable'
            : 'pub.dev unreachable')
      : 'pub.dev unknown';

  var cache = 'Package cache unknown';
  if (report.packageCacheClassification.observed) {
    final stateStr = report.packageCacheClassification.value?.name
        .toUpperCase();
    if ((stateStr == 'PARTIAL' || stateStr == 'COLD') &&
        report.packageCacheMissing.value != null &&
        report.packageCacheMissing.value!.isNotEmpty) {
      cache =
          'Package cache $stateStr (missing: ${report.packageCacheMissing.value!.join(", ")})';
    } else {
      cache = 'Package cache $stateStr';
    }
  }
  buffer.writeln('Network    ${ansiStatus(net, color: useColor)} · $cache');

  if (report.windowsLongPathStatus.observed) {
    buffer.writeln(
      'Windows    long-path ${report.windowsLongPathStatus.value == true ? "enabled" : "disabled"}',
    );
  } else {
    buffer.writeln('Windows    n/a');
  }

  if (report.provisionalNotes.observed &&
      report.provisionalNotes.value != null &&
      report.provisionalNotes.value!.isNotEmpty) {
    buffer.writeln(
      '\nProvisional features active: ${report.provisionalNotes.value!.join(", ")}',
    );
  }

  if (blocking.isNotEmpty) {
    buffer.writeln('\nBlocking environment failures:');
    for (final cond in blocking) {
      buffer.writeln('  - $cond');
    }
  }

  if (compatibility?.warnings case final warnings? when warnings.isNotEmpty) {
    buffer.writeln('\nCompatibility warnings:');
    for (final warning in warnings) {
      buffer.writeln('  - [${warning.code}] ${warning.message}');
    }
  }

  return buffer.toString().trim();
}