]> git.mxchange.org Git - fba.git/blob - fba/helpers/version.py
Continued:
[fba.git] / fba / helpers / version.py
1 # Copyright (C) 2023 Free Software Foundation
2 #
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License as published
5 # by the Free Software Foundation, either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU Affero General Public License for more details.
12 #
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16 import re
17
18 # Pattern instance for version numbers
19 patterns = [
20     # semantic version number (with v|V) prefix)
21     re.compile("^(?P<version>v|V{0,1})(\.{0,1})(?P<major>0|[1-9]\d*)\.(?P<minor>0+|[1-9]\d*)(\.(?P<patch>0+|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)?$"),
22     # non-sematic, e.g. 1.2.3.4
23     re.compile("^(?P<version>v|V{0,1})(\.{0,1})(?P<major>0|[1-9]\d*)\.(?P<minor>0+|[1-9]\d*)(\.(?P<patch>0+|[1-9]\d*)(\.(?P<subpatch>0|[1-9]\d*))?)$"),
24     # non-sematic, e.g. 2023-05[-dev]
25     re.compile("^(?P<year>[1-9]{1}[0-9]{3})\.(?P<month>[0-9]{2})(-dev){0,1}$"),
26     # non-semantic, e.g. abcdef0
27     re.compile("^[a-f0-9]{7}$"),
28 ]
29
30 def remove(software: str) -> str:
31     # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
32     if not "." in software and " " not in software:
33         print(f"WARNING: software='{software}' does not contain a version number.")
34         return software
35
36     temp = software
37     if ";" in software:
38         temp = software.split(";")[0]
39     elif "," in software:
40         temp = software.split(",")[0]
41     elif " - " in software:
42         temp = software.split(" - ")[0]
43
44     # DEBUG: print(f"DEBUG: software='{software}'")
45     version = None
46     if " " in software:
47         version = temp.split(" ")[-1]
48     elif "/" in software:
49         version = temp.split("/")[-1]
50     elif "-" in software:
51         version = temp.split("-")[-1]
52     else:
53         # DEBUG: print(f"DEBUG: Was not able to find common seperator, returning untouched software='{software}'")
54         return software
55
56     match = None
57     # DEBUG: print(f"DEBUG: Checking {len(patterns)} patterns ...")
58     for pattern in patterns:
59         # Run match()
60         match = pattern.match(version)
61
62         # DEBUG: print(f"DEBUG: match[]='{type(match)}'")
63         if isinstance(match, re.Match):
64             # DEBUG: print(f"DEBUG: version='{version}' is matching pattern='{pattern}'")
65             break
66
67     # DEBUG: print(f"DEBUG: version[{type(version)}]='{version}',match='{match}'")
68     if not isinstance(match, re.Match):
69         print(f"WARNING: version='{version}' does not match regex, leaving software='{software}' untouched.")
70         return software
71
72     # DEBUG: print(f"DEBUG: Found valid version number: '{version}', removing it ...")
73     end = len(temp) - len(version) - 1
74
75     # DEBUG: print(f"DEBUG: end[{type(end)}]={end}")
76     software = temp[0:end].strip()
77     if " version" in software:
78         # DEBUG: print(f"DEBUG: software='{software}' contains word ' version'")
79         software = strip_until(software, " version")
80
81     # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
82     return software
83
84 def strip_powered_by(software: str) -> str:
85     # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
86     if not isinstance(software, str):
87         raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
88     elif software == "":
89         raise ValueError("Parameter 'software' is empty")
90     elif "powered by" not in software:
91         print(f"WARNING: Cannot find 'powered by' in software='{software}'!")
92         return software
93
94     start = software.find("powered by ")
95     # DEBUG: print(f"DEBUG: start[{type(start)}]='{start}'")
96
97     software = software[start + 11:].strip()
98     # DEBUG: print(f"DEBUG: software='{software}'")
99
100     software = strip_until(software, " - ")
101
102     # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
103     return software
104
105 def strip_hosted_on(software: str) -> str:
106     # DEBUG: print(f"DEBUG: software='{software}' - CALLED!")
107     if not isinstance(software, str):
108         raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
109     elif software == "":
110         raise ValueError("Parameter 'software' is empty")
111     elif "hosted on" not in software:
112         print(f"WARNING: Cannot find 'hosted on' in '{software}'!")
113         return software
114
115     end = software.find("hosted on ")
116     # DEBUG: print(f"DEBUG: end[{type(end)}]='{end}'")
117
118     software = software[0, end].strip()
119     # DEBUG: print(f"DEBUG: software='{software}'")
120
121     software = strip_until(software, " - ")
122
123     # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
124     return software
125
126 def strip_until(software: str, until: str) -> str:
127     # DEBUG: print(f"DEBUG: software='{software}',until='{until}' - CALLED!")
128     if not isinstance(software, str):
129         raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'")
130     elif software == "":
131         raise ValueError("Parameter 'software' is empty")
132     elif not isinstance(until, str):
133         raise ValueError(f"Parameter until[]='{type(until)}' is not 'str'")
134     elif until == "":
135         raise ValueError("Parameter 'until' is empty")
136     elif not until in software:
137         print(f"WARNING: Cannot find '{until}' in '{software}'!")
138         return software
139
140     # Next, strip until part
141     end = software.find(until)
142
143     # DEBUG: print(f"DEBUG: end[{type(end)}]='{end}'")
144     if end > 0:
145         software = software[0:end].strip()
146
147     # DEBUG: print(f"DEBUG: software='{software}' - EXIT!")
148     return software