def __init__(self, query, is_regex=False): """Create query object. @type is_regex: bool @param is_regex: query is a regular expression """ # We need at least one of these chars for a valid query needed_chars = ascii_letters + '*' if not set(query).intersection(needed_chars): raise errors.GentoolkitInvalidPackage(query) # Separate repository repository = None if query.count(':') == 2: query, repository = query.rsplit(':', 1) self.query = query.rstrip(':') # Don't leave dangling colon self.repo_filter = repository self.is_regex = is_regex self.query_type = self._get_query_type() # Name the rest of the chunks, if possible if self.query_type != "set": try: atom = Atom(self.query) self.__dict__.update(atom.__dict__) except errors.GentoolkitInvalidAtom: CPV.__init__(self, self.query) self.operator = '' self.atom = self.cpv
def entries_matching_range(self, from_ver=None, to_ver=None): """Return entries whose header versions are within a range of versions. @type from_ver: str @param from_ver: valid Gentoo version @type to_ver: str @param to_ver: valid Gentoo version @rtype: list @return: entries between from_ver and to_ver @raise errors.GentoolkitFatalError: if neither vers are set @raise errors.GentoolkitInvalidVersion: if either ver is invalid """ result = [] # Make sure we have at least one version set if not (from_ver or to_ver): raise errors.GentoolkitFatalError( "Need to specifiy 'from_ver' or 'to_ver'" ) # Create a VersionMatch instance out of from_ver from_restriction = None if from_ver: try: from_ver_rev = CPV("null-%s" % from_ver) except errors.GentoolkitInvalidCPV: raise errors.GentoolkitInvalidVersion(from_ver) from_restriction = VersionMatch(from_ver_rev, op='>=') # Create a VersionMatch instance out of to_ver to_restriction = None if to_ver: try: to_ver_rev = CPV("null-%s" % to_ver) except errors.GentoolkitInvalidCPV: raise errors.GentoolkitInvalidVersion(to_ver) to_restriction = VersionMatch(to_ver_rev, op='<=') # Add entry to result if version ranges intersect it for entry_set in self.indexed_entries: i, entry = entry_set if from_restriction and not from_restriction.match(i): continue if to_restriction and not to_restriction.match(i): # TODO: is it safe to break here? continue result.append(entry) return result
def _index_changelog(self): """Use the output of L{self._split_changelog} to create an index list of L{gentoolkit.versionmatch.VersionMatch} objects. @rtype: list @return: tuples containing a VersionMatch instance for the release version of each entry header as the first item and the entire entry as the second item @raise ValueError: if self.invalid_entry_is_fatal is True and we hit an invalid entry """ result = [] for entry in self.entries: # Extract the package name from the entry header, ex: # *xterm-242 (07 Mar 2009) => xterm-242 pkg_name = entry.split(' ', 1)[0].lstrip('*') if not pkg_name.strip(): continue try: entry_ver = CPV(pkg_name, validate=True) except errors.GentoolkitInvalidCPV: if self.invalid_entry_is_fatal: raise ValueError(entry_ver) continue result.append((VersionMatch(entry_ver, op='='), entry)) return result
def __lt__(self, other): if not isinstance(other, self.__class__): err = "other isn't of %s type, is %s" raise TypeError(err % (self.__class__, other.__class__)) if self.operator != other.operator: return self.operator < other.operator if not CPV.__eq__(self, other): return CPV.__lt__(self, other) if bool(self.blocker) != bool(other.blocker): # We want non blockers, then blockers, so only return True # if self.blocker is True and other.blocker is False. return bool(self.blocker) > bool(other.blocker) if self.blocker and other.blocker: if self.blocker.overlap.forbid != other.blocker.overlap.forbid: # we want !! prior to ! return (self.blocker.overlap.forbid < other.blocker.overlap.forbid) # Don't believe Portage has something like this #c = cmp(self.negate_vers, other.negate_vers) #if c: # return c if self.slot != other.slot: if self.slot is None: return False elif other.slot is None: return True return self.slot < other.slot this_use = [] if self.use is not None: this_use = sorted(self.use.tokens) that_use = [] if other.use is not None: that_use = sorted(other.use.tokens) if this_use != that_use: return this_use < that_use # Not supported by Portage Atom yet #return cmp(self.repo_name, other.repo_name) return False
def __init__(self, atom): self.atom = atom self.operator = self.blocker = self.use = self.slot = None try: portage.dep.Atom.__init__(self, atom) except portage.exception.InvalidAtom: raise errors.GentoolkitInvalidAtom(atom) # Make operator compatible with intersects if self.operator is None: self.operator = '' CPV.__init__(self, self.cpv) # use_conditional is USE flag condition for this Atom to be required: # For: !build? ( >=sys-apps/sed-4.0.5 ), use_conditional = '!build' self.use_conditional = None
def test_chunk_splitting(self): all_tests = [ # simple ('sys-apps/portage-2.2', { 'category': 'sys-apps', 'name': 'portage', 'cp': 'sys-apps/portage', 'version': '2.2', 'revision': '', 'fullversion': '2.2' }), # with rc ('sys-apps/portage-2.2_rc10', { 'category': 'sys-apps', 'name': 'portage', 'cp': 'sys-apps/portage', 'version': '2.2_rc10', 'revision': '', 'fullversion': '2.2_rc10' }), # with revision ('sys-apps/portage-2.2_rc10-r1', { 'category': 'sys-apps', 'name': 'portage', 'cp': 'sys-apps/portage', 'version': '2.2_rc10', 'revision': 'r1', 'fullversion': '2.2_rc10-r1' }), # with dash (-) in name (Bug #316961) ('c-portage', { 'category': '', 'name': 'c-portage', 'cp': 'c-portage', 'version': '', 'revision': '', 'fullversion': '' }), # with dash (-) in name (Bug #316961) ('sys-apps/c-portage-2.2_rc10-r1', { 'category': 'sys-apps', 'name': 'c-portage', 'cp': 'sys-apps/c-portage', 'version': '2.2_rc10', 'revision': 'r1', 'fullversion': '2.2_rc10-r1' }), ] for test in all_tests: cpv = CPV(test[0]) keys = ('category', 'name', 'cp', 'version', 'revision', 'fullversion') for k in keys: self.assertEqual(getattr(cpv, k), test[1][k])
def __init__(self, cpv, validate=False, local_config=True): if isinstance(cpv, CPV): self.__dict__.update(cpv.__dict__) else: CPV.__init__(self, cpv, validate=validate) if validate and not all( hasattr(self, x) for x in ('category', 'version')): # CPV allows some things that Package must not raise errors.GentoolkitInvalidPackage(self.cpv) if local_config: self._settings = default_settings else: self._settings = nolocal_settings # Set dynamically self._package_path = None self._dblink = None self._metadata = None self._deps = None self._portdir_path = None
def __init__(self, cpv, validate=False, local_config=True): if isinstance(cpv, CPV): self.__dict__.update(cpv.__dict__) else: CPV.__init__(self, cpv, validate=validate) if validate and not all( hasattr(self, x) for x in ('category', 'version') ): # CPV allows some things that Package must not raise errors.GentoolkitInvalidPackage(self.cpv) if local_config: self._settings = default_settings else: self._settings = nolocal_settings # Set dynamically self._package_path = None self._dblink = None self._metadata = None self._deps = None self._portdir_path = None
def _do_complex_lookup(self, show_progress=True): """Find matches for a query which is a regex or includes globbing.""" result = [] if show_progress and not CONFIG["piping"]: self.print_summary() try: cat = CPV(self.query).category except errors.GentoolkitInvalidCPV: cat = '' pre_filter = [] # The "get_" functions can pre-filter against the whole package key, # but since we allow globbing now, we run into issues like: # >>> portage.dep.dep_getkey("sys-apps/portage-*") # 'sys-apps/portage-' # So the only way to guarantee we don't overrun the key is to # prefilter by cat only. if cat: if self.is_regex: cat_re = cat else: cat_re = fnmatch.translate(cat) predicate = lambda x: re.match(cat_re, x.split("/", 1)[0]) pre_filter = self.package_finder(predicate=predicate) # Post-filter if self.is_regex: try: re.compile(self.query) except re.error: raise errors.GentoolkitInvalidRegex(self.query) predicate = lambda x: re.search(self.query, x) else: if cat: query_re = fnmatch.translate(self.query) else: query_re = fnmatch.translate("*/%s" % self.query) predicate = lambda x: re.search(query_re, x) if pre_filter: result = [x for x in pre_filter if predicate(x)] else: result = self.package_finder(predicate=predicate) return [Package(x) for x in result]
def __eq__(self, other): if not isinstance(other, self.__class__): err = "other isn't of %s type, is %s" raise TypeError(err % (self.__class__, other.__class__)) if self.operator != other.operator: return False if not CPV.__eq__(self, other): return False if bool(self.blocker) != bool(other.blocker): return False if self.blocker and other.blocker: if self.blocker.overlap.forbid != other.blocker.overlap.forbid: return False if self.use_conditional != other.use_conditional: return False # Don't believe Portage has something like this #c = cmp(self.negate_vers, other.negate_vers) #if c: # return c if self.slot != other.slot: return False this_use = None if self.use is not None: this_use = sorted(self.use.tokens) that_use = None if other.use is not None: that_use = sorted(other.use.tokens) if this_use != that_use: return False # Not supported by Portage Atom yet #return cmp(self.repo_name, other.repo_name) return True
def test_chunk_splitting(self): all_tests = [ # simple ( "sys-apps/portage-2.2", { "category": "sys-apps", "name": "portage", "cp": "sys-apps/portage", "version": "2.2", "revision": "", "fullversion": "2.2", }, ), # with rc ( "sys-apps/portage-2.2_rc10", { "category": "sys-apps", "name": "portage", "cp": "sys-apps/portage", "version": "2.2_rc10", "revision": "", "fullversion": "2.2_rc10", }, ), # with revision ( "sys-apps/portage-2.2_rc10-r1", { "category": "sys-apps", "name": "portage", "cp": "sys-apps/portage", "version": "2.2_rc10", "revision": "r1", "fullversion": "2.2_rc10-r1", }, ), # with dash (-) in name (Bug #316961) ( "c-portage", { "category": "", "name": "c-portage", "cp": "c-portage", "version": "", "revision": "", "fullversion": "", }, ), # with dash (-) in name (Bug #316961) ( "sys-apps/c-portage-2.2_rc10-r1", { "category": "sys-apps", "name": "c-portage", "cp": "sys-apps/c-portage", "version": "2.2_rc10", "revision": "r1", "fullversion": "2.2_rc10-r1", }, ), ] for test in all_tests: cpv = CPV(test[0]) keys = ("category", "name", "cp", "version", "revision", "fullversion") for k in keys: self.assertEqual(getattr(cpv, k), test[1][k])
def test_intersects_nameonly(self): atom = Atom('cat/pkg') self.assertTrue(atom.intersects(CPV('pkg'))) self.assertFalse(atom.intersects(CPV('other'))) self.assertFalse(atom.intersects(CPV('dkg')))
def test_comparison(self): self.assertEqual2(CPV("pkg"), CPV("pkg")) self.assertNotEqual2(CPV("pkg"), CPV("pkg1")) self.assertEqual2(CPV("cat/pkg"), CPV("cat/pkg")) self.assertNotEqual2(CPV("cat/pkg"), CPV("cat/pkgb")) self.assertNotEqual2(CPV("cata/pkg"), CPV("cat/pkg")) self.assertEqual2(CPV("cat/pkg-0.1"), CPV("cat/pkg-0.1")) self.assertNotEqual2(CPV("cat/pkg-1.0"), CPV("cat/pkg-1")) self.assertEqual2(CPV("cat/pkg-0"), CPV("cat/pkg-0")) self.assertEqual2(CPV("cat/pkg-1-r1"), CPV("cat/pkg-1-r1")) self.assertNotEqual2(CPV("cat/pkg-2-r1"), CPV("cat/pkg-2-r10")) self.assertEqual2(CPV("cat/pkg-1_rc2"), CPV("cat/pkg-1_rc2")) self.assertNotEqual2(CPV("cat/pkg-2_rc2-r1"), CPV("cat/pkg-2_rc1-r1"))
def test_intersects_nameonly(self): atom = Atom("cat/pkg") self.assertTrue(atom.intersects(CPV("pkg"))) self.assertFalse(atom.intersects(CPV("other"))) self.assertFalse(atom.intersects(CPV("dkg")))
def test_comparison(self): self.assertEqual2(CPV('pkg'), CPV('pkg')) self.assertNotEqual2(CPV('pkg'), CPV('pkg1')) self.assertEqual2(CPV('cat/pkg'), CPV('cat/pkg')) self.assertNotEqual2(CPV('cat/pkg'), CPV('cat/pkgb')) self.assertNotEqual2(CPV('cata/pkg'), CPV('cat/pkg')) self.assertEqual2(CPV('cat/pkg-0.1'), CPV('cat/pkg-0.1')) self.assertNotEqual2(CPV('cat/pkg-1.0'), CPV('cat/pkg-1')) self.assertEqual2(CPV('cat/pkg-0'), CPV('cat/pkg-0')) self.assertEqual2(CPV('cat/pkg-1-r1'), CPV('cat/pkg-1-r1')) self.assertNotEqual2(CPV('cat/pkg-2-r1'), CPV('cat/pkg-2-r10')) self.assertEqual2(CPV('cat/pkg-1_rc2'), CPV('cat/pkg-1_rc2')) self.assertNotEqual2(CPV('cat/pkg-2_rc2-r1'), CPV('cat/pkg-2_rc1-r1'))