run function

Future<int> run(
  1. List<String> args,
  2. List<FaircliCommand> commands(), {
  3. bool muteCommandLogging = false,
  4. bool verbose = false,
  5. bool verboseHelp = false,
  6. bool reportCrashes = true,
  7. String? flutterVersion,
  8. required Map<Type, Generator> overrides,
})

Runs the faircli tool with support for the specified list of commands.

Implementation

Future<int> run(
  List<String> args,
  List<FaircliCommand> Function() commands, {
  bool muteCommandLogging = false,
  bool verbose = false,
  bool verboseHelp = false,
  bool reportCrashes = true,
  String? flutterVersion,
  required Map<Type, Generator> overrides,
}) async {
  if (muteCommandLogging) {
    // Remove the verbose option; for help and doctor, users don't need to see
    // verbose logs.
    args = List<String>.of(args);
    args.removeWhere((String option) =>
        option == '-vv' || option == '-v' || option == '--verbose');
  }

  return runInContext<int>(() async {
    final FaircliCommandRunner runner =
        FaircliCommandRunner(verboseHelp: verboseHelp);
    commands().forEach(runner.addCommand);

    // Initialize the system locale.
    final String systemLocale = await intl_standalone.findSystemLocale();
    intl.Intl.defaultLocale = intl.Intl.verifiedLocale(
      systemLocale,
      intl.NumberFormat.localeExists,
      onFailure: (String _) => 'en_US',
    );

    String getVersion() =>
        flutterVersion ??
        globals.flutterVersion.getVersionString(redactUnknownBranches: true);
    Object? firstError;
    StackTrace? firstStackTrace;
    return runZoned<Future<int>>(() async {
      try {
        final bool version =
            args.contains('-version') || args.contains('--version');
        if (version) {
          cliPrint(versionName);
          return 0;
        }

        await runner.run(args);

        // Triggering [runZoned]'s error callback does not necessarily mean that
        // we stopped executing the body.  See https://github.com/dart-lang/sdk/issues/42150.
        if (firstError == null) {
          return await _exit(0);
        }

        // We already hit some error, so don't return success.  The error path
        // (which should be in progress) is responsible for calling _exit().
        return 1;
      } catch (error, stackTrace) {
        // ignore: avoid_catches_without_on_clauses
        // This catches all exceptions to send to crash logging, etc.
        firstError = error;
        firstStackTrace = stackTrace;
        return _handleToolError(
            error, stackTrace, verbose, args, reportCrashes, getVersion);
      }
    }, onError: (Object error, StackTrace stackTrace) async {
      // ignore: deprecated_member_use
      // If sending a crash report throws an error into the zone, we don't want
      // to re-try sending the crash report with *that* error. Rather, we want
      // to send the original error that triggered the crash report.
      firstError ??= error;
      firstStackTrace ??= stackTrace;
      await _handleToolError(firstError, firstStackTrace, verbose, args,
          reportCrashes, getVersion);
    });
  }, overrides: overrides);
}