parseCliArgs function

List<String> parseCliArgs(
  1. String command, {
  2. bool isRawString = true,
})

Parse a CLI command string into a list of its full arguments, including the command name itself.

Attempts to simulate basic shell argument parsing behavior, including handling single quotes, double quotes, and escape characters.

final cmd = '''ft search --pattern="**.yaml" --excludes="/**/.**" --source=~/Downloads --fields=ok,action,type,time,size --regexp="version: 1.0.\d+" -v''';
print(parseCliCommand(cmd));
// [ft, search, --pattern=**.yaml, --excludes=/**/.**, --source=~/Downloads, --fields=ok,action,type,time,size, --regexp=version: 1.0.\d+, -v]

Implementation

List<String> parseCliArgs(String command, {bool isRawString = true}) {
  List<String> args = [];
  StringBuffer currentArg = StringBuffer();
  bool inDoubleQuote = false;
  bool inSingleQuote = false;
  bool escaped = false;

  for (int i = 0; i < command.length; i++) {
    String char = command[i];

    if (escaped) {
      currentArg.write(char);
      escaped = false;
    } else if (char == r'\') {
      escaped = true;
      if (isRawString) {
        escaped = false;
        currentArg.write(char);
      }
    } else if (char == r'"' && !inSingleQuote) {
      inDoubleQuote = !inDoubleQuote;
    } else if (char == r"'" && !inDoubleQuote) {
      inSingleQuote = !inSingleQuote;
    } else if (char == r' ' && !inDoubleQuote && !inSingleQuote) {
      if (currentArg.isNotEmpty) {
        args.add(currentArg.toString());
        currentArg.clear();
      }
    } else {
      currentArg.write(char);
    }
  }

  if (currentArg.isNotEmpty) {
    args.add(currentArg.toString());
  }

  return args;
}