From 4920e33160519b39f4d788a2655464dd908a7ee4 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Sat, 3 Sep 2022 19:30:59 -0400 Subject: [PATCH] version: Compare Debian package version numbers Provides a Version class wrapper around apt_pkg.version_compare. Replaces distutils.version which is deprecated. Closes: #2261. Tests: - Install ejabberd. Signed-off-by: James Valleroy [sunil: Add two more version comparison tests] Signed-off-by: Sunil Mohan Adapa Reviewed-by: Sunil Mohan Adapa --- actions/ejabberd | 8 +++---- plinth/tests/test_version.py | 45 ++++++++++++++++++++++++++++++++++++ plinth/utils.py | 5 ++-- plinth/version.py | 22 ++++++++++++++++++ 4 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 plinth/tests/test_version.py create mode 100644 plinth/version.py diff --git a/actions/ejabberd b/actions/ejabberd index f9d9aed35..42de818f5 100755 --- a/actions/ejabberd +++ b/actions/ejabberd @@ -12,20 +12,20 @@ import shutil import socket import subprocess import sys -from distutils.version import LooseVersion as LV from pathlib import Path from ruamel.yaml import YAML, scalarstring from plinth import action_utils +from plinth.version import Version EJABBERD_CONFIG = '/etc/ejabberd/ejabberd.yml' EJABBERD_BACKUP = '/var/log/ejabberd/ejabberd.dump' EJABBERD_BACKUP_NEW = '/var/log/ejabberd/ejabberd_new.dump' EJABBERD_ORIG_CERT = '/etc/ejabberd/ejabberd.pem' EJABBERD_MANAGED_COTURN = '/etc/ejabberd/freedombox_managed_coturn' -IQDISC_DEPRECATED_VERSION = LV('18.03') -MOD_IRC_DEPRECATED_VERSION = LV('18.06') +IQDISC_DEPRECATED_VERSION = Version('18.03') +MOD_IRC_DEPRECATED_VERSION = Version('18.06') yaml = YAML() yaml.allow_duplicate_keys = True @@ -433,7 +433,7 @@ def _get_version(): version_info = output.strip().split('\n')[-1].split() if version_info: version = str(version_info[1]) - return LV(version) + return Version(version) return None diff --git a/plinth/tests/test_version.py b/plinth/tests/test_version.py new file mode 100644 index 000000000..954839bd1 --- /dev/null +++ b/plinth/tests/test_version.py @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +""" +Tests for Version class. +""" + +from plinth.version import Version + + +def test_version_comparisons(): + """Test comparing Debian package version numbers.""" + assert Version('3.1.8-1') == Version('3.1.8-1') + assert Version('3.1.8-1') <= Version('4~') + assert Version('3.1.8-1') < Version('4~') + assert Version('4.0.0-1') >= Version('4~') + assert Version('4.0') >= Version('4~') + assert Version('4.0.0-1') > Version('4~') + assert Version('4.0') > Version('4~') + + +def test_backport_versions(): + """Test comparing Debian backports package version numbers.""" + assert Version('3.1.7-1~bpo11+1') == Version('3.1.7-1~bpo11+1') + assert Version('3.1.7-1~bpo11+1') <= Version('4~') + assert Version('3.1.7-1~bpo11+1') < Version('4~') + assert Version('4.0.0-1~bpo11+1') >= Version('4~') + assert Version('4.0.0-1~bpo11+1') > Version('4~') + + +def test_dfsg_versions(): + """Test comparing Debian DFSG package version numbers.""" + assert Version('1.3.0+dfsg-2.2') == Version('1.3.0+dfsg-2.2') + assert Version('1.3.0+dfsg-2.2') <= Version('1.4~') + assert Version('1.3.0+dfsg-2.2') < Version('1.4~') + assert Version('1.4.0+dfsg-1.1') >= Version('1.4~') + assert Version('1.4.0+dfsg-1.1') > Version('1.4~') + + +def test_git_versions(): + """Test comparing Debian git package version numbers.""" + assert Version('21~git20210204.b4cbc79+dfsg-1') == \ + Version('21~git20210204.b4cbc79+dfsg-1') + assert Version('21~git20210204.b4cbc79+dfsg-1') <= Version('22~') + assert Version('21~git20210204.b4cbc79+dfsg-1') < Version('22~') + assert Version('22~git20210204.b4cbc79+dfsg-1') >= Version('22~') + assert Version('22~git20210204.b4cbc79+dfsg-1') > Version('22~') diff --git a/plinth/utils.py b/plinth/utils.py index 34b1db425..6f0f6043b 100644 --- a/plinth/utils.py +++ b/plinth/utils.py @@ -9,13 +9,12 @@ import os import random import re import string -from distutils.version import LooseVersion import markupsafe import ruamel.yaml from django.utils.functional import lazy -Version = LooseVersion # Abstraction over distutils.version.LooseVersion +from plinth.version import Version def import_from_gi(library, version): @@ -184,7 +183,7 @@ def is_axes_old(): # axes.get_version() was removed in 5.0.13 return False - return LooseVersion(version) < LooseVersion('5.0') + return Version(version) < Version('5.0') def is_authenticated_user(username, password): diff --git a/plinth/version.py b/plinth/version.py new file mode 100644 index 000000000..7b98f7f5a --- /dev/null +++ b/plinth/version.py @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +""" +Compare Debian package version numbers. +""" + +from functools import total_ordering + +from apt import apt_pkg + + +@total_ordering +class Version: + """The version number of a Debian package.""" + + def __init__(self, version: str): + self.version = version + + def __eq__(self, other): + return apt_pkg.version_compare(self.version, other.version) == 0 + + def __lt__(self, other): + return apt_pkg.version_compare(self.version, other.version) < 0