semver_parser 0.2.0 semver_parser: ^0.2.0 copied to clipboard
Provides an API to parse strings to Semantic Versions along with Semantic Version comparison logic.
import 'dart:io';
import 'package:semver_parser/src/semver.dart';
import 'src/command_history.dart';
import 'src/comparison_operator.dart';
import 'src/input_parser.dart';
// example app, no need for exhaustive documentation
// ignore_for_file: public_member_api_docs
const String printUsageStringKey = "usage";
final CommandHistory commandHistory = new CommandHistory();
InputParser inputParser;
/// Runs a CLI that reads from stdin and attempts to parse the input. Supports parsing input strings or various comparision operators.
///
/// To Run: 'dart example/semver_parser.dart' or 'pub run example/semver_parser.dart'.
///
/// This is intended as a demo or testing tool for the semver parsing in this library.
void main() {
// Setting this to false allows reading each byte as they come in without waiting for a return/line feed.
stdin.lineMode = false;
inputParser = new InputParser(handleStringInput, handleArrowInput, commandHistory);
printUsageOutput();
for (;;) {
stdout.writeln("Input?");
inputParser.readInput();
// add a blank line for spacing
stdout.writeln("");
}
}
final List<ComparisonOperator> supportedCompareOperators = [
new EqualityOperator(attemptSemverParse),
new NotEqualOperator(attemptSemverParse),
new LessThanOperator(attemptSemverParse),
new LessThanOrEqualOperator(attemptSemverParse),
new GreaterThanOperator(attemptSemverParse),
new GreaterThanOrEqualOperator(attemptSemverParse),
];
/// Prints out usage information about this example.
void printUsageOutput() {
stdout
..writeln("- Input a string to parse it.\n\tE.X. '1.2.3'")
..writeln("- Use the up and/or down arrow keys to move between previously run commands")
..writeln("- Use backspace to delete the previous character to edit the input");
for (var compareOp in supportedCompareOperators) {
stdout.writeln(compareOp.usageExample());
}
stdout.writeln("\nPrint this output again by inputting '$printUsageStringKey'\n");
}
/// Asks the user if they want to show usage information about this example.
bool shouldPrintUsageOutput() {
stdout.writeln("Print usage information and examples? (y or n)");
return stdin.readLineSync() == "y";
}
/// Handles an input string to parse or run through comparision operators.
void handleStringInput(String inputString) {
// If the input is the printUsageStringKey and the user confirms it, print usage information
if (inputString == printUsageStringKey && shouldPrintUsageOutput()) {
printUsageOutput();
return;
}
// add this command to history
commandHistory.addCommand(inputString);
// See if one (and only one) supported comparision operator matches the input and run it (assuming the user confirms it)
final compareOp = compareOperatorMatch(inputString);
if (compareOp != null && compareOp.shouldRunCompare()) {
compareOp.runCompare(inputString);
return;
}
// Try to parse the input as a single Semantic Version
attemptSemverParse(inputString);
}
/// Handle arrow keys by moving between previously run commands.
void handleArrowInput(bool isUpArrow) {
// if no previous commands, don't change the current text.
if (!commandHistory.hasCommandsInHistory()) {
inputParser.syncInputBytesToTerminal();
return;
}
var command = "";
if (isUpArrow) {
command = commandHistory.previousCommand();
} else {
command = commandHistory.nextCommand();
}
// clear any existing text, insert and sync the command from history
inputParser
..clearInputBytes()
..addInputBytes(command.codeUnits)
..syncInputBytesToTerminal();
}
/// Determines if one (and only one) [ComparisonOperator]s in [supportedCompareOperators] match the input.
/// Returns the [ComparisonOperator] that matched.
ComparisonOperator compareOperatorMatch(String input) {
final compareMatches = supportedCompareOperators.where((compare) => compare.matches(input));
if (compareMatches.length != 1) {
// too many or too few matches, do not try to handle the input
return null;
}
return compareMatches.elementAt(0);
}
/// Attempts to parse the [inputString] as a Semantic Version.
/// Writes the result (successfully or exception) to [stdout].
Semver attemptSemverParse(String inputString) {
Semver semver;
try {
semver = parseSemverString(inputString);
stdout.writeln("Parsed input ('$inputString') as Semantic Version: '$semver'");
} on SemverParseException catch (e) {
stdout.writeln("Parsed input ('$inputString') threw: '$e");
}
return semver;
}