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 <jvalleroy@mailbox.org>
[sunil: Add two more version comparison tests]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
James Valleroy 2022-09-03 19:30:59 -04:00 committed by Sunil Mohan Adapa
parent 49d77f20d7
commit 4920e33160
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
4 changed files with 73 additions and 7 deletions

View File

@ -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

View File

@ -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~')

View File

@ -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):

22
plinth/version.py Normal file
View File

@ -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