Skip to content

Commit bbbedad

Browse files
committed
New Atom implementation
Based off of gentooPackage.py from =app-portage/tatt-0.5 package, see https://github.com/gentoo/tatt/blob/master/tatt/gentooPackage.py Add tests
1 parent 2f625a1 commit bbbedad

File tree

2 files changed

+120
-32
lines changed

2 files changed

+120
-32
lines changed

ebuildtester/atom.py

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,94 @@
1+
2+
import re
3+
4+
15
class AtomException(Exception):
26
pass
37

48

59
class Atom(object):
10+
"""A Gentoo Atom consists of the:
11+
category
12+
package (name)
13+
version
14+
of a Gentoo package"""
615

716
def __init__(self, atom):
8-
# We expect an atom of the form [=]CATEGORY/PACKAGE[-VERSION].
9-
self.category = None
10-
self.package = None
11-
self.version = None
12-
13-
# We don't store the optional '='.
14-
temp = atom.split("=")
15-
self.atom = temp[-1]
16-
17-
try:
18-
self.category, self.package = self.atom.split("/")
19-
except ValueError:
20-
raise AtomException(
21-
"ATOM has to be of the form [=]SECTION/PACKAGE[-VERSION]")
22-
23-
# Split off version.
24-
try:
25-
temp = self.package.index("-")
26-
if temp > -1:
27-
self.version = self.package[temp + 1:]
28-
self.package = self.package[:temp]
29-
except ValueError:
30-
pass
17+
"""We expect an atom of the form [=]CATEGORY/PACKAGE[-VERSION]."""
18+
self.category = ""
19+
self.package = ""
20+
self.version = ""
3121

32-
def __str__(self):
33-
if self.version is not None:
34-
prefix = "="
35-
suffix = "-" + self.version
22+
# strip off an optional leading =
23+
atom = str(atom)
24+
if atom[0] == "=":
25+
atom = atom[1:]
26+
27+
slashparts = atom.split("/")
28+
if len(slashparts) == 1:
29+
raise AtomException("Atoms must be of the form [=]CAT/PKG[-VER]!")
30+
else:
31+
self.category = slashparts[0]
32+
self._split_version(slashparts[1])
33+
34+
def _split_version(self, pkg):
35+
"""Splits the version from an atom with version"""
36+
minusparts = pkg.split("-")
37+
if len(minusparts) == 1:
38+
# no version given
39+
self.package = pkg
3640
else:
37-
prefix = ""
38-
suffix = ""
39-
return prefix + self.category + "/" + self.package + suffix
41+
# parse the name-version part
42+
while 1:
43+
try:
44+
p = minusparts.pop(0)
45+
except IndexError:
46+
break
47+
48+
# try a number after a '-'
49+
if re.match('[0-9]+', p):
50+
# version starts here
51+
self.version = "-".join([p] + minusparts)
52+
break
53+
else:
54+
# append back to name
55+
if self.package == "":
56+
self.package = p
57+
else:
58+
self.package = "-".join([self.package, p])
59+
60+
def atomName(self):
61+
"""Returns the package name without category"""
62+
return self.package
63+
64+
def atomCategory(self):
65+
"""Returns the package category without name"""
66+
return self.category
67+
68+
def atomVersion(self):
69+
"""Returns the package version"""
70+
return self.version
71+
72+
def atomCatName(self):
73+
"""Returns the package category and name without version"""
74+
return "/".join([self.category, self.package])
75+
76+
def atomString(self):
77+
"""Returns a portage compatible string representation"""
78+
if self.version == "":
79+
return self.atomCatName()
80+
81+
return ("=" + "/".join([self.category,
82+
"-".join([self.package,
83+
self.version])]))
84+
85+
def __str__(self):
86+
return self.atomString()
4087

4188
def __eq__(self, other):
42-
result = (self.atom == other.atom)
89+
result = (self.category == other.category
90+
and self.package == other.package
91+
and self.version == other.version)
4392
return result
4493

4594
def __repr__(self):

tests/test_atom.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import unittest
2-
from ebuildtester.atom import Atom, AtomException
2+
from ebuildtester.atom import Atom AtomException
33

44

55
class TestAtom(unittest.TestCase):
@@ -28,3 +28,42 @@ def test_str(self):
2828
atom_1 = Atom("=CATEGORY/PACKAGE-1.0.0-r1")
2929
atom_2 = Atom(str(atom_1))
3030
self.assertEqual(atom_1, atom_2)
31+
32+
def test_atomName(self):
33+
self.assertEqual(Atom("CATEGORY/PACKAGE").atomName(), "PACKAGE")
34+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0.0").atomName(), "PACKAGE")
35+
self.assertEqual(Atom("CATEGORY/PACKAGE-1.0.0").atomName(), "PACKAGE")
36+
self.assertEqual(Atom("=CATEGORY/PACKAGE-DEP-1.0b-r1").atomName(),
37+
"PACKAGE-DEP")
38+
39+
def test_atomCategory(self):
40+
self.assertEqual(Atom("CATEGORY/PACKAGE").atomCategory(), "CATEGORY")
41+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0.0").atomCategory(),
42+
"CATEGORY")
43+
44+
def test_atomVersion(self):
45+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1").atomVersion(), "1")
46+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0").atomVersion(), "1.0")
47+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0-r1").atomVersion(),
48+
"1.0-r1")
49+
self.assertEqual(Atom("=CATEGORY/PACKAGE-DEP-1.0b-r1").atomVersion(),
50+
"1.0b-r1")
51+
52+
def test_atomCatName(self):
53+
self.assertEqual(Atom("CATEGORY/PACKAGE").atomCatName(),
54+
"CATEGORY/PACKAGE")
55+
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0").atomCatName(),
56+
"CATEGORY/PACKAGE")
57+
58+
def test_atomString(self):
59+
atom1 = Atom("=CATEGORY/PACKAGE-1.0.0")
60+
atom2 = Atom(atom1.atomString())
61+
self.assertEqual(atom1, atom2)
62+
63+
def test_atom(self):
64+
atom1 = Atom("=CATEGORY/PACKAGE-DEP-1.0b-r1")
65+
self.assertEqual(atom1.atomCategory(), "CATEGORY")
66+
self.assertEqual(atom1.atomName(), "PACKAGE-DEP")
67+
self.assertEqual(atom1.atomCatName(), "CATEGORY/PACKAGE-DEP")
68+
self.assertEqual(atom1.atomVersion(), "1.0b-r1")
69+
self.assertEqual(atom1.atomString(), "=CATEGORY/PACKAGE-DEP-1.0b-r1")

0 commit comments

Comments
 (0)