1 |
Fix the python INSTALL_MASK implementation so that a trailing slash |
2 |
matches a directory, for compatibility with the previous bash |
3 |
implementation. |
4 |
|
5 |
Fixes: 3416876c0ee7 ("{,PKG_}INSTALL_MASK: python implementation") |
6 |
Bug: https://bugs.gentoo.org/658322 |
7 |
--- |
8 |
pym/portage/tests/util/test_install_mask.py | 87 +++++++++++++++++++++++++++++ |
9 |
pym/portage/util/install_mask.py | 7 ++- |
10 |
2 files changed, 92 insertions(+), 2 deletions(-) |
11 |
create mode 100644 pym/portage/tests/util/test_install_mask.py |
12 |
|
13 |
diff --git a/pym/portage/tests/util/test_install_mask.py b/pym/portage/tests/util/test_install_mask.py |
14 |
new file mode 100644 |
15 |
index 0000000000..0badcf0165 |
16 |
--- /dev/null |
17 |
+++ b/pym/portage/tests/util/test_install_mask.py |
18 |
@@ -0,0 +1,87 @@ |
19 |
+# Copyright 2018 Gentoo Foundation |
20 |
+# Distributed under the terms of the GNU General Public License v2 |
21 |
+ |
22 |
+from portage.tests import TestCase |
23 |
+from portage.util.install_mask import InstallMask |
24 |
+ |
25 |
+ |
26 |
+class InstallMaskTestCase(TestCase): |
27 |
+ |
28 |
+ def testTrailingSlash(self): |
29 |
+ """ |
30 |
+ Test that elements with a trailing slash match a directory |
31 |
+ but not a regular file. |
32 |
+ """ |
33 |
+ cases = ( |
34 |
+ ( |
35 |
+ '/foo/bar/ -/foo/bar/*.foo -*.baz', |
36 |
+ ( |
37 |
+ ( |
38 |
+ 'foo/bar/baz', |
39 |
+ True, |
40 |
+ ), |
41 |
+ ( |
42 |
+ 'foo/bar/', |
43 |
+ True, |
44 |
+ ), |
45 |
+ # /foo/bar/ does not match |
46 |
+ ( |
47 |
+ 'foo/bar', |
48 |
+ False, |
49 |
+ ), |
50 |
+ # this is excluded |
51 |
+ ( |
52 |
+ 'foo/bar/baz.foo', |
53 |
+ False, |
54 |
+ ), |
55 |
+ # this is excluded |
56 |
+ ( |
57 |
+ 'foo/bar/baz.baz', |
58 |
+ False, |
59 |
+ ), |
60 |
+ ( |
61 |
+ 'foo/bar/baz.bar', |
62 |
+ True, |
63 |
+ ), |
64 |
+ ) |
65 |
+ ), |
66 |
+ ( |
67 |
+ '/foo/bar -/foo/bar/*.foo -*.baz', |
68 |
+ ( |
69 |
+ ( |
70 |
+ 'foo/bar/baz', |
71 |
+ True, |
72 |
+ ), |
73 |
+ # /foo/bar matches both foo/bar/ and foo/bar |
74 |
+ ( |
75 |
+ 'foo/bar/', |
76 |
+ True, |
77 |
+ ), |
78 |
+ ( |
79 |
+ 'foo/bar', |
80 |
+ True, |
81 |
+ ), |
82 |
+ # this is excluded |
83 |
+ ( |
84 |
+ 'foo/bar/baz.foo', |
85 |
+ False, |
86 |
+ ), |
87 |
+ # this is excluded |
88 |
+ ( |
89 |
+ 'foo/bar/baz.baz', |
90 |
+ False, |
91 |
+ ), |
92 |
+ ( |
93 |
+ 'foo/bar/baz.bar', |
94 |
+ True, |
95 |
+ ), |
96 |
+ ) |
97 |
+ ), |
98 |
+ ) |
99 |
+ |
100 |
+ for install_mask_str, paths in cases: |
101 |
+ install_mask = InstallMask(install_mask_str) |
102 |
+ for path, expected in paths: |
103 |
+ self.assertEqual(install_mask.match(path), expected, |
104 |
+ 'unexpected match result for "{}" with path {}'.\ |
105 |
+ format(install_mask_str, path)) |
106 |
diff --git a/pym/portage/util/install_mask.py b/pym/portage/util/install_mask.py |
107 |
index 1667d883a0..32627eb05b 100644 |
108 |
--- a/pym/portage/util/install_mask.py |
109 |
+++ b/pym/portage/util/install_mask.py |
110 |
@@ -41,10 +41,13 @@ class InstallMask(object): |
111 |
pattern = pattern[1:] |
112 |
# absolute path pattern |
113 |
if pattern.startswith('/'): |
114 |
+ # handle trailing slash for explicit directory match |
115 |
+ if path.endswith('/'): |
116 |
+ pattern = pattern.rstrip('/') + '/' |
117 |
# match either exact path or one of parent dirs |
118 |
# the latter is done via matching pattern/* |
119 |
if (fnmatch.fnmatch(path, pattern[1:]) |
120 |
- or fnmatch.fnmatch(path, pattern[1:] + '/*')): |
121 |
+ or fnmatch.fnmatch(path, pattern[1:].rstrip('/') + '/*')): |
122 |
ret = is_inclusive |
123 |
# filename |
124 |
else: |
125 |
@@ -118,7 +121,7 @@ def install_mask_dir(base_dir, install_mask, onerror=None): |
126 |
except IndexError: |
127 |
break |
128 |
|
129 |
- if install_mask.match(dir_path[base_dir_len:]): |
130 |
+ if install_mask.match(dir_path[base_dir_len:] + '/'): |
131 |
try: |
132 |
os.rmdir(dir_path) |
133 |
except OSError: |
134 |
-- |
135 |
2.13.6 |