From 31c818a54eb8a0aca3a22db3e1f706c1fd54115b Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Fri, 2 Oct 2009 20:40:28 +0000 Subject: [PATCH] Merged from trunk -r14463:14472 | 14465 | Fix SyntaxError with Python 3 added in r14462. | | arfrever | | | 14466 | Take regular expressions from portage.dep and use them to | | zmedico | reimplement portage.versions.pkgsplit(). This simplifies | | | the code and helps guarantee consistency package | | | name/version validation. | | 14467 | Use a regular expression for SLOT validation inside | | zmedico | vardbapi.aux_get(). | | 14468 | Bug #286895 - Generate an eerror message when a directory | | zmedico | blocks merge of a regular file and the file is merged using | | | a 'config protect' filename even though the path may not be | | | among those covered by CONFIG_PROTECT. | | 14469 | Add --tolerant option (already in use on master rsync | | zmedico | mirror), requested by robbat2. | | 14470 | Remove libtool from RDEPEND.suspect list, since libltdl.so | | zmedico | is validly used by some packages at runtime. Thanks to | | | Samuli Suominen for reporting. | | 14471 | Bug #285191 - Remove the RDEPEND.implicit check because it | | zmedico | is invalid. | | 14472 | Bug #287333 - Fix the code from bug #252167 so it behaves | | zmedico | consistently regardless of the package (ebuild or binpkg) | | | being masked. | svn path=/main/branches/prefix/; revision=14473 --- bin/egencache | 5 ++++ bin/repoman | 1 - man/egencache.1 | 5 ++++ man/repoman.1 | 4 --- pym/_emerge/Package.py | 2 +- pym/_emerge/depgraph.py | 7 +++-- pym/portage/__init__.py | 2 +- pym/portage/dbapi/vartree.py | 32 +++++++++++++++------- pym/portage/dep.py | 18 +++---------- pym/portage/versions.py | 51 +++++++++++++++++++++++++----------- pym/repoman/checks.py | 33 +---------------------- 11 files changed, 78 insertions(+), 82 deletions(-) diff --git a/bin/egencache b/bin/egencache index 47f93c792..25a51d12c 100755 --- a/bin/egencache +++ b/bin/egencache @@ -67,6 +67,9 @@ def parse_args(args): action="store_true", help="enable rsync stat collision workaround " + \ "for bug 139134 (use with --update)") + parser.add_option("--tolerant", + action="store_true", + help="exit successfully if only minor errors occurred") parser.add_option("--ignore-default-opts", action="store_true", help="do not use the EGENCACHE_DEFAULT_OPTS environment variable") @@ -343,6 +346,8 @@ def egencache_main(args): max_load=options.load_average, rsync=options.rsync) gen_cache.run() + if options.tolerant: + return os.EX_OK return gen_cache.returncode if __name__ == "__main__": diff --git a/bin/repoman b/bin/repoman index 981998b05..db079f491 100755 --- a/bin/repoman +++ b/bin/repoman @@ -426,7 +426,6 @@ suspect_rdepend = frozenset([ "sys-devel/bison", "sys-devel/dev86", "sys-devel/flex", - "sys-devel/libtool", "sys-devel/m4", "sys-devel/pmake", "x11-misc/bdftopcf", diff --git a/man/egencache.1 b/man/egencache.1 index dbcc44e4b..d0bd1014a 100644 --- a/man/egencache.1 +++ b/man/egencache.1 @@ -54,6 +54,11 @@ This option should only be needed for distribution via something like (see \fBbug 139134\fR). It's not needed with \fBgit\fR(1) since that uses a more thorough mechanism which allows it to detect changed inode numbers (described in \fIracy-git.txt\fR in the git technical docs). +.TP +.BR "\-\-tolerant" +Exit successfully if only minor errors occurred, such as skipped cache +updates due to ebuilds that either fail to source or are not sourced +due to invalid Manifest entries. .SH "ENVIRONMENT OPTIONS" .TP \fBEGENCACHE_DEFAULT_OPTS\fR diff --git a/man/repoman.1 b/man/repoman.1 index 52ef02a1e..b07427749 100644 --- a/man/repoman.1 +++ b/man/repoman.1 @@ -186,10 +186,6 @@ Masked ebuilds with RDEPEND settings (matched against *all* ebuilds) .B RDEPEND.badmaskedindev Masked ebuilds with RDEPEND settings (matched against *all* ebuilds) in developing arch .TP -.B RDEPEND.implicit -RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND -assignment -.TP .B RDEPEND.suspect RDEPEND contains a package that usually only belongs in DEPEND .TP diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py index 472b1d375..e07c8fc4b 100644 --- a/pym/_emerge/Package.py +++ b/pym/_emerge/Package.py @@ -212,7 +212,7 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase): elif k in self._use_conditional_keys: try: use_reduce(paren_reduce(v), matchall=1) - except portage.exception.InvalidDependString, e: + except portage.exception.InvalidDependString as e: self._pkg._invalid_metadata(k + ".syntax", "%s: %s" % (k, e)) def _set_inherited(self, k, v): diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index 551022b56..b6d01f9a3 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -2304,8 +2304,7 @@ class depgraph(object): reinstall_for_flags = None if not pkg.installed or \ - (pkg.built and matched_packages and \ - not (avoid_update and pkg.installed)): + (matched_packages and not avoid_update): # Only enforce visibility on installed packages # if there is at least one other visible package # available. By filtering installed masked packages @@ -2323,8 +2322,8 @@ class depgraph(object): # with visible KEYWORDS when the installed # version is masked by KEYWORDS, but never # reinstall the same exact version only due - # to a KEYWORDS mask. - if built and matched_packages: + # to a KEYWORDS mask. See bug #252167. + if matched_packages: different_version = None for avail_pkg in matched_packages: diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index f57c1c85e..2f9fb26df 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -8183,7 +8183,7 @@ def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1): return None return deplist -_cpv_key_re = re.compile('^' + dep._cpv + '$', re.VERBOSE) +_cpv_key_re = re.compile('^' + versions._cpv + '$', re.VERBOSE) def cpv_getkey(mycpv): """Calls pkgsplit on a cpv and returns only the cp.""" m = _cpv_key_re.match(mycpv) diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 38e10c15f..1df5580c0 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -13,7 +13,7 @@ import portage portage.proxy.lazyimport.lazyimport(globals(), 'portage.checksum:_perform_md5_merge@perform_md5', 'portage.dep:dep_getkey,isjustname,match_from_list,' + \ - 'use_reduce,paren_reduce', + 'use_reduce,paren_reduce,_slot_re', 'portage.elog:elog_process', 'portage.elog.filtering:filter_mergephases,filter_unmergephases', 'portage.locks:lockdir,unlockdir', @@ -1967,10 +1967,12 @@ class vardbapi(dbapi): cache_data[aux_key] = mydata[aux_key] self._aux_cache["packages"][mycpv] = (mydir_mtime, cache_data) self._aux_cache["modified"].add(mycpv) - if not mydata['SLOT']: - # Empty slot triggers InvalidAtom exceptions when generating slot - # atoms for packages, so translate it to '0' here. + + if _slot_re.match(mydata['SLOT']) is None: + # Empty or invalid slot triggers InvalidAtom exceptions when + # generating slot atoms for packages, so translate it to '0' here. mydata['SLOT'] = _unicode_decode('0') + return [mydata[x] for x in wants] def _aux_get(self, mycpv, wants, st=None): @@ -4890,12 +4892,20 @@ class dblink(object): protected = self.isprotected(mydest) if mydmode != None: # destination file exists - cfgprot = 0 + if stat.S_ISDIR(mydmode): # install of destination is blocked by an existing directory with the same name - cfgprot = 1 - showMessage("!!! %s\n" % mydest, - level=logging.ERROR, noiselevel=-1) + newdest = new_protect_filename(mydest, newmd5=mymd5) + msg = [] + msg.append("") + msg.append("Installation of a regular file is blocked by a directory:") + msg.append(" '%s'" % mydest) + msg.append("This file will be merged with a different name:") + msg.append(" '%s'" % newdest) + msg.append("") + self._eerror("preinst", msg) + mydest = newdest + elif stat.S_ISREG(mydmode) or (stat.S_ISLNK(mydmode) and os.path.exists(mydest) and stat.S_ISREG(os.stat(mydest)[stat.ST_MODE])): # install of destination is blocked by an existing regular file, # or by a symlink to an existing regular file; @@ -4903,6 +4913,7 @@ class dblink(object): # we only need to tweak mydest if cfg file management is in play. if protected: # we have a protection path; enable config file management. + cfgprot = 0 destmd5 = perform_md5(mydest, calc_prelink=1) if mymd5 == destmd5: #file already in place; simply update mtimes of destination @@ -4927,8 +4938,9 @@ class dblink(object): """A previously remembered update has been accepted, so it is removed from confmem.""" del cfgfiledict[myrealdest] - if cfgprot: - mydest = new_protect_filename(mydest, newmd5=mymd5) + + if cfgprot: + mydest = new_protect_filename(mydest, newmd5=mymd5) # whether config protection or not, we merge the new file the # same way. Unless moveme=0 (blocking directory) diff --git a/pym/portage/dep.py b/pym/portage/dep.py index 1fe4bc905..70d95e484 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -24,7 +24,7 @@ import portage.exception from portage.exception import InvalidData, InvalidAtom from portage.localization import _ from portage.versions import catpkgsplit, catsplit, \ - pkgcmp, pkgsplit, ververify, _version + pkgcmp, pkgsplit, ververify, _cp, _cpv import portage.cache.mappings if sys.hexversion >= 0x3000000: @@ -806,28 +806,18 @@ def dep_getusedeps( depend ): # \w is [a-zA-Z0-9_] -# 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+-]*?' - # 2.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+.-]*)' +_slot = r'([\w+][\w+.-]*)' +_slot_re = re.compile('^' + _slot + '$', re.VERBOSE) _use = r'\[.*\]' _op = r'([=~]|[><]=?)' -_cp = '(' + _cat + '/' + _pkg + '(-' + _version + ')?)' -_cpv = '(' + _cp + '-' + _version + ')' _atom_re = re.compile('^(?P(?:' + '(?P' + _op + _cpv + ')|' + '(?P=' + _cpv + r'\*)|' + - '(?P' + _cp + '))(?:' + _slot + ')?)(' + _use + ')?$', re.VERBOSE) + '(?P' + _cp + '))(:' + _slot + ')?)(' + _use + ')?$', re.VERBOSE) def isvalidatom(atom, allow_blockers=False): """ diff --git a/pym/portage/versions.py b/pym/portage/versions.py index 06ca9fd8c..8b5ad3422 100644 --- a/pym/portage/versions.py +++ b/pym/portage/versions.py @@ -5,10 +5,28 @@ import re + +# \w is [a-zA-Z0-9_] + +# 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'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)' # PREFIX hack: -r(\d+) -> -r(\d+|0\d+\.\d+) (see below) -_version = r'(cvs\.)?(\d+)((\.\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\d*)*)(-r(\d+|0\d+\.\d+))?' +_rev = r'(\d+|0\d+\.\d+)' +_vr = _v + '(-r(' + _rev + '))?' -ver_regexp = re.compile("^" + _version + "$") +_cp = '(' + _cat + '/' + _pkg + '(-' + _vr + ')?)' +_cpv = '(' + _cp + '-' + _vr + ')' +_pv = '(?P' + _pkg + '(?P-' + _vr + ')?)' + '-(?P' + _v + ')(-r(?P' + _rev + '))?' + +ver_regexp = re.compile("^" + _vr + "$") suffix_regexp = re.compile("^(alpha|beta|rc|pre|p)(\\d*)$") suffix_value = {"pre": -2, "p": 0, "alpha": -4, "beta": -3, "rc": -1} endversion_keys = ["pre", "p", "alpha", "beta", "rc"] @@ -231,23 +249,15 @@ def pkgcmp(pkg1, pkg2): return None return vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:])) -pkgcache={} +_pv_re = re.compile('^' + _pv + '$', re.VERBOSE) def pkgsplit(mypkg,silent=1): - try: - if not pkgcache[mypkg]: - return None - return pkgcache[mypkg] - except KeyError: - pass - myparts=mypkg.split("-") - - if len(myparts)<2: - if not silent: - print(_("!!! Name error in %s: missing a version or name part.") % mypkg) - pkgcache[mypkg]=None + + m = _pv_re.match(mypkg) + if m is None: return None +<<<<<<< .working #verify rev revok=0 myrev=myparts[-1] @@ -275,8 +285,19 @@ def pkgsplit(mypkg,silent=1): return myval else: pkgcache[mypkg]=None +======= + if m.group('pn_inval') is not None: + # package name appears to have a version-like suffix +>>>>>>> .merge-right.r14472 return None + rev = m.group('rev') + if rev is None: + rev = '0' + rev = 'r' + rev + + return (m.group('pn'), m.group('ver'), rev) + catcache={} def catpkgsplit(mydata,silent=1): """ diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py index bfb262545..5058ec77e 100644 --- a/pym/repoman/checks.py +++ b/pym/repoman/checks.py @@ -268,37 +268,6 @@ class EbuildQuotedA(LineCheck): if match: return "Quoted \"${A}\" on line: %d" -class ImplicitRuntimeDeps(LineCheck): - """ - Detect the case where DEPEND is set and RDEPEND is unset in the ebuild, - since this triggers implicit RDEPEND=$DEPEND assignment. - """ - - _assignment_re = re.compile(r'^\s*(R?DEPEND)=') - - def new(self, pkg): - # RDEPEND=DEPEND is no longer available in EAPI=3 - if pkg.metadata['EAPI'] in ('0', '1', '2'): - self.repoman_check_name = 'RDEPEND.implicit' - else: - self.repoman_check_name = 'EAPI.incompatible' - self._rdepend = False - self._depend = False - - def check(self, num, line): - if not self._rdepend: - m = self._assignment_re.match(line) - if m is None: - pass - elif m.group(1) == "RDEPEND": - self._rdepend = True - elif m.group(1) == "DEPEND": - self._depend = True - - def end(self): - if self._depend and not self._rdepend: - yield 'RDEPEND is not explicitly assigned' - class InheritAutotools(LineCheck): """ Make sure appropriate functions are called in @@ -493,7 +462,7 @@ _constant_checks = tuple((c() for c in ( EbuildAssignment, EbuildUselessDodoc, EbuildUselessCdS, EbuildNestedDie, EbuildPatches, EbuildQuotedA, EapiDefinition, - IUseUndefined, ImplicitRuntimeDeps, InheritAutotools, + IUseUndefined, InheritAutotools, EMakeParallelDisabled, EMakeParallelDisabledViaMAKEOPTS, DeprecatedBindnowFlags, SrcUnpackPatches, WantAutoDefaultValue, SrcCompileEconf, Eapi3IncompatibleFuncs, Eapi3GoneVars))) -- 2.26.2