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
---
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
+#
+# 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
+#
+# 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