1111
1212from .utils import logger , fail
1313
14+
1415@dataclass
1516class Require :
17+ """Requirement."""
18+
1619 name : str
1720 min_version : tuple
1821 mandatory : bool
@@ -28,6 +31,17 @@ class Require:
2831)
2932
3033
34+ def _version_tuple (version_str ):
35+ """Translate version into a tuple of int."""
36+ if not version_str :
37+ return None
38+ if "-" in version_str :
39+ version_str , * _ = version_str .rpartition ("-" )
40+ try :
41+ return tuple (int (i ) for i in version_str .split ("." ))
42+ except ValueError :
43+ return None
44+
3145
3246def check (name , min_version = None , mandatory = True ):
3347 """Check whether an app exists and whether its version is correct."""
@@ -43,27 +57,21 @@ def error(*args):
4357
4458 # Get version
4559 result = subprocess .run (
46- [app , "--version" ],
47- capture_output = True ,
48- text = True ,
60+ [app , "--version" ], capture_output = True , text = True , check = False
4961 )
5062 output = result .stdout .strip () or result .stderr .strip ()
5163 # Match version patterns like 1.2.3, 4.5, 2.0.1-alpha, etc.
52- match = re .search (r'\d+\.\d+(?:\.\d+)?(?:[-.\w]*)?' , output )
53- if match :
54- version = match .group (0 )
55- if '-' in version :
56- version , * _ = version .rpartition ("-" )
57- version = tuple (int (i ) for i in version .split ("." ))
58- version_str = "." .join (str (i ) for i in version )
64+ if match := re .search (r"\d+\.\d+(?:\.\d+)?(?:[-.\w]*)?" , output ):
65+ version_str = match .group (0 )
5966 else :
60- version = None
6167 version_str = None
6268
6369 # Check Version, if necessary
6470 if min_version :
6571 min_version_str = "." .join (str (i ) for i in min_version )
66- if not version :
72+
73+ # Translate version
74+ if not (version := _version_tuple (version_str )):
6775 return error ("Cannot read '%s' version" , name )
6876 if version < min_version :
6977 return error (
0 commit comments