parse method
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,
);
}