Skip to content

Commit 3d6fcc0

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 3d6fcc0

File tree

2 files changed

+87
-9
lines changed

2 files changed

+87
-9
lines changed

ebuildtester/atom.py

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

3+
import re
4+
35

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

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

978
class Atom(object):
1079

@@ -26,10 +95,10 @@ def __init__(self, atom):
2695

2796
# Split off version.
2897
try:
29-
temp = self.package.index("-")
30-
if temp > -1:
31-
self.version = self.package[temp + 1:]
32-
self.package = self.package[:temp]
98+
# If atom don't start with "=" we assume there is no version
99+
if '=' in atom:
100+
self.package, self.version, rev = _pkgsplit(self.package)
101+
self.version = f"{self.version}-{rev}"
33102
except ValueError:
34103
pass
35104

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)