Skip to content

Commit 297ea51

Browse files
committed
fix parsing of atoms
Previously atoms like category/a-long-name were parsed in such a way that "name" was taken as the version
1 parent 50d9382 commit 297ea51

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

ebuildtester/atom.py

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,82 @@
11
"""An Atom."""
22

3+
import re
4+
35

46
class AtomException(Exception):
57
"""An exception in this class."""
68
pass
79

810

11+
# from lib/portage/version.py
12+
# PMS 3.1.3: A slot name may contain any of the characters [A-Za-z0-9+_.-].
13+
# It must not begin with a hyphen or a dot.
14+
_slot = r"([\w+][\w+.-]*)"
15+
16+
# 2.1.1 A category name may contain any of the characters [A-Za-z0-9+_.-].
17+
# It must not begin with a hyphen or a dot.
18+
_cat = r"[\w+][\w+.-]*"
19+
20+
# 2.1.2 A package name may contain any of the characters [A-Za-z0-9+_-].
21+
# It must not begin with a hyphen,
22+
# and must not end in a hyphen followed by one or more digits.
23+
_pkg = r"[\w+][\w+-]*?"
24+
25+
_v = r"(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)"
26+
_rev = r"\d+"
27+
_vr = _v + "(-r(" + _rev + "))?"
28+
29+
_cp = "(" + _cat + "/" + _pkg + "(-" + _vr + ")?)"
30+
_cpv = "(" + _cp + "-" + _vr + ")"
31+
_pv = (
32+
"(?P<pn>"
33+
+ _pkg
34+
+ "(?P<pn_inval>-"
35+
+ _vr
36+
+ ")?)"
37+
+ "-(?P<ver>"
38+
+ _v
39+
+ ")(-r(?P<rev>"
40+
+ _rev
41+
+ "))?"
42+
)
43+
44+
_pv_re = None
45+
46+
47+
def _get_pv_re():
48+
global _pv_re
49+
if _pv_re is not None:
50+
return _pv_re
51+
52+
_pv_re = re.compile(r"^" + _pv + r"$", re.VERBOSE | re.UNICODE)
53+
54+
return _pv_re
55+
56+
57+
def _pkgsplit(mypkg: str):
58+
"""
59+
@param mypkg: pv
60+
@return:
61+
1. None if input is invalid.
62+
2. (pn, ver, rev) if input is pv
63+
"""
64+
m = _get_pv_re().match(mypkg)
65+
if m is None:
66+
return None
67+
68+
if m.group("pn_inval") is not None:
69+
# package name appears to have a version-like suffix
70+
return None
71+
72+
rev = m.group("rev")
73+
if rev is None:
74+
rev = "0"
75+
rev = "r" + rev
76+
77+
return (m.group("pn"), m.group("ver"), rev)
78+
79+
980
class Atom(object):
1081

1182
def __init__(self, atom):
@@ -26,10 +97,10 @@ def __init__(self, atom):
2697

2798
# Split off version.
2899
try:
29-
temp = self.package.index("-")
30-
if temp > -1:
31-
self.version = self.package[temp + 1:]
32-
self.package = self.package[:temp]
100+
# If atom don't start with "=" we assume there is no version
101+
if '=' in atom:
102+
self.package, self.version, rev = _pkgsplit(self.package)
103+
self.version = f"{self.version}-{rev}"
33104
except ValueError:
34105
pass
35106

test/test_atom.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class TestAtom(unittest.TestCase):
77
def test_equals(self):
88
atom = Atom("=CATEGORY/PACKAGE-1.0.0")
99
self.assertEqual(atom.__str__()[0], "=")
10-
self.assertEqual(atom.__str__(), "=CATEGORY/PACKAGE-1.0.0")
10+
self.assertEqual(atom.__str__(), "=CATEGORY/PACKAGE-1.0.0-r0")
1111

1212
def test_slash_1(self):
1313
with self.assertRaises(AtomException) as e:
@@ -19,12 +19,21 @@ def test_slash_2(self):
1919
self.assertEqual(atom.package, "PACKAGE")
2020

2121
def test_version(self):
22-
self.assertEqual(Atom("CATEGORY/PACKAGE-1").version, "1")
23-
self.assertEqual(Atom("CATEGORY/PACKAGE-1.0").version, "1.0")
24-
self.assertEqual(
25-
Atom("CATEGORY/PACKAGE-1.0-r1").version, "1.0-r1")
22+
self.assertEqual(Atom("CATEGORY/PACKAGE-1").version, None)
23+
self.assertEqual(Atom("CATEGORY/PACKAGE-NAME-1").version, None)
24+
self.assertEqual(Atom("CATEGORY/PACKAGE-1.0-r1").version, None)
25+
self.assertEqual(Atom("CATEGORY/P-NAME-1.0-r1").version, None)
26+
27+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1").version, "1-r0")
28+
self.assertEqual(Atom("=CATEGORY/PACKAGE-NAME-1").version, "1-r0")
29+
self.assertEqual(Atom("=CATEGORY/PACKAGE-NAME-1.0").version, "1.0-r0")
30+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0-r1").version, "1.0-r1")
2631

2732
def test_str(self):
2833
atom_1 = Atom("=CATEGORY/PACKAGE-1.0.0-r1")
2934
atom_2 = Atom(str(atom_1))
3035
self.assertEqual(atom_1, atom_2)
36+
atom_3 = Atom("=CATEGORY/PACKAGE-NAME-1.0.0-r1")
37+
atom_4 = Atom(str(atom_3))
38+
self.assertEqual(atom_3, atom_4)
39+

0 commit comments

Comments
 (0)