aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2018-06-24 14:42:52 -0700
committerZac Medico <zmedico@gentoo.org>2018-06-26 20:15:08 -0700
commitdeb87a465306d05146d7eb55d27d7d89943725c0 (patch)
treeb73df66b1087e4835b6f7ed2e5710322ee57c52a
parentAsyncioEventLoop: exit after unhandled exception (bug 658684) (diff)
downloadportage-deb87a465306d05146d7eb55d27d7d89943725c0.tar.gz
portage-deb87a465306d05146d7eb55d27d7d89943725c0.tar.bz2
portage-deb87a465306d05146d7eb55d27d7d89943725c0.zip
{,PKG_}INSTALL_MASK: support trailing slash (bug 658322)
Fix the python INSTALL_MASK implementation so that a trailing slash matches a directory, for compatibility with the previous bash implementation. Fixes: 3416876c0ee7 ("{,PKG_}INSTALL_MASK: python implementation") Bug: https://bugs.gentoo.org/658322
-rw-r--r--pym/portage/tests/util/test_install_mask.py129
-rw-r--r--pym/portage/util/install_mask.py7
2 files changed, 134 insertions, 2 deletions
diff --git a/pym/portage/tests/util/test_install_mask.py b/pym/portage/tests/util/test_install_mask.py
new file mode 100644
index 000000000..f651eb4b7
--- /dev/null
+++ b/pym/portage/tests/util/test_install_mask.py
@@ -0,0 +1,129 @@
+# Copyright 2018 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.util.install_mask import InstallMask
+
+
+class InstallMaskTestCase(TestCase):
+
+ def testTrailingSlash(self):
+ """
+ Test that elements with a trailing slash match a directory
+ but not a regular file.
+ """
+ cases = (
+ (
+ '/foo/bar/ -/foo/bar/*.foo -*.baz',
+ (
+ (
+ 'foo/bar/baz',
+ True,
+ ),
+ (
+ 'foo/bar/',
+ True,
+ ),
+ # /foo/bar/ does not match
+ (
+ 'foo/bar',
+ False,
+ ),
+ # this is excluded
+ (
+ 'foo/bar/baz.foo',
+ False,
+ ),
+ # this is excluded
+ (
+ 'foo/bar/baz.baz',
+ False,
+ ),
+ (
+ 'foo/bar/baz.bar',
+ True,
+ ),
+ )
+ ),
+ (
+ '/foo/bar -/foo/bar/*.foo -*.baz',
+ (
+ (
+ 'foo/bar/baz',
+ True,
+ ),
+ # /foo/bar matches both foo/bar/ and foo/bar
+ (
+ 'foo/bar/',
+ True,
+ ),
+ (
+ 'foo/bar',
+ True,
+ ),
+ # this is excluded
+ (
+ 'foo/bar/baz.foo',
+ False,
+ ),
+ # this is excluded
+ (
+ 'foo/bar/baz.baz',
+ False,
+ ),
+ (
+ 'foo/bar/baz.bar',
+ True,
+ ),
+ )
+ ),
+ (
+ '/foo*',
+ (
+ (
+ 'foo',
+ True,
+ ),
+ (
+ 'foo/',
+ True,
+ ),
+ (
+ 'foobar',
+ True,
+ ),
+ (
+ 'foobar/',
+ True,
+ ),
+ )
+ ),
+ (
+ '/foo*/',
+ (
+ (
+ 'foo',
+ False,
+ ),
+ (
+ 'foo/',
+ True,
+ ),
+ (
+ 'foobar',
+ False,
+ ),
+ (
+ 'foobar/',
+ True,
+ ),
+ )
+ ),
+ )
+
+ for install_mask_str, paths in cases:
+ install_mask = InstallMask(install_mask_str)
+ for path, expected in paths:
+ self.assertEqual(install_mask.match(path), expected,
+ 'unexpected match result for "{}" with path {}'.\
+ format(install_mask_str, path))
diff --git a/pym/portage/util/install_mask.py b/pym/portage/util/install_mask.py
index 1667d883a..32627eb05 100644
--- a/pym/portage/util/install_mask.py
+++ b/pym/portage/util/install_mask.py
@@ -41,10 +41,13 @@ class InstallMask(object):
pattern = pattern[1:]
# absolute path pattern
if pattern.startswith('/'):
+ # handle trailing slash for explicit directory match
+ if path.endswith('/'):
+ pattern = pattern.rstrip('/') + '/'
# match either exact path or one of parent dirs
# the latter is done via matching pattern/*
if (fnmatch.fnmatch(path, pattern[1:])
- or fnmatch.fnmatch(path, pattern[1:] + '/*')):
+ or fnmatch.fnmatch(path, pattern[1:].rstrip('/') + '/*')):
ret = is_inclusive
# filename
else:
@@ -118,7 +121,7 @@ def install_mask_dir(base_dir, install_mask, onerror=None):
except IndexError:
break
- if install_mask.match(dir_path[base_dir_len:]):
+ if install_mask.match(dir_path[base_dir_len:] + '/'):
try:
os.rmdir(dir_path)
except OSError: