diff --git a/pyproject.toml b/pyproject.toml index 09f619adb..8725da767 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,8 @@ dependencies = [ "ruamel.yaml", "jinja2", "GitPython", - "pvi~=0.8", # pvi currently tracks breaking changes with minor version + "semantic-version", + "pvi~=0.8", # pvi currently tracks breaking changes with minor version ] # Add project dependencies here, e.g. ["click", "numpy"] dynamic = ["version"] license.file = "LICENSE" diff --git a/src/ibek/__main__.py b/src/ibek/__main__.py index b2645ee83..8da04c60d 100644 --- a/src/ibek/__main__.py +++ b/src/ibek/__main__.py @@ -4,6 +4,7 @@ from ruamel.yaml import YAML from ibek._version import __version__ +from ibek.commands import semver_compare from ibek.dev_cmds.commands import dev_cli from ibek.globals import NaturalOrderGroup from ibek.ioc_cmds.commands import ioc_cli @@ -59,6 +60,24 @@ def main( """ +@cli.command() +def compare( + base: str = typer.Argument( + help='SemVer string e.g. "1.2.0"', + ), + target: str = typer.Argument( + help='An operator (<=,>=,==,<,>) followed by a SemVer string e.g.">=1.2.0"', + ), +): + """ + Compare two SemVer strings similarly to pip's requirements specifier syntax + """ + if semver_compare(base, target): + raise typer.Exit(code=0) + else: + raise typer.Exit(code=1) + + # test with: # pipenv run python -m ibek if __name__ == "__main__": diff --git a/src/ibek/commands.py b/src/ibek/commands.py new file mode 100644 index 000000000..84c214b1a --- /dev/null +++ b/src/ibek/commands.py @@ -0,0 +1,26 @@ +import operator + +from semantic_version import Version + + +def semver_compare(base: str, target: str) -> bool: + """ + Compare two semVer strings similarly to pip's requirements specifier syntax + """ + ops = { + ">=": operator.ge, + "<=": operator.le, + "==": operator.eq, + ">": operator.gt, + "<": operator.lt, + } + for op in ops.keys(): + if op in target: + in_op = op + target = target.strip(op) + break + + if ops[in_op](Version.coerce(base), Version.coerce(target)): + return True + else: + return False diff --git a/tests/test_unit.py b/tests/test_unit.py index 6b30201ce..ee5b90624 100644 --- a/tests/test_unit.py +++ b/tests/test_unit.py @@ -2,6 +2,7 @@ Some unit tests for ibek. """ +from ibek.commands import semver_compare from ibek.ioc import ( clear_entity_model_ids, id_to_entity, @@ -53,3 +54,12 @@ def test_object_references(): assert device.type == "mymodule.device" assert device.port is port assert id_to_entity == {"PORT": port} + + +def test_compare(): + """ + Verify the SemVer comparrisons work + """ + assert semver_compare("1.1.1", "==1.1.1") + assert semver_compare("1.1.1", ">=1.1.0") + assert not semver_compare("1.1.1", ">=1.1.2")