Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 75 additions & 4 deletions ebuildtester/atom.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,82 @@
"""An Atom."""

import re


class AtomException(Exception):
"""An exception in this class."""
pass


# from lib/portage/version.py
# PMS 3.1.3: A slot name may contain any of the characters [A-Za-z0-9+_.-].
# It must not begin with a hyphen or a dot.
_slot = r"([\w+][\w+.-]*)"

# 2.1.1 A category name may contain any of the characters [A-Za-z0-9+_.-].
# It must not begin with a hyphen or a dot.
_cat = r"[\w+][\w+.-]*"

# 2.1.2 A package name may contain any of the characters [A-Za-z0-9+_-].
# It must not begin with a hyphen,
# and must not end in a hyphen followed by one or more digits.
_pkg = r"[\w+][\w+-]*?"

_v = r"(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)"
_rev = r"\d+"
_vr = _v + "(-r(" + _rev + "))?"

_cp = "(" + _cat + "/" + _pkg + "(-" + _vr + ")?)"
_cpv = "(" + _cp + "-" + _vr + ")"
_pv = (
"(?P<pn>"
+ _pkg
+ "(?P<pn_inval>-"
+ _vr
+ ")?)"
+ "-(?P<ver>"
+ _v
+ ")(-r(?P<rev>"
+ _rev
+ "))?"
)

_pv_re = None


def _get_pv_re():
global _pv_re
if _pv_re is not None:
return _pv_re

_pv_re = re.compile(r"^" + _pv + r"$", re.VERBOSE | re.UNICODE)

return _pv_re


def _pkgsplit(mypkg: str):
"""
@param mypkg: pv
@return:
1. None if input is invalid.
2. (pn, ver, rev) if input is pv
"""
m = _get_pv_re().match(mypkg)
if m is None:
return None

if m.group("pn_inval") is not None:
# package name appears to have a version-like suffix
return None

rev = m.group("rev")
if rev is None:
rev = "0"
rev = "r" + rev

return (m.group("pn"), m.group("ver"), rev)


class Atom(object):

def __init__(self, atom):
Expand All @@ -26,10 +97,10 @@ def __init__(self, atom):

# Split off version.
try:
temp = self.package.index("-")
if temp > -1:
self.version = self.package[temp + 1:]
self.package = self.package[:temp]
# If atom don't start with "=" we assume there is no version
if '=' in atom:
self.package, self.version, rev = _pkgsplit(self.package)
self.version = f"{self.version}-{rev}"
except ValueError:
pass

Expand Down
19 changes: 14 additions & 5 deletions test/test_atom.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class TestAtom(unittest.TestCase):
def test_equals(self):
atom = Atom("=CATEGORY/PACKAGE-1.0.0")
self.assertEqual(atom.__str__()[0], "=")
self.assertEqual(atom.__str__(), "=CATEGORY/PACKAGE-1.0.0")
self.assertEqual(atom.__str__(), "=CATEGORY/PACKAGE-1.0.0-r0")

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

def test_version(self):
self.assertEqual(Atom("CATEGORY/PACKAGE-1").version, "1")
self.assertEqual(Atom("CATEGORY/PACKAGE-1.0").version, "1.0")
self.assertEqual(
Atom("CATEGORY/PACKAGE-1.0-r1").version, "1.0-r1")
self.assertEqual(Atom("CATEGORY/PACKAGE-1").version, None)
self.assertEqual(Atom("CATEGORY/PACKAGE-NAME-1").version, None)
self.assertEqual(Atom("CATEGORY/PACKAGE-1.0-r1").version, None)
self.assertEqual(Atom("CATEGORY/P-NAME-1.0-r1").version, None)

self.assertEqual(Atom("=CATEGORY/PACKAGE-1").version, "1-r0")
self.assertEqual(Atom("=CATEGORY/PACKAGE-NAME-1").version, "1-r0")
self.assertEqual(Atom("=CATEGORY/PACKAGE-NAME-1.0").version, "1.0-r0")
self.assertEqual(Atom("=CATEGORY/PACKAGE-1.0-r1").version, "1.0-r1")

def test_str(self):
atom_1 = Atom("=CATEGORY/PACKAGE-1.0.0-r1")
atom_2 = Atom(str(atom_1))
self.assertEqual(atom_1, atom_2)
atom_3 = Atom("=CATEGORY/PACKAGE-NAME-1.0.0-r1")
atom_4 = Atom(str(atom_3))
self.assertEqual(atom_3, atom_4)