[arch-projects] [namcap][PATCH] Add setuptools rule
This rule detects python imports from pkg_resources from python*-setupsools in /usr/bin/*. Missing dependency on corresponding setuptools package will render the executables unusable. Signed-off-by: Felix Yan <felixonmars@gmail.com> --- Namcap/rules/__init__.py | 1 + Namcap/rules/setuptools.py | 73 +++++++++++++++++++++++++++++++++ Namcap/tests/package/test_setuptools.py | 71 ++++++++++++++++++++++++++++++++ namcap-tags | 2 + 4 files changed, 147 insertions(+) create mode 100644 Namcap/rules/setuptools.py create mode 100644 Namcap/tests/package/test_setuptools.py diff --git a/Namcap/rules/__init__.py b/Namcap/rules/__init__.py index f7780d2..d42a241 100644 --- a/Namcap/rules/__init__.py +++ b/Namcap/rules/__init__.py @@ -44,6 +44,7 @@ from . import ( permissions, rpath, scrollkeeper, + setuptools, shebangdepends, sodepends, symlink diff --git a/Namcap/rules/setuptools.py b/Namcap/rules/setuptools.py new file mode 100644 index 0000000..1b1a3b4 --- /dev/null +++ b/Namcap/rules/setuptools.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# namcap rules - setuptools +# Copyright (C) 2014 Felix Yan <felixonmars@gmail.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +from Namcap.ruleclass import * +import Namcap.depends + +def check_setuptools(pyfile): + "returns python prefix if need setuptools, else False" + try: + shebang = pyfile.readline().decode("utf8") + except UnicodeDecodeError: + # Not a text file + return False + + if "python" in shebang: + try: + rest_of_file = "\n" + pyfile.read().decode("utf8") + except UnicodeDecodeError: + return False + + # Simple test + if "\nfrom pkg_resources import" in rest_of_file or "\nimport pkg_resources" in rest_of_file: + return "python2" if "python2" in shebang else "python" + + return False + +class package(TarballRule): + name = "setuptools" + description = "Checks that Python executables under /usr/bin that uses pkg_resources have setuptools as a dependency" + def analyze(self, pkginfo, tar): + executables = [ f for f in tar + if f.name.startswith("usr/bin") and f.isfile() ] + if len(executables) == 0: + return + + # If there are executables, check for pkg_resources reference + + need_setuptools = [] + for executable in executables: + pyfile = tar.extractfile(executable) + + if pyfile is None: + continue + + python_prefix = check_setuptools(pyfile) + if python_prefix: + need_setuptools.append(executable.name) + + if len(need_setuptools): + potential_depends = (python_prefix + "-setuptools", python_prefix + "-distribute") + if not any(dependency in pkginfo.get("depends") or dependency in Namcap.depends.getcovered(pkginfo.get("depends")) for dependency in potential_depends): + self.infos.append(("setuptools-needed-dep %s in %s", (python_prefix + "-setuptools", need_setuptools))) + reasons = pkginfo.detected_deps.setdefault(python_prefix + "-setuptools", []) + reasons.append( ('setuptools-needed %s', str(need_setuptools)) ) + +# vim: set ts=4 sw=4 noet: diff --git a/Namcap/tests/package/test_setuptools.py b/Namcap/tests/package/test_setuptools.py new file mode 100644 index 0000000..1593604 --- /dev/null +++ b/Namcap/tests/package/test_setuptools.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# namcap tests - setuptools +# Copyright (C) 2014 Felix Yan <felixonmars@gmail.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA +# + +import os + +from Namcap.tests.makepkg import MakepkgTest +import Namcap.rules.setuptools + +class SetuptoolsProgramsTest(MakepkgTest): + pkgbuild = """ +pkgname=__namcap_test_setuptools +pkgver=1.0 +pkgrel=1 +pkgdesc="A Good Python2 package" +arch=('any') +url="http://www.example.com/" +license=('GPL') +depends=('python2') +options=(!purge !zipman) +source=() +build() { + true +} +package() { + mkdir -p "${pkgdir}/usr/bin" + tee "${pkgdir}/usr/bin/foobar" << EOF +#!/usr/bin/python2 +from pkg_resources import load_entry_point +EOF +} +""" + + def test_setuptools_files(self): + pkgfile = "__namcap_test_setuptools-1.0-1-any.pkg.tar" + with open(os.path.join(self.tmpdir, "PKGBUILD"), "w") as f: + f.write(self.pkgbuild) + self.run_makepkg() + pkg, r = self.run_rule_on_tarball( + os.path.join(self.tmpdir, pkgfile), + Namcap.rules.setuptools.package + ) + e, w, i = Namcap.depends.analyze_depends(pkg) + self.assertEqual(e + r.errors, + [('dependency-detected-not-included %s (%s)', + ('python2-setuptools', "needed for programs ['usr/bin/foobar']") + )]) + self.assertEqual(r.warnings, []) + self.assertTrue( + ("setuptools-needed-dep %s in %s", ("python2-setuptools", ["usr/bin/foobar"])) + in r.infos) + + +# vim: set ts=4 sw=4 noet: diff --git a/namcap-tags b/namcap-tags index d638478..fa23abe 100644 --- a/namcap-tags +++ b/namcap-tags @@ -69,6 +69,7 @@ potential-non-fhs-info-page %s :: Potential non-FHS info page (%s) found. potential-non-fhs-man-page %s :: Potential non-FHS man page (%s) found. script-link-detected %s in %s :: Script link detected (%s) in file %s scrollkeeper-dir-exists %s :: Scrollkeeper directory exists (%s). Remember to not run scrollkeeper till post_{install,upgrade,remove}. +setuptools-needed-dep %s in %s :: %s probably needed for python programs %s to run correctly site-ruby :: Found usr/lib/ruby/site_ruby in package, usr/lib/ruby/vendor_ruby should be used instead. specific-host-type-used %s :: Reference to %s should be changed to $CARCH specific-sourceforge-mirror :: Attempting to use specific sourceforge mirror, use downloads.sourceforge.net instead @@ -98,3 +99,4 @@ kdebase-runtime-needed %s :: needed for programs %s java-environment-needed %s :: found class files %s libraries-needed %s %s :: libraries %s needed in files %s programs-needed %s %s :: programs %s needed in scripts %s +setuptools-needed %s :: needed for programs %s -- 1.9.0
On Fri, Feb 21, 2014 at 6:10 AM, Felix Yan <felixonmars@gmail.com> wrote:
This rule detects python imports from pkg_resources from python*-setupsools in /usr/bin/*. Missing dependency on corresponding setuptools package will render the executables unusable.
Why do we need a special rule for setuptools? It is not different that the hundreds of python packages required to run all the different binaries out there. IMO, this is a case where the packager should consult the upstream documentation.
On Friday, February 21, 2014 17:01:06 Eric Bélanger wrote:
On Fri, Feb 21, 2014 at 6:10 AM, Felix Yan <felixonmars@gmail.com> wrote:
This rule detects python imports from pkg_resources from python*-setupsools in /usr/bin/*. Missing dependency on corresponding setuptools package will render the executables unusable.
Why do we need a special rule for setuptools? It is not different that the hundreds of python packages required to run all the different binaries out there. IMO, this is a case where the packager should consult the upstream documentation.
Sorry, I should explain more on the commit message. I have the following reasons to have this special rule for setuptools added: - Upstreams often recommend to use "pip install xxx" and have setuptools installed at installation time, since setuptools is a hard dependency of pip. But this doesn't give any information about if setuptools is still needed after installation. The rule I added will just check for that. - Adding executables with dependency on setuptools is a default behavior of setuptools [1]. Even upstream themselves may not care about it too much. But it's still something that we have to care when packaging. - setuptools is kind of a basic package, like the existing rule to check for kdelibs. Packagers may not notice the dependency, since he or she may already installed something that depends on setuptools. - We already have 17 bug reports on flyspray about missing dependency on setuptools, out of 24 total for a search of setuptools [2]. And you may notice that hgsvn has appeared twice - that may mean, after a new packager see the information about dependency not needed: setuptools, he removed it. This is where namcap could help. Let me know about what you think :) [1] http://guide.python-distribute.org/creation.html#entry-points [2] https://bugs.archlinux.org/index.php?string=setuptools&project=0&search_name=&type%5B%5D=&sev%5B%5D=&pri%5B%5D=&due%5B%5D=&reported%5B%5D=&cat%5B%5D=&status%5B%5D=&percent%5B%5D=&opened=&dev=&closed=&duedatefrom=&duedateto=&changedfrom=&changedto=&openedfrom=&openedto=&closedfrom=&closedto=&do=index Regards, Felix Yan
participants (2)
-
Eric Bélanger
-
Felix Yan