semver_parser 0.2.0

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new49

semver_parser

Pub Documentation Build Status codecov License: MIT

A Dart library that provides an API to parse strings to Semantic Versions along with Semantic Version comparison logic. The library's semver parsing and comparison logic follows the Semantic Version 2.0.0 spec.

A note about the pub_semver package

This package (semver_parser) is NOT the official dartlang semver parsing package. This project is not endorsed, associated with or supported by the dartlang team. The pub_semver package is the official semver parsing library provided by the dartlang team and is used in many of the dart and pub tools (such as the version resolution done in a pub get command).

The pub_semver package follows a modified Semantic Version 2.0.0 spec to provide more logical version resolution, so if you want to use the same rules pub does, use the official pub_semver package. This package (semver_parser) is intending to implement the exact Semantic Version 2.0.0 spec, so this package's logic will differ from pub_semver's logic.

  • In the standard 2.0.0 spec, the version range '<2.0.0' would allow using the version '2.0.0-beta' which could lead to broken builds due to breaking changes in the '2.0.0-beta' branch.
  • In the pub modified spec, '<2.0.0' would not allow any '2.0.0-blah' versions to be used. '1.Last.Last' would be the last supported version.

It is also worth nothing the pub_semver is an officially supported package backed by a team of professional, dedicated, developers. This package (semver_parser) is a hobby project, and while I strive to deliver high quality, accurate code and address any bugs found, I cannot provide the same level of support as the official dartlang team can.

Semantic Version Parsing

This library can take an arbitrary string value and attempt to parse it into a single Semantic Version, represented by the Semver object. For a string to parse to a Semantic Version it must contain one, and only one, valid Semantic Version. Additional "noise" in the string will not affect the parse and will be dropped.

E.X.

  • '1.2.3' = Major: 1 Minor: 2 Patch: 3
  • 'react-16.3.2' = Major: 16 Minor: 3 Patch 2 ('react-' is ignored as it does not affect the Semantic Version)
  • 'California' = No Semantic Version, exception would be thrown.
  • '2.1.5 and 5.12.6' = Two potential Semantic Versions, exception would be thrown.
Note: Pre-Release information is not parsed currently, issue #17 will add support for parsing this information.
Note: Built metadata information is not parsed currently, issue #18 will add support for parsing this information.

Semantic Version Comparison Logic

Two Semver objects can be compared using the standard comparison operators such as ==, !=, <, <=, > or >=.

E.X.

  • '1.2.3' == '1.2.3' (true)
  • '4.3.1' != '4.3.1' (false)
  • '2.4.5' > '2.3.0' (true)
  • '2.4.5' >= '2.4.5' (true)
  • '1.12.43' < '1.12.42' (false)
  • '1.12.43' <= '1.12.43' (true)

Example Parsing

var versionOne = parseSemverString('some-12.5.3%thing');
var versionTwo = parseSemverString('11.5.12');

print(versionOne); // 12.5.3
print(versionTwo); // 11.5.12

print(versionOne == versionTwo); // true
print(versionOne < versionTwo); // false

Example Parsing App

An example app to test or demo semver string parsing is included under 'example/'. This app can be run using dart example/semver_parser.dart or pub run example/semver_parser.dart. The example app takes input from stdin and parses that input. Run the example to see more details about all its functions.

Releases/Roadmap

The 0.1.0 release has been made. Breaking changes are possible until a '1.x.y' release is made, please read all changelog notes to be safe. Additional pre-1.0.0 releases will increment the minor version (unless the change is non-functional in which case the patch version will be changed).

Release '1.0.0' will likely be made after support for parsing all Semantic Version information and comparison logic work is complete.

Contributing

Feel free to submit issues for any bugs, feature requests or questions in generally. Please provide as much information as possible so I can best help you out.

If you'd like to contribute, feel free to open pulls for changes. I'd suggest you read the contributing guide as well.

Changelog

0.2.0

  • The Semver object now supports the <, >, <= and >= operators (new public API).
  • Improved the usability of the example app.
  • This version contains no breaking changes.

0.1.0

  • Initial "real" published version of semver_parser.
  • Note this is still a pre-version 1 release and breaking changes are possible.
  • Supported features
    • Parsing of semver strings to major, minor and patch versions
      • Pre-release and metadata are not parsed yet (though including them will not break the parse)
    • == and != operators are support for comparing two Semver objects
      • No other comparision operators are supported

0.1.0-alpha

  • Initial published version of semver_parser.
  • Repo and code is fully functional, though some essential features are missing and some known bugs exist.
  • This is mainly tagged as a way to determine how to do the release process (tag, publish etc)
    • I would recommend waiting until the '0.1.0' release to depend on this package to be safe.

example/example.dart

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;
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  semver_parser: "^0.2.0"

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


      import 'package:semver_parser/semver_parser.dart';
  
Version Uploaded Documentation Archive
0.2.0 May 8, 2018 Go to the documentation of semver_parser 0.2.0 Download semver_parser 0.2.0 archive
0.1.0 May 2, 2018 Go to the documentation of semver_parser 0.1.0 Download semver_parser 0.1.0 archive
0.1.0-alpha May 2, 2018 Go to the documentation of semver_parser 0.1.0-alpha Download semver_parser 0.1.0-alpha archive

Analysis

We analyzed this package on May 14, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0-dev.54.0
  • pana: 0.10.6

Scores

Popularity:
Describes how popular the package is relative to other packages. [more]
0 / 100
Health:
Code health derived from static analysis. [more]
98 / 100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100 / 100
Overall score:
Weighted score of the above. [more]
49
Learn more about scoring.

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:semver_parser/semver_parser.dart.

Suggestions

  • Package is pre-v1 release.

    While there is nothing inherently wrong with versions of 0.*.*, it usually means that the author is still experimenting with the general direction API.

  • Fix analysis and formatting issues.

    Analysis or formatting checks reported 2 hints.

    Run dartfmt to format lib/src/semver.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.24.2 <2.0.0
Dev dependencies
coverage ^0.10.0
dart_dev ^1.9.2
dart_style ^1.0.9+1
dartdoc ^0.15.1
dependency_validator ^1.1.2
test ^0.12.34