-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpacktuple.py
230 lines (182 loc) · 6.23 KB
/
packtuple.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# -*- coding: utf-8 -*-
import typing
from typing import *
min_py = (3, 8)
###
# Standard imports, starting with os and sys
###
import os
import sys
if sys.version_info < min_py:
print(f"This program requires Python {min_py[0]}.{min_py[1]}, or higher.")
sys.exit(os.EX_SOFTWARE)
###
# Other standard distro imports
###
import argparse
import contextlib
from functools import total_ordering
import getpass
import re
mynetid = getpass.getuser()
###
# From hpclib
###
from dorunrun import dorunrun
import linuxutils
from urdecorators import trap
###
# imports and objects that are a part of this project
###
verbose = False
###
# Credits
###
__author__ = "Alina Enikeeva"
__copyright__ = 'Copyright 2022'
__credits__ = None
__version__ = 0.1
__maintainer__ = "ALina Enikeeva"
__email__ = ["[email protected]"]
__status__ = 'in progress'
__license__ = 'MIT'
class CompareTuple: pass
@trap
def packtuple(packagename: str) -> tuple:
"""
Breaks down a packagename into parts and converts it into the tuple.
"""
#some packages have svn12345 as their major. Find them first. If the package name does not contain svn12345, use another pattern
#38.20130427_r30134.el7.noarch package name does not fit in either of the two packname patterns.
packname = re.search(r'.*(?=\b\-svn\d+\b)', packagename)
if packname == None:
packname = re.search(r'^[\w+\-]+([^?=\0-9])', packagename)
#print(packagename)
mmp = re.search(r'\d+\.\d+\.\d+|\d+\.\d+', packagename) #major, minor and patch all together
datum = re.search(r'\-\w+.*?(\-\d+)', packagename)
myOS = re.search(r'el\d', packagename) #####rename the variable!!! use myOS instead
architecture = re.search(r'\w+$', packagename)
#assign None values to variables that were not matched
#.group() allows to display an actual string matched, rather than an address of the match
try:
packname = packname.group()
except:
packname = None
try:
mmp = mmp.group().split(".")
if len(mmp)==3: # all three - major, minor and patch are present in the package name
major = mmp[0]
minor = mmp[1]
patch = mmp[2]
elif len(mmp)==2: # only major and minor are present
major = mmp[0]
minor = mmp[1]
patch = None
elif len(mmp)==1: #only major is present
major = mmp[0]
minor = None
patch = None
except:
major = None
minor = None
patch = None
try:
datum = datum.group(1).split("-")[1] # regex for datum matches two groups. We are interested in group 1, that is
# why we do .group(1). Regex also matches a dash in front of the datum
# we split on "-" to extract the datum (the number) only
except:
datum = None
try:
myOS = myOS.group()
except:
myOS = None
try:
architecture = architecture.group()
except:
architecture = None
try:
return tuple((packname, major, minor, patch, datum, myOS, architecture,))
except:
return "non-standard package name "+ packagename
@total_ordering
class CompareTuple:
"""
This class compares packagenames.
"""
def __init__(self, pkgname:str):
self.packfull = pkgname #full packagename
self.packtuple = packtuple(pkgname)
self.OK = None not in self.packtuple[:3]
def __bool__(self) -> bool:
"""
Determines if the packagename can be used for comparison.
Comparison of the packages is possible only for standatd package names.
Standard package names contain at least name, major and minor.
"""
return self.OK
def __eq__(self, other:object) -> bool:
"""
Compares name, major and minor of the packages.
"""
other = CompareTuple(other)
if self.OK and other.OK: #check if both are instances of a tuple
return self.getTuple==other.getTuple
def __lt__(self, other:object) -> bool:
"""
Returns True if the version of the self object is lower than the version of the other object.
"""
other = CompareTuple(other)
if self.OK and other.OK:
if self.getPackname==other.getPackname:
return (self.getMajor, self.getMinor) < (other.getMajor, other.getMinor)
def __str__(self) -> str:
return self.packfull
@property
def getPackname(self) -> str:
"""
Returns packagename.
"""
return self.packtuple[0]
@property
def getMajor(self) -> str:
"""
Returns major of the package.
"""
return self.packtuple[1]
@property
def getMinor(self) -> str:
"""
Returns minor of the package.
"""
return self.packtuple[2]
@property
def getTuple(self) -> tuple:
"""
Returns tuple for approximate comparison.
Tuple contains name, major and minor of the package.
"""
return self.getPackname, self.getMajor, self.getMinor
@trap
def packtuple_main(myargs:argparse.Namespace) -> int:
obj = CompareTuple("yelp-3.28.1-1.el7.x86_64")
obj2 = "yel-3.28.1-2.el7.x86_64"
print(obj==obj2)
print(str(obj))
return os.EX_OK
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog="packtuple",
description="What packtuple does, packtuple does best.")
parser.add_argument('-i', '--input', type=str, default="",
help="Input file name.")
parser.add_argument('-o', '--output', type=str, default="",
help="Output file name")
parser.add_argument('-v', '--verbose', action='store_true',
help="Be chatty about what is taking place")
myargs = parser.parse_args()
verbose = myargs.verbose
try:
outfile = sys.stdout if not myargs.output else open(myargs.output, 'w')
with contextlib.redirect_stdout(outfile):
sys.exit(globals()[f"{os.path.basename(__file__)[:-3]}_main"](myargs))
except Exception as e:
print(f"Escaped or re-raised exception: {e}")