handle method

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

Execute the command. Returns the process exit code.

Implementation

@override
Future<int> handle(ArtisanContext 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 <app>:artisan deeplink:install');
  ctx.output
      .writeln('  • Generate: dart run <app>:artisan deeplink:generate');
  return 1;
}