usage method
Return a string telling the user how to use your application from the command line.
Implementation
String usage() {
List<String?> lines = [];
if (isNotNull(_app?.description)) {
lines.add(_app!.description);
lines.add('');
}
List<String> helpKeys = [];
List<Group?> helpGroups = [];
List<List<String>> helpDescriptions = [];
final arguments =
_mirrorParameterPairs.where((v) => isFalse(v.argument is Command));
final commands = _mirrorParameterPairs.where((v) => v.argument is Command);
if (arguments.isNotEmpty) {
for (var mpp in arguments) {
List<String?> keys = [];
keys.addAll(mpp.keys(_app).map((v) => v!.startsWith('-') ? v : '--$v'));
helpKeys.add(keys.join(', '));
helpGroups.add(mpp.group);
List<String> helpLines = [mpp.argument.help ?? 'no help available'];
if (mpp.argument.isRequired ?? false) {
helpLines.add('[REQUIRED]');
}
String? envVar = mpp.argument.environmentVariable;
if (isNotBlank(envVar)) {
helpLines.add('[Environment Variable: \$$envVar]');
}
helpLines.addAll(mpp.argument.additionalHelpLines);
helpDescriptions.add(helpLines);
}
}
const lineIndent = 2;
const lineWidth = 80 - lineIndent;
final linePrefix = ' ' * lineIndent;
const optionColumnWidth = 25;
const helpLineWidth = lineWidth - optionColumnWidth;
{
void trailingHelp(Group? group) {
if (isNotNull(group?.afterHelp)) {
lines.add('');
lines.add(
indent(
hardWrap(group!.afterHelp!, lineWidth - lineIndent),
lineIndent,
),
);
}
}
Group? currentGroup;
for (var i = 0; i < helpKeys.length; i++) {
final thisGroup = helpGroups[i];
if (thisGroup != currentGroup) {
trailingHelp(currentGroup);
if (isNotNull(currentGroup)) {
lines.add('');
}
lines.add(thisGroup!.name);
if (isNotNull(thisGroup.beforeHelp)) {
lines.add(
indent(
hardWrap(thisGroup.beforeHelp!, lineWidth - lineIndent),
lineIndent,
),
);
lines.add('');
}
}
var keyDisplay = linePrefix + helpKeys[i];
var thisHelpDescriptions = helpDescriptions[i].join('\n');
thisHelpDescriptions = hardWrap(thisHelpDescriptions, helpLineWidth);
thisHelpDescriptions = indent(thisHelpDescriptions, optionColumnWidth);
if (keyDisplay.length <= optionColumnWidth - 1) {
thisHelpDescriptions = thisHelpDescriptions.replaceRange(
0,
keyDisplay.length,
keyDisplay,
);
} else {
lines.add(keyDisplay);
}
lines.add(thisHelpDescriptions);
currentGroup = helpGroups[i] ?? currentGroup;
}
trailingHelp(currentGroup);
}
if (commands.isNotEmpty) {
lines.add('');
lines.add('COMMANDS');
List<MirrorParameterPair>.from(commands)
.sortedBy((mpp) => mpp.displayKey!)
.forEach((mpp) {
final String? help = _argumentHelp(mpp);
final commandDisplay = '$linePrefix${mpp.displayKey!}';
var commandHelp = hardWrap(
help ?? '',
helpLineWidth,
);
commandHelp = indent(commandHelp, optionColumnWidth);
if (commandDisplay.length <= optionColumnWidth - 1) {
commandHelp = commandHelp.replaceRange(
0,
commandDisplay.length,
commandDisplay,
);
} else {
lines.add(commandDisplay);
}
lines.add(commandHelp);
});
}
if (isNotNull(_app?.extendedHelp)) {
for (final eh in _app!.extendedHelp!) {
if (isNull(eh.help)) {
throw StateError('Help.help must be set');
}
lines.add('');
if (isNotNull(eh.header)) {
lines.add(hardWrap(eh.header!, lineWidth));
lines.add(
indent(hardWrap(eh.help!, lineWidth - lineIndent), lineIndent),
);
} else {
lines.add(hardWrap(eh.help!, lineWidth));
}
}
}
return lines.join('\n');
}