parse method

  1. @override
ArgResults parse(
  1. Iterable<String> args, {
  2. List<String> badArgs = const [],
  3. List<String>? preFlags,
})

Parses args, a list of command-line arguments, matches them against the flags and options defined by this parser, and returns the result.

Implementation

@override
ArgResults parse(
  Iterable<String> args, {
  List<String> badArgs = const [],
  List<String>? preFlags,
}) {
  var mutableArgs = [...args];
  final removedArgs = <String>[...badArgs];

  ArgResults backUpResult;

  final preFlags0 = <String>[];

  if (preFlags != null) {
    preFlags0.addAll(preFlags);
  } else {
    final preFlags = mutableArgs.takeWhile((value) => !value.startsWith('-'));
    preFlags0.addAll(preFlags);
    mutableArgs = mutableArgs.skip(preFlags.length).toList();
  }

  try {
    backUpResult = _argParser.parse([...preFlags0, ...mutableArgs]);
  } on ArgParserException catch (e) {
    final badFlag = RegExp('"([a-z-_=]+)"').firstMatch(e.message)?.group(1);

    if (badFlag == null) {
      rethrow;
    }

    var grabValues = true;

    if (mutableArgs.remove(badFlag)) {
      removedArgs.add(badFlag);
    } else if (mutableArgs.remove('-$badFlag')) {
      removedArgs.add('-$badFlag');
    } else if (mutableArgs.remove('--$badFlag')) {
      removedArgs.add('--$badFlag');
    } else {
      var foundFlag = false;
      for (final key in mutableArgs.reversed) {
        if (key.startsWith('--$badFlag=')) {
          mutableArgs.remove(key);
          removedArgs.add(key);
          foundFlag = true;
          break;
        } else if (RegExp(r'^-\w').hasMatch(badFlag) &&
            RegExp(r'(?:-)\w*' '${badFlag.replaceAll('-', '')}')
                .hasMatch(key)) {
          final badFlagOnly = badFlag.replaceAll('-', '');
          grabValues = key.endsWith(badFlagOnly);

          final updatedKey = key.replaceAll(badFlagOnly, '');

          final replaceIndex = mutableArgs.indexOf(key);
          mutableArgs
              .replaceRange(replaceIndex, replaceIndex + 1, [updatedKey]);

          removedArgs.add(badFlag);
          foundFlag = true;
          break;
        }
      }

      if (!foundFlag) {
        throw Exception('Unknown flag format: $badFlag');
      }
    }

    if (grabValues) {
      final removed =
          mutableArgs.takeWhile((value) => !value.startsWith('-'));

      removedArgs.addAll(removed.expand((element) => element.split('=')));

      mutableArgs = mutableArgs.skip(removed.length).toList();
    }

    return parse(
      mutableArgs,
      badArgs: removedArgs,
      preFlags: preFlags0,
    );
  }

  final anyArgResults = AnyArgResults(backUpResult)..addAllRest(removedArgs);

  return anyArgResults;
}