This repository contains a fully tested and easily extendable function to compare semantic versions. See the corresponding presentation for more details on the function as well as semantic versioning.
A semantic versioning comparator compare(version_1, version_2)
is implemented which
- accepts two version strings, referred to as
version_1
andversion_2
- every version string may only contain integer numbers and dots
- every version string must start with an integer
version_1
must also contain a leading comparator out of a list of known comparators- known comparators are
=
,>
, and>=
- return values are only
True
orFalse
The following assumptions were made:
version_1
is the only version string which contains a comparator- The question answered by
compare(version_1, version_2)
is "version_2
version_1
"; i.e.compare('>=1.0', '1.1')
answers the question of'1.1''>=1.0'
- versions cannot be empty
- Version numbers are compared from left to right, split at "."
The compare(version_1, version_2)
was implemented in standard Python 2.7 by
- Splitting the comparator from
version_1
and passing it on the corresponding comparator class - Parsing
version_1
andversion_2
into lists of integers, splitting them at the "." symbol - Handing the two parsed versions to the previously detected comparator and return the result
Should any of the above steps fail, a detailed error message is being displayed.
As the implementation relies on list comparison, all limitations of standard Python 2.7.13 list comparision apply.
The task was implemented with extendability in mind. Adding a new comparator is fairly straightforward. All that needs to be done is use of the existing comparators as a template and provide the comparator specific
SYMBOL
as well ascompare
method.
The comparator is then made available by adding it to the KNOWN_SYMBOLS_TO_COMPARATORS_MAPPING
in the VersionComparator
class.
Should the power of the Version
class be leveraged, then the corresponding magic method in the Version
class has to be provided.
As the compare(version_1, version_2)
function does not provide any main functionality, the tests (and associated logging output) provide some insight.
Run the tests from the base directory of this project via
python -m unittest discover tests/
Note: Base Class tests are skipped on purpose as the tests require a comparator to be meaningful.
Just as the actual application is written with extendability in mind, so are the tests. Adding a new comparator is again fairly straightforward. All that needs to be done is use of the existing comparator test cases as a template and provide the comparator specific private methods. All other functional tests are included in the base version test as they are common across all comparators.
The function compare(version_1, version_2)
can be used directly after importing as outlined in the minimum example
from main import compare
print compare('>3.14.159', '3.14.159.2653')
When run via
python minimum_example.py
the following output is printed
2017-09-17 19:21:06,057 - root - INFO - Found comparator ">" and version "3.14.159" in string ">3.14.159"
2017-09-17 19:21:06,058 - root - INFO - Found matching class "<class 'comparators.strictly_greater.StrictlyGreater'>" for string ">"
2017-09-17 19:21:06,058 - root - INFO - Comparing Versions: 3.14.159.2653 > 3.14.159 : True
True
Here, the last True
corresponds to the expected output of the compare('>3.14.159', '3.14.159.2653')
function as also indicated by the preceding info log message.
The application does come with a settings.py
module which mainly provides logging setup. It expects to be able to create a directory .logs
(if not already present) and writes its logs to that directory as well.