If the user has a non-canonical (i.e. symlinked on Arch) location in
front of their $PATH, such as /usr/sbin, shutil.which will return
locations with that path. This later causes the rule to fail to find
the binary in any packages, causing spurious
library-no-package-associated and dependency-not-needed warnings.

Fix this by resolving all symlinks for executables (using
os.path.realpath) before trying to find them among installed packages.
---
 Namcap/rules/shebangdepends.py              |  3 +-
 Namcap/tests/package/test_shebangdepends.py | 38 +++++++++++++++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/Namcap/rules/shebangdepends.py b/Namcap/rules/shebangdepends.py
index 07896df..fc359c3 100644
--- a/Namcap/rules/shebangdepends.py
+++ b/Namcap/rules/shebangdepends.py
@@ -21,7 +21,7 @@
 
 """Checks dependencies on programs specified in shebangs."""
 
-import shutil
+import shutil, os.path
 import Namcap.package
 from Namcap.util import is_script, script_type
 from Namcap.ruleclass import *
@@ -59,6 +59,7 @@ def findowners(scriptlist):
                out = shutil.which(s)
                if not out:
                        continue
+               out = os.path.realpath(out)
 
                # strip leading slash
                scriptpath = out.lstrip('/')
diff --git a/Namcap/tests/package/test_shebangdepends.py 
b/Namcap/tests/package/test_shebangdepends.py
index dbacd86..b92e9fe 100644
--- a/Namcap/tests/package/test_shebangdepends.py
+++ b/Namcap/tests/package/test_shebangdepends.py
@@ -60,5 +60,43 @@ package() {
                ])
                self.assertEqual(w, [])
 
+       valid_pkgbuild = """
+pkgname=__namcap_test_shebangdepends
+pkgver=1.0
+pkgrel=1
+pkgdesc="A package"
+arch=('any')
+url="http://www.example.com/";
+license=('GPL')
+depends=('python')
+source=()
+options=(!purge !zipman)
+build() {
+  cd "${srcdir}"
+  echo -e "#! /usr/bin/env python\nprint('a script')" > python_sample
+}
+package() {
+  install -Dm755 "$srcdir/python_sample" "$pkgdir/usr/bin/python_sample"
+}
+"""
+       def test_shebangdepends_noncanonical(self):
+               "shutil.which returns noncanonical path (e.g. in /usr/sbin)"
+               pkgfile = "__namcap_test_shebangdepends-1.0-1-any.pkg.tar"
+               with open(os.path.join(self.tmpdir, "PKGBUILD"), "w") as f:
+                       f.write(self.valid_pkgbuild)
+               self.run_makepkg()
+               old_path = os.environ['PATH']
+               try:
+                       os.environ['PATH'] = '/usr/sbin:' + old_path
+                       pkg, r = self.run_rule_on_tarball(
+                                       os.path.join(self.tmpdir, pkgfile),
+                                       
Namcap.rules.shebangdepends.ShebangDependsRule
+                                       )
+               finally:
+                       os.environ['PATH'] = old_path
+               e, w, i = Namcap.depends.analyze_depends(pkg)
+               self.assertEqual(e, [])
+               self.assertEqual(w, [])
+
 # vim: set ts=4 sw=4 noet:
 
-- 
2.25.0

Reply via email to