handle method

  1. @override
Future<int> handle(
  1. DowelContext ctx
)

Execute the command. Returns the process exit code.

Implementation

@override
Future<int> handle(DowelContext ctx) async {
  final verbose = ctx.input.option('verbose') as bool;
  final remote = ctx.input.option('remote') as bool;

  // 1. Remote checks are opt-in only — the default run never touches the
  //    network, so a doctor invoked in CI or offline never hangs on DNS.
  RemoteCheckResult? remoteResult;
  if (remote) {
    remoteResult = await checkRemoteAssociationFiles();
  }

  // 2. Collect local findings before printing — the report and the exit
  //    code both need the same lists.
  final missing = <String>[
    ...getMissingRequirements(),
    if (remoteResult != null)
      for (final issue in remoteResult.issues) '[remote] $issue',
  ];
  final warnings = <String>[
    ...getWarnings(),
    if (remoteResult != null)
      for (final warning in remoteResult.warnings) '[remote] $warning',
  ];

  ctx.output.writeln(
    generateReport(verbose: verbose, remoteResult: remoteResult),
  );

  // 3. Exit with the appropriate code. A warning alone exits 0: mixing
  //    AASA formats is discouraged, not broken, and a doctor that fails on
  //    it stops being read.
  if (missing.isEmpty && warnings.isEmpty) {
    ctx.output.success('All checks passed!');
    ctx.output.writeln('');
    return 0;
  }

  if (missing.isEmpty) {
    ctx.output.warning('Nothing failed, but see the warnings above.');
    ctx.output.writeln('');
    return 0;
  }

  ctx.output.writeln('');
  ctx.output.warning('Issues detected. Run the following to fix:');
  ctx.output.writeln('  • Install: dart run magic:dowel deeplink:install');
  // The doctor searches web/.well-known and public/.well-known, and
  // generate defaults to public, so the hint names the directory itself.
  ctx.output.writeln(
    '  • Generate: dart run magic:dowel deeplink:generate '
    '--output public/.well-known',
  );
  return 1;
}