Files
dotfiles/local/bin/x-compare-versions.py

74 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python
"""
Version Comparison tool for the CLI.
Adapted from script found in anishathalye's dotfiles.
https://github.com/anishathalye/dotfiles/blob/master/bin/vercmp
"""
import operator
import sys
from packaging import version
str_to_operator = {
"==": operator.eq,
"!=": operator.ne,
"<": operator.lt,
"<=": operator.le,
">": operator.gt,
">=": operator.ge,
}
def vercmp(expr):
"""Version Comparison function."""
words = expr.split()
comparisons = [words[i: i + 3] for i in range(0, len(words) - 2, 2)]
for left, op_str, right in comparisons:
compare_op = str_to_operator[op_str]
if not compare_op(version.parse(left), version.parse(right)):
return False
return True
def main():
"""Triggers version comparison if line is provided."""
for line in sys.stdin:
if not vercmp(line):
sys.exit(1)
sys.exit(0)
def test():
"""Basic functionality tests."""
assert not vercmp("1.9 >= 2.4")
assert vercmp("2.4 >= 2.4")
assert vercmp("2.5 >= 2.4")
assert vercmp("3 >= 2.999")
assert vercmp("2.9a < 2.9")
assert vercmp("2.9a >= 2.8")
# multiple comparisons in a single expression
assert vercmp("1.0 < 2.0 <= 2.0")
assert not vercmp("1.0 > 2.0 < 3.0")
# mixed major/minor version comparisons
assert vercmp("2 >= 1.5")
assert not vercmp("1 < 1.0")
# invalid operator should raise an error
try:
vercmp("1.0 <> 2.0")
except KeyError:
pass
else:
assert False, "invalid operator did not raise"
if __name__ == "__main__":
if len(sys.argv) == 2 and sys.argv[1] == "test":
test()
else:
main()