#!/usr/bin/env python
import re
import warnings
from toolchest.rpm.rpmvercmp import labelCompare as rpmLabelCompare
[docs]def split_filename_fast(nvr):
info = nvr.rsplit('-', 2)
return (info[0], info[1], info[2])
# rpmUtils.miscutils and
# dnf.rpm.miscutils are bugged for several types of valid
# rpm names
[docs]def splitFilename(nvr):
#
# If we have a full rpm name, we'll have an arch
# or src -
# foo-1.2-1.f23.noarch.rpm - 2 dots - arch exists
# foo-1.2-1.f23.noarch - 2 dots - arch exists
# foo-1.2-1.noarch.rpm - 1 dot, arch exists, no disttag
# foo-1.2-1.f23 - 1 dot... not 100% deterministic, but
# likely .f23 is a disttag; very rare
# 1.2-1.f23 - no name, just v, r
# 1:1.2-1.f23 - no name, just e, v, r
# 1:foo-1.2-1.f23 - no name, just e, v, r
#
# Junk .rpm if it exists
if nvr[-4:] == '.rpm':
nvr = nvr[:-4]
#
# Any field may be absent
#
n = ''
v = ''
r = ''
e = ''
a = ''
# Determine arch in a deterministic way
arches = ['noarch', 'x86_64', 'i386', 'i486', 'i586',
'i686', 'ppc', 'ppc64', 'ppc64le', 's390',
's390x', 'aarch64', 'src']
arch_rx = r'\.(' + '|'.join(arches) + ')$'
if re.search(arch_rx, nvr):
x = nvr.rfind('.')
a = nvr[x + 1:]
if a == 'src':
# src is not an arch; we just use it for
# determinism
a = ''
nvr = nvr[:x]
tmp = nvr
#
# version & release are after two last dashes, respectively
# Get 'release' first
#
x = tmp.rfind('-')
if x < 0:
#
# maybe someone provided just a version?
#
if tmp.rfind('.') >= 0:
v = tmp
else:
n = tmp
return n, v, r, e, a
# Release
r = tmp[x + 1:]
tmp = tmp[:x]
x = tmp.rfind('-')
if x < 0:
#
# Someone just provided version-release?
#
v = tmp
return n, v, r, e, a
#
# epoch can be in version or in rpm name
# Check version first
#
version = tmp[x + 1:]
tmp = tmp[:x]
x = version.rfind(':')
if x > 0:
e = version[:x]
v = version[x + 1:]
else:
v = version
x = tmp.rfind(':')
if x > 0:
# We don't want to crash tools if someone
# somehow got a weird nvr
# if e != '':
# raise ValueError
e = tmp[:x]
n = tmp[x + 1:]
else:
n = tmp
return n, v, r, e, a
# Preserve old function name
[docs]def split_filename(nvr):
return splitFilename(nvr)
[docs]def dlrn_label_compare(left, right):
warnings.warn("dlrn_label_compare() is deprecated; use label_compare().",
DeprecationWarning)
if type(left) is not tuple or type(right) is not tuple:
raise ValueError('dlrn_label_compare requires two tuples')
l_is_dlrn = False
r_is_dlrn = False
l_is_rc = False
r_is_rc = False
l_is_ga = False
r_is_ga = False
lx = left[0]
lv = left[1]
lr = left[2]
dlrn_regex = r'^[012](\.[0-9]{1,2})?\.[0-9]{14}\.[0-9a-f]{7}\.'
if re.match(dlrn_regex, lr):
l_is_dlrn = True
elif re.match(r'^0\.[0-9]{1,2}\.0rc[123](\.|$)', lr):
l_is_rc = True
elif re.match(r'^0\.[0-9]{1,2}(\.|$)', lr):
l_is_ga = True
rx = right[0]
rv = right[1]
rr = right[2]
if re.match(dlrn_regex, rr):
r_is_dlrn = True
elif re.match(r'^0\.[0-9]{1,2}\.0rc[123](\.|$)', rr):
r_is_rc = True
elif re.match(r'^0\.[0-9]{1,2}(\.|$)', rr):
r_is_ga = True
if r_is_dlrn == l_is_dlrn:
return (rpmLabelCompare(left, right), False)
altered = False
if l_is_dlrn:
if r_is_rc:
# print 'fudging DLRN release for right to 1 (RC build)'
rr = '1'
altered = True
if r_is_ga:
# print 'fudging DLRN release for left to 0 (GA build)'
lr = '0'
altered = True
if rv[:-1] == lv[:-1] and \
ord(lv[-1:]) - ord(rv[-1:]) == 1:
# print 'fudging DLRN build version (type 1l)'
return (rpmLabelCompare((lx, rv, lr), (rx, rv, rr)), True)
x = lv.rfind('.')
if lv[:x] == rv:
# 6.2-2.el6ost > 6.2.1-0.20171313131313
# print 'fudging DLRN build version (type 2l.b)'
return (rpmLabelCompare((lx, lv, lr), (rx, lv, rr)), True)
if lv[:x] == rv[:x]:
# 6.0.9-1.el7ost > 6.0.10-0.201713131313131
lm = int(lv[x + 1:])
rm = int(rv[x + 1:])
if (lm - rm) == 1:
# print 'fudging DLRN build version (type 2l)'
return (rpmLabelCompare((lx, lv, lr), (rx, lv, rr)), True)
if r_is_dlrn:
if l_is_rc:
# print 'fudging DLRN release for left to 1 (RC build)'
lr = '1'
altered = True
if l_is_ga:
# print 'fudging DLRN release for right to 0 (GA build)'
rr = '0'
altered = True
if rv[:-1] == lv[:-1] and \
ord(rv[-1:]) - ord(lv[-1:]) == 1:
# print 'fudging DLRN build version (type 1r)'
return (rpmLabelCompare((lx, lv, lr), (rx, lv, rr)), True)
x = rv.rfind('.')
if rv[:x] == lv:
# 6.2.1-0.20171313131313 < 6.2-2.el7ost
# print 'fudging DLRN build version (type 2r.b)'
return (rpmLabelCompare((lx, lv, lr), (rx, lv, rr)), True)
if lv[:x] == rv[:x]:
# 6.0.10-0.201713131313131 < 6.0.9-1.el7ost
lm = int(lv[x + 1:])
rm = int(rv[x + 1:])
if (rm - lm) == 1:
# print 'fudging DLRN build version (type 2r)'
return (rpmLabelCompare((lx, lv, lr), (rx, lv, rr)), True)
# Version are equal, but maybe we altered release
return (rpmLabelCompare((lx, lv, lr), (rx, rv, rr)), altered)
[docs]def cpaas_label_compare(left, right):
if type(left) is not tuple or type(right) is not tuple:
raise ValueError('cpaas_label_compare requires two tuples')
if len(left) != 3 or len(right) != 3:
raise ValueError('cpaas_label_compare requires two tuples of length 3')
rx = re.compile(r'\.[0-9]+$')
l_m = rx.search(left[2])
r_m = rx.search(right[2])
if l_m:
l_r = left[2][0:l_m.span()[0]]
else:
l_r = left[2]
if r_m:
r_r = right[2][0:r_m.span()[0]]
else:
r_r = right[2]
return rpmLabelCompare((left[0], left[1], l_r), (right[0], right[1], r_r))
[docs]def label_compare(left, right):
return rpmLabelCompare(left, right)
# Preserve old method name
[docs]def labelCompare(left, right):
return label_compare(left, right)
[docs]def drop_epoch(nevra):
(n, v, r, e, a) = splitFilename(nevra)
nvra = '-'.join([x for x in [n, v, r] if x != ''])
if a:
nvra = f'{nvra}.{a}'
return nvra
[docs]def componentize(builds):
if builds is None:
return None
if type(builds) is str:
_builds = [builds]
elif type(builds) is list:
_builds = builds
else:
raise TypeError(
'Builds is not str or list (' + str(type(builds)) + ')')
ret = []
for b in _builds:
(n, v, r, e, a) = splitFilename(b)
ret.append(n)
if type(builds) is str:
return ret[0]
return ret