parse method

ParsedArguments parse(
  1. List<String> tokens
)

Implementation

ParsedArguments parse(List<String> tokens) {
  final resolution = _registry.resolveCommandPath(tokens);
  final commandPath = resolution.path;
  final registry = resolution.registry;
  final values = <Object, Object?>{};
  final positionals = <String>[];
  final trailing = <String>[];
  var help = false;
  var version = false;
  final consumed = <int>{};
  final optionInputs = [
    ...registry.applicableOptions,
    for (final group in registry.pairedOptionGroups) ...group.options,
    for (final group in registry.selectedOptions) ...group.options,
  ];
  for (var index = 0; index < tokens.length; index++) {
    if (consumed.contains(index) || resolution.tokenIndices.contains(index))
      continue;
    final token = tokens[index];
    if (token == '--') {
      trailing.addAll(tokens.skip(index + 1));
      break;
    }
    if (token == '--help' || token == '-h') {
      values[MambaBuiltInFlags.help] = true;
      help = true;
      continue;
    }
    if (token == '--version') {
      values[MambaBuiltInFlags.version] = true;
      version = true;
      continue;
    }
    if (help || version) continue;
    if (token.startsWith('--') && token.length > 2) {
      final (name, inline) = _split(token.substring(2));
      final accessor = _accessorFor(name, registry.applicableAccessors);
      if (accessor != null) {
        values[accessor] = _parseValue(
          accessor,
          _takeValue(tokens, index, consumed, name, inline, accessor),
        );
        continue;
      }
      final input = optionInputs
          .where((item) => item.name == name)
          .firstOrNull;
      if (input != null) {
        _put(
          values,
          input,
          _parseValue(
            input,
            _takeValue(tokens, index, consumed, name, inline, input),
          ),
        );
        continue;
      }
      final flag = registry.applicableFlags
          .where(
            (item) =>
                item.name == name ||
                (item is BooleanFlag &&
                    item.negatable &&
                    name == 'no-${item.name}'),
          )
          .firstOrNull;
      if (flag == null)
        throw MambaParseException('Unknown flag or option --$name.');
      if (inline != null)
        throw MambaParseException('Flag --$name does not accept a value');
      if (flag is BooleanFlag)
        values[flag] = !name.startsWith('no-');
      else if (flag is CountFlag)
        values[flag] = ((values[flag] as int?) ?? 0) + 1;
      continue;
    }
    if (token.startsWith('-') && token.length > 1) {
      final short = token.substring(1);
      final input = optionInputs
          .where((item) => _shortOf(item) == short)
          .firstOrNull;
      if (input != null) {
        _put(
          values,
          input,
          _parseValue(
            input,
            _takeValue(tokens, index, consumed, input.name, null, input),
          ),
        );
        continue;
      }
      for (final letter in short.split('')) {
        if (letter == 'h') {
          help = true;
          continue;
        }
        final flag = registry.applicableFlags
            .where((item) => item.short == letter)
            .firstOrNull;
        if (flag == null)
          throw MambaParseException(
            "This isn't a registered short flag or option",
          );
        if (flag is BooleanFlag) values[flag] = true;
        if (flag is CountFlag)
          values[flag] = ((values[flag] as int?) ?? 0) + 1;
      }
      continue;
    }
    positionals.add(token);
  }
  if (!help && !version) {
    _addDefaults(registry, values);
    _validateRequired(registry, values);
    _validateConflicts(registry, values);
    _validateGroups(registry, values);
    _parsePositionals(registry, positionals, values);
    _validateVariadic(registry.variadic, trailing);
  }
  for (final flag in registry.applicableFlags) {
    if (flag is BooleanFlag && flag.name != 'help')
      values.putIfAbsent(flag, () => flag.defaultValue);
    if (flag is CountFlag) values.putIfAbsent(flag, () => 0);
  }
  _addAccessorMaps(registry, values);
  return (
    commandPath,
    ParsedInputs(values, _knownInputs(registry)),
    List.unmodifiable(trailing),
    help: help,
    version: version,
  );
}