runCommand function

Future<int> runCommand(
  1. Command command, [
  2. List<String> rawArguments = const [],
  3. List<Flag> globalFlags = const []
])

Executes a Command with the arguments of the command line.

globalFlags are available for every command, regardless of inheritFlags.

Implementation

Future<int> runCommand(
  Command command, [
  final List<String> rawArguments = const [],
  final List<Flag> globalFlags = const [],
]) async {
  List<Flag> flags = command.flags;
  String argument = "";

  final List<String> mergedArgs = _mergeArguments(rawArguments);
  final Iterable<String> plainArgs = mergedArgs.where(
    (raw) => !raw.startsWith("--"),
  );
  final Iterable<String> flagArgs = mergedArgs
      .where((raw) => raw.startsWith("--"))
      .map((raw) => raw.substring(2));

  /*
   * Figures out, which argument is a prompt for
   * a sub command or the actual argument for a command.
   */
  for (final String plainArg in plainArgs) {
    bool isSubCmd = false;
    for (final Command subCmd in command.subCommands) {
      if (plainArg == subCmd.use) {
        flags = subCmd.inheritFlags ? subCmd.flags += flags : subCmd.flags;
        command = subCmd;
        isSubCmd = true;
        break;
      }
    }
    if (!isSubCmd) {
      argument = plainArg;
      break;
    }
  }

  /*
   * Adds the global flags the current's command flags.
   * Set's then the [flags] list with the parsed values of [flagArgs].
   */
  flags += globalFlags;
  _parseAndSetFlags(flagArgs, flags);

  Response? response;
  try {
    response = await command.run(CommandInformation(command, argument, flags));
  } catch (e) {
    stderr.writeln(e);
  }

  final bool isError = response?.level == Level.error || response?.level == Level.critical;
  final String responseMsg = response?.message ?? "";

  if (isError) {
    stderr.writeln(
      "An error occurred" + (responseMsg.isEmpty ? "." : ": $responseMsg"),
    );
    return 1;
  }
  stdout.writeln(responseMsg);
  return 0;
}