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 socket
import subprocess import subprocess
import sys import sys
from distutils.version import LooseVersion as LV
from pathlib import Path from pathlib import Path
from ruamel.yaml import YAML, scalarstring from ruamel.yaml import YAML, scalarstring
from plinth import action_utils from plinth import action_utils
from plinth.version import Version
EJABBERD_CONFIG = '/etc/ejabberd/ejabberd.yml' EJABBERD_CONFIG = '/etc/ejabberd/ejabberd.yml'
EJABBERD_BACKUP = '/var/log/ejabberd/ejabberd.dump' EJABBERD_BACKUP = '/var/log/ejabberd/ejabberd.dump'
EJABBERD_BACKUP_NEW = '/var/log/ejabberd/ejabberd_new.dump' EJABBERD_BACKUP_NEW = '/var/log/ejabberd/ejabberd_new.dump'
EJABBERD_ORIG_CERT = '/etc/ejabberd/ejabberd.pem' EJABBERD_ORIG_CERT = '/etc/ejabberd/ejabberd.pem'
EJABBERD_MANAGED_COTURN = '/etc/ejabberd/freedombox_managed_coturn' EJABBERD_MANAGED_COTURN = '/etc/ejabberd/freedombox_managed_coturn'
IQDISC_DEPRECATED_VERSION = LV('18.03') IQDISC_DEPRECATED_VERSION = Version('18.03')
MOD_IRC_DEPRECATED_VERSION = LV('18.06') MOD_IRC_DEPRECATED_VERSION = Version('18.06')
yaml = YAML() yaml = YAML()
yaml.allow_duplicate_keys = True yaml.allow_duplicate_keys = True
@ -433,7 +433,7 @@ def _get_version():
version_info = output.strip().split('\n')[-1].split() version_info = output.strip().split('\n')[-1].split()
if version_info: if version_info:
version = str(version_info[1]) version = str(version_info[1])
return LV(version) return Version(version)
return None 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 random
import re import re
import string import string
from distutils.version import LooseVersion
import markupsafe import markupsafe
import ruamel.yaml import ruamel.yaml
from django.utils.functional import lazy from django.utils.functional import lazy
Version = LooseVersion # Abstraction over distutils.version.LooseVersion from plinth.version import Version
def import_from_gi(library, version): def import_from_gi(library, version):
@ -184,7 +183,7 @@ def is_axes_old():
# axes.get_version() was removed in 5.0.13 # axes.get_version() was removed in 5.0.13
return False return False
return LooseVersion(version) < LooseVersion('5.0') return Version(version) < Version('5.0')
def is_authenticated_user(username, password): 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