From c2c060ba39bf0d5a4ff3058e941b28988bd59571 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 13 Jan 2008 11:05:32 +0000 Subject: [PATCH] Merged from trunk 9159:9179 | 9160 | Bug #162542 - When dropping privileges for | | zmedico | FEATURES=userpriv, automatically detect permission problems | | | with CCACHE_DIR and recursively adjust permissions only when | | | necessary. | | 9162 | Bug#204668 - Fix WORKDIR quoting in econf() when updating | | zmedico | config.guess and config.sub. | | 9163 | Bug #204425 - Remove --delete-after from the default | | zmedico | PORTAGE_RSYNC_OPTS. This allows the rsync program to choose | | | the preferred --delete algorithm, or the user can choose one | | | via PORTAGE_RSYNC_EXTRA_OPTS. | | 9164 | Make sure that portdb.findname() returns the correct ebuild. | | zmedico | | | 9165 | Fix the "Appending to PORTDIR_OVERLAY..." feature which was | | zmedico | broken by the previous commit. | | 9166 | Bug #203316 - Fix isvalidatom() to properly detect invalid | | zmedico | operators used together with slot atoms. Thanks to Arfrever | | | Frehtes Taifersar Arahesis for the | | | patch. | | 9167 | Bug #203887 - Implement RESTRICT=installsources for binaries | | zmedico | that are not compatible with debugedit. | | 9176 | Bug #162450 - Try to avoid having so many bugs marked | | zmedico | UPSTREAM by encouraging users to report 'poor programming | | | practices' QA issues upstream and show them the $HOMEPAGE | | | for convenience. | | 9177 | Add a DESCRIPTION.toolong warning for when the DESCRIPTION | | zmedico | line is over 80 characters long. Thanks to Betelgeuse for | | | the patch. | | 9178 | * Make pkgcmp() pass the ebuild revision directly into | | zmedico | vercmp() since there is code there to handle it already. | | | This eliminates some redundant revision comparison code. | | | Thanks to peper for the patch. * Add some vercmp() test | | | cases for comparison of ebuild revisions. | | 9179 | Add a new "ebuild.autotools" check for when ebuilds call | | zmedico | autotools directly instead of using autotools.eclass. Thanks | | | to Betelgeuse for the initial patch. | svn path=/main/branches/prefix/; revision=9202 --- bin/ebuild | 29 +++++++++++++---------- bin/ebuild.sh | 6 +++-- bin/misc-functions.sh | 7 ++++++ bin/prepstrip | 1 + bin/repoman | 13 ++++++++++ cnf/make.globals | 2 +- man/ebuild.5 | 4 ++++ pym/_emerge/__init__.py | 1 - pym/portage/__init__.py | 13 +++++++++- pym/portage/dep.py | 2 +- pym/portage/tests/versions/test_vercmp.py | 21 ++++++++++++---- pym/portage/versions.py | 8 +------ pym/repoman/checks.py | 22 +++++++++++++---- 13 files changed, 95 insertions(+), 34 deletions(-) diff --git a/bin/ebuild b/bin/ebuild index eb5976315..c3dcd8a32 100755 --- a/bin/ebuild +++ b/bin/ebuild @@ -60,8 +60,20 @@ if not os.path.isabs(ebuild): ebuild = portage.normalize_path(ebuild) # portdbapi uses the canonical path for the base of the portage tree, but # subdirectories of the base can be built from symlinks (like crossdev does). -ebuild_portdir = os.path.realpath(os.path.dirname(os.path.dirname(ebuild))) -ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-2:]) +ebuild_portdir = os.path.realpath( + os.path.dirname(os.path.dirname(os.path.dirname(ebuild)))) +ebuild = os.path.join(ebuild_portdir, *ebuild.split(os.path.sep)[-3:]) + +# Make sure that portdb.findname() returns the correct ebuild. +if ebuild_portdir not in portage.portdb.porttrees: + os.environ["PORTDIR_OVERLAY"] = \ + os.environ.get("PORTDIR_OVERLAY","") + " " + ebuild_portdir + print "Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir + portage.close_portdbapi_caches() + reload(portage) +del portage.portdb.porttrees[1:] +if ebuild_portdir != portage.portdb.porttree_root: + portage.portdb.porttrees.append(ebuild_portdir) if not os.path.exists(ebuild): print "'%s' does not exist." % ebuild @@ -90,17 +102,8 @@ else: portage_ebuild = portage.portdb.findname(cpv) if not portage_ebuild or portage_ebuild != ebuild: - overlay = "/".join(ebuild_split[:-2]) - os.environ["PORTDIR_OVERLAY"] = os.environ.get("PORTDIR_OVERLAY","") + " " + overlay - print "Appending %s to PORTDIR_OVERLAY..." % overlay - portage.close_portdbapi_caches() - reload(portage) - portage_ebuild = portage.portdb.findname(cpv) - - if not portage_ebuild or portage_ebuild != ebuild: - print "!!! %s does not seem to have a valid PORTDIR structure." % overlay - sys.exit(1) - + print "!!! %s does not seem to have a valid PORTDIR structure." % ebuild + sys.exit(1) if len(pargs) > 1 and "config" in pargs: print "config must be called on it's own, not combined with any other phase" diff --git a/bin/ebuild.sh b/bin/ebuild.sh index 6c748bded..d97745569 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -422,9 +422,11 @@ econf() { fi if [ -x "${ECONF_SOURCE}/configure" ]; then if [ -e "${EPREFIX}"/usr/share/gnuconfig/ ]; then - for x in $(find "${WORKDIR}" -type f '(' -name config.guess -o -name config.sub ')') ; do + find "${WORKDIR}" -type f '(' \ + -name config.guess -o -name config.sub ')' -print0 | \ + while read -d $'\0' x ; do vecho " * econf: updating ${x/${WORKDIR}\/} with ${EPREFIX}/usr/share/gnuconfig/${x##*/}" - cp -f "${EPREFIX}"/usr/share/gnuconfig/${x##*/} ${x} + cp -f "${EPREFIX}"/usr/share/gnuconfig/"${x##*/}" "${x}" done fi diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh index f1a52e71d..5e8ed6fc6 100644 --- a/bin/misc-functions.sh +++ b/bin/misc-functions.sh @@ -406,6 +406,13 @@ install_qa_check() { *) abort="yes";; esac fi + if [[ ${abort} == "yes" ]] || ; then + echo "Please do not file a Gentoo bug and instead" \ + "report the above QA issues directly to the upstream" \ + "developers of this software." | fmt -w 70 | \ + while read line ; do eqawarn "${line}" ; done + eqawarn "Homepage: ${HOMEPAGE}" + fi [[ ${abort} == "yes" ]] && hasq stricter ${FEATURES} && die "poor code kills airplanes" fi diff --git a/bin/prepstrip b/bin/prepstrip index 2ccf84c99..e89f67f26 100755 --- a/bin/prepstrip +++ b/bin/prepstrip @@ -32,6 +32,7 @@ fi save_elf_sources() { hasq installsources ${FEATURES} || return 0 + hasq installsources ${RESTRICT} && return 0 type -P debugedit >/dev/null || return 0 local x=$1 diff --git a/bin/repoman b/bin/repoman index a0a0322b4..22e1051fd 100755 --- a/bin/repoman +++ b/bin/repoman @@ -72,6 +72,8 @@ from portage.output import ConsoleStyleFile, StyleWriter initialize_logger() +# 14 is the length of DESCRIPTION="" +max_desc_len = 80 - 14 allowed_filename_chars="a-zA-Z0-9._-+:" allowed_filename_chars_set = {} map(allowed_filename_chars_set.setdefault, map(chr, range(ord('a'), ord('z')+1))) @@ -258,6 +260,7 @@ qahelp={ "KEYWORDS.stupid":"Ebuilds that use KEYWORDS=-* instead of package.mask", "LICENSE.missing":"Ebuilds that have a missing or empty LICENSE variable", "DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable", + "DESCRIPTION.toolong":"DESCRIPTION line is over 80 characters", "EAPI.unsupported":"Ebuilds that have an unsupported EAPI version (you must upgrade portage)", "SLOT.missing":"Ebuilds that have a missing or empty SLOT variable", "HOMEPAGE.missing":"Ebuilds that have a missing or empty HOMEPAGE variable", @@ -294,6 +297,7 @@ qahelp={ "ebuild.majorsyn":"This ebuild has a major syntax error that may cause the ebuild to fail partially or fully", "ebuild.minorsyn":"This ebuild has a minor syntax error that contravenes gentoo coding style", "ebuild.badheader":"This ebuild has a malformed header", + "ebuild.autotools":"Ebuild calls autotools directly instead of using autotools.eclass", "metadata.missing":"Missing metadata.xml files", "metadata.bad":"Bad metadata.xml files", "virtual.versioned":"PROVIDE contains virtuals with versions", @@ -311,6 +315,7 @@ qawarnings=[ "ebuild.notadded", "ebuild.nostable", "ebuild.allmasked", +"ebuild.autotools", "ebuild.nesteddie", "desktop.invalid", "digest.assumed", @@ -319,6 +324,7 @@ qawarnings=[ "DEPEND.badmasked","RDEPEND.badmasked","PDEPEND.badmasked", "DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev", "DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev", +"DESCRIPTION.toolong", "IUSE.invalid", "KEYWORDS.stupid", "KEYWORDS.missing", @@ -1350,6 +1356,13 @@ for x in scanlist: stats[myqakey]=stats[myqakey]+1 fails[myqakey].append(x+"/"+y+".ebuild") + # 14 is the length of DESCRIPTION="" + if len(myaux['DESCRIPTION']) > max_desc_len: + stats['DESCRIPTION.toolong'] += 1 + fails['DESCRIPTION.toolong'].append( + "%s: DESCRIPTION is %d characters (max %d)" % \ + (relative_path, len(myaux['DESCRIPTION']), max_desc_len)) + keywords = myaux["KEYWORDS"].split() stable_keywords = [] for keyword in keywords: diff --git a/cnf/make.globals b/cnf/make.globals index 8ea92f189..9d1179c8e 100644 --- a/cnf/make.globals +++ b/cnf/make.globals @@ -57,7 +57,7 @@ PORTAGE_RSYNC_RETRIES="3" # Number of seconds rsync will wait before timing out. #RSYNC_TIMEOUT="180" -PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --delete-after --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --filter=H_**/files/digest-*" +PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --filter=H_**/files/digest-*" # Minimal CONFIG_PROTECT CONFIG_PROTECT="/etc" diff --git a/man/ebuild.5 b/man/ebuild.5 index cbd9e9528..5623d9084 100644 --- a/man/ebuild.5 +++ b/man/ebuild.5 @@ -364,6 +364,10 @@ Distribution of binary packages is restricted. .I fetch like \fImirror\fR but the files will not be fetched via \fBSRC_URI\fR either. .TP +.I installsources +Disables installsources for specific packages. This is for packages with +binaries that are not compatible with debugedit. +.TP .I mirror files in \fBSRC_URI\fR will not be downloaded from the \fBGENTOO_MIRRORS\fR. .TP diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index e705bd3e0..61fcbb223 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -5385,7 +5385,6 @@ def action_sync(settings, trees, mtimedb, myopts, myaction): "--force", # Force deletion on non-empty dirs "--whole-file", # Don't do block transfers, only entire files "--delete", # Delete files that aren't in the master tree - "--delete-after", # Delete only after everything else is done "--stats", # Show final statistics about what was transfered "--timeout="+str(mytimeout), # IO timeout if not done in X seconds "--exclude=/distfiles", # Exclude distfiles from consideration diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index e22e8074c..f39f66605 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -4118,6 +4118,11 @@ def prepare_build_dirs(myroot, mysettings, cleanup): dirmode = 02070 filemode = 060 modemask = 02 + restrict = mysettings.get("PORTAGE_RESTRICT","").split() + from portage.data import secpass + droppriv = secpass >= 2 and \ + "userpriv" in mysettings.features and \ + "userpriv" not in restrict for myfeature, kwargs in features_dirs.iteritems(): if myfeature in mysettings.features: basedir = mysettings[kwargs["basedir_var"]] @@ -4134,7 +4139,13 @@ def prepare_build_dirs(myroot, mysettings, cleanup): # Generally, we only want to apply permissions for # initial creation. Otherwise, we don't know exactly what # permissions the user wants, so should leave them as-is. - if modified or kwargs["always_recurse"]: + droppriv_fix = False + if droppriv: + st = os.stat(mydir) + if st.st_gid != portage_gid or \ + not stat.S_IMODE(st.st_mode) & dirmode: + droppriv_fix = True + if modified or kwargs["always_recurse"] or droppriv_fix: if modified: writemsg("Adjusting permissions recursively: '%s'\n" % mydir, noiselevel=-1) diff --git a/pym/portage/dep.py b/pym/portage/dep.py index da0bb6427..bf42d2ba8 100644 --- a/pym/portage/dep.py +++ b/pym/portage/dep.py @@ -480,7 +480,7 @@ def isvalidatom(atom, allow_blockers=False): return 0 operator = get_operator(atom) if operator: - if operator[0] in "<>" and atom[-1] == "*": + if operator[0] in "<>" and remove_slot(atom).endswith("*"): return 0 if mycpv_cps and mycpv_cps[0] != "null": # >=cat/pkg-1.0 diff --git a/pym/portage/tests/versions/test_vercmp.py b/pym/portage/tests/versions/test_vercmp.py index c25ed954b..d8837b852 100644 --- a/pym/portage/tests/versions/test_vercmp.py +++ b/pym/portage/tests/versions/test_vercmp.py @@ -12,7 +12,9 @@ class VerCmpTestCase(TestCase): def testVerCmpGreater(self): - tests = [ ( "6.0", "5.0"), ("5.0","5")] + tests = [ ( "6.0", "5.0"), ("5.0","5"), + ("1.0-r1", "1.0-r0"), + ("1.0-r1", "1.0")] for test in tests: self.failIf( vercmp( test[0], test[1] ) <= 0, msg="%s < %s? Wrong!" % (test[0],test[1]) ) @@ -24,20 +26,31 @@ class VerCmpTestCase(TestCase): ("1.0_alpha2", "1.0_p2"),("1.0_alpha1", "1.0_beta1"),("1.0_beta3","1.0_rc3"), ("1.001000000000000000001", "1.001000000000000000002"), ("1.00100000000", "1.0010000000000000001"), - ("1.01", "1.1")] + ("1.01", "1.1"), + ("1.0-r0", "1.0-r1"), + ("1.0", "1.0-r1")] for test in tests: self.failIf( vercmp( test[0], test[1]) >= 0, msg="%s > %s? Wrong!" % (test[0],test[1])) def testVerCmpEqual(self): - tests = [ ("4.0", "4.0") ] + tests = [ ("4.0", "4.0"), + ("1.0", "1.0"), + ("1.0-r0", "1.0"), + ("1.0", "1.0-r0"), + ("1.0-r0", "1.0-r0"), + ("1.0-r1", "1.0-r1")] for test in tests: self.failIf( vercmp( test[0], test[1]) != 0, msg="%s != %s? Wrong!" % (test[0],test[1])) def testVerNotEqual(self): tests = [ ("1","2"),("1.0_alpha","1.0_pre"),("1.0_beta","1.0_alpha"), - ("0", "0.0")] + ("0", "0.0"), + ("1.0-r0", "1.0-r1"), + ("1.0-r1", "1.0-r0"), + ("1.0", "1.0-r1"), + ("1.0-r1", "1.0")] for test in tests: self.failIf( vercmp( test[0], test[1]) == 0, msg="%s == %s? Wrong!" % (test[0],test[1])) diff --git a/pym/portage/versions.py b/pym/portage/versions.py index 131aa628c..ba7ad24d3 100644 --- a/pym/portage/versions.py +++ b/pym/portage/versions.py @@ -210,17 +210,11 @@ def pkgcmp(pkg1, pkg2): """ if pkg1[0] != pkg2[0]: return None - mycmp=vercmp(pkg1[1],pkg2[1]) + mycmp = vercmp("-".join(pkg1[1:]), "-".join(pkg2[1:])) if mycmp>0: return 1 if mycmp<0: return -1 - r1=float(pkg1[2][1:]) - r2=float(pkg2[2][1:]) - if r1>r2: - return 1 - if r2>r1: - return -1 return 0 diff --git a/pym/repoman/checks.py b/pym/repoman/checks.py index 916003e7e..b4f1b016e 100644 --- a/pym/repoman/checks.py +++ b/pym/repoman/checks.py @@ -178,11 +178,25 @@ class EbuildUselessCdS(LineCheck): elif self.method_re.match(line): self.check_next_line = True +class Autotools(LineCheck): + """Check for direct calls to autotools""" + repoman_check_name = 'ebuild.autotools' + re = re.compile(r'^[^#]*([^e]|^)(autoconf|automake|aclocal|libtoolize)') + + def check(self, num, line): + """Run the check on line and return error if there is one""" + m = self.re.match(line) + if m is not None: + return ("Direct calls to '%s'" % m.group(2)) + \ + " instead of using autotools.eclass on line: %d" + +_constant_checks = tuple((c() for c in (Autotools, + EbuildWhitespace, EbuildQuote, + EbuildAssignment, EbuildUselessDodoc, + EbuildUselessCdS, EbuildNestedDie))) + def run_checks(contents, st_mtime): - checks = [] - for c in (EbuildWhitespace, EbuildQuote, EbuildAssignment, - EbuildUselessDodoc, EbuildUselessCdS, EbuildNestedDie): - checks.append(c()) + checks = list(_constant_checks) checks.append(EbuildHeader(st_mtime)) for num, line in enumerate(contents): for lc in checks: -- 2.26.2