|  | 
|  | 1 | + | 
|  | 2 | +import re | 
|  | 3 | + | 
|  | 4 | + | 
| 1 | 5 | class AtomException(Exception): | 
| 2 | 6 |     pass | 
| 3 | 7 | 
 | 
| 4 | 8 | 
 | 
| 5 | 9 | class Atom(object): | 
|  | 10 | +    """A Gentoo Atom consists of the: | 
|  | 11 | +    category | 
|  | 12 | +    package (name) | 
|  | 13 | +    version | 
|  | 14 | +    of a Gentoo package""" | 
| 6 | 15 | 
 | 
| 7 | 16 |     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 = "" | 
| 31 | 21 | 
 | 
| 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 | 
| 36 | 40 |         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() | 
| 40 | 87 | 
 | 
| 41 | 88 |     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) | 
| 43 | 92 |         return result | 
| 44 | 93 | 
 | 
| 45 | 94 |     def __repr__(self): | 
|  | 
0 commit comments