Gentoo Archives: gentoo-commits

From: Zac Medico <zmedico@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: pym/portage/tests/util/, pym/portage/util/
Date: Wed, 27 Jun 2018 03:32:33
Message-Id: 1530069308.deb87a465306d05146d7eb55d27d7d89943725c0.zmedico@gentoo
1 commit: deb87a465306d05146d7eb55d27d7d89943725c0
2 Author: Zac Medico <zmedico <AT> gentoo <DOT> org>
3 AuthorDate: Sun Jun 24 21:42:52 2018 +0000
4 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org>
5 CommitDate: Wed Jun 27 03:15:08 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=deb87a46
7
8 {,PKG_}INSTALL_MASK: support trailing slash (bug 658322)
9
10 Fix the python INSTALL_MASK implementation so that a trailing slash
11 matches a directory, for compatibility with the previous bash
12 implementation.
13
14 Fixes: 3416876c0ee7 ("{,PKG_}INSTALL_MASK: python implementation")
15 Bug: https://bugs.gentoo.org/658322
16
17 pym/portage/tests/util/test_install_mask.py | 129 ++++++++++++++++++++++++++++
18 pym/portage/util/install_mask.py | 7 +-
19 2 files changed, 134 insertions(+), 2 deletions(-)
20
21 diff --git a/pym/portage/tests/util/test_install_mask.py b/pym/portage/tests/util/test_install_mask.py
22 new file mode 100644
23 index 000000000..f651eb4b7
24 --- /dev/null
25 +++ b/pym/portage/tests/util/test_install_mask.py
26 @@ -0,0 +1,129 @@
27 +# Copyright 2018 Gentoo Foundation
28 +# Distributed under the terms of the GNU General Public License v2
29 +
30 +from portage.tests import TestCase
31 +from portage.util.install_mask import InstallMask
32 +
33 +
34 +class InstallMaskTestCase(TestCase):
35 +
36 + def testTrailingSlash(self):
37 + """
38 + Test that elements with a trailing slash match a directory
39 + but not a regular file.
40 + """
41 + cases = (
42 + (
43 + '/foo/bar/ -/foo/bar/*.foo -*.baz',
44 + (
45 + (
46 + 'foo/bar/baz',
47 + True,
48 + ),
49 + (
50 + 'foo/bar/',
51 + True,
52 + ),
53 + # /foo/bar/ does not match
54 + (
55 + 'foo/bar',
56 + False,
57 + ),
58 + # this is excluded
59 + (
60 + 'foo/bar/baz.foo',
61 + False,
62 + ),
63 + # this is excluded
64 + (
65 + 'foo/bar/baz.baz',
66 + False,
67 + ),
68 + (
69 + 'foo/bar/baz.bar',
70 + True,
71 + ),
72 + )
73 + ),
74 + (
75 + '/foo/bar -/foo/bar/*.foo -*.baz',
76 + (
77 + (
78 + 'foo/bar/baz',
79 + True,
80 + ),
81 + # /foo/bar matches both foo/bar/ and foo/bar
82 + (
83 + 'foo/bar/',
84 + True,
85 + ),
86 + (
87 + 'foo/bar',
88 + True,
89 + ),
90 + # this is excluded
91 + (
92 + 'foo/bar/baz.foo',
93 + False,
94 + ),
95 + # this is excluded
96 + (
97 + 'foo/bar/baz.baz',
98 + False,
99 + ),
100 + (
101 + 'foo/bar/baz.bar',
102 + True,
103 + ),
104 + )
105 + ),
106 + (
107 + '/foo*',
108 + (
109 + (
110 + 'foo',
111 + True,
112 + ),
113 + (
114 + 'foo/',
115 + True,
116 + ),
117 + (
118 + 'foobar',
119 + True,
120 + ),
121 + (
122 + 'foobar/',
123 + True,
124 + ),
125 + )
126 + ),
127 + (
128 + '/foo*/',
129 + (
130 + (
131 + 'foo',
132 + False,
133 + ),
134 + (
135 + 'foo/',
136 + True,
137 + ),
138 + (
139 + 'foobar',
140 + False,
141 + ),
142 + (
143 + 'foobar/',
144 + True,
145 + ),
146 + )
147 + ),
148 + )
149 +
150 + for install_mask_str, paths in cases:
151 + install_mask = InstallMask(install_mask_str)
152 + for path, expected in paths:
153 + self.assertEqual(install_mask.match(path), expected,
154 + 'unexpected match result for "{}" with path {}'.\
155 + format(install_mask_str, path))
156
157 diff --git a/pym/portage/util/install_mask.py b/pym/portage/util/install_mask.py
158 index 1667d883a..32627eb05 100644
159 --- a/pym/portage/util/install_mask.py
160 +++ b/pym/portage/util/install_mask.py
161 @@ -41,10 +41,13 @@ class InstallMask(object):
162 pattern = pattern[1:]
163 # absolute path pattern
164 if pattern.startswith('/'):
165 + # handle trailing slash for explicit directory match
166 + if path.endswith('/'):
167 + pattern = pattern.rstrip('/') + '/'
168 # match either exact path or one of parent dirs
169 # the latter is done via matching pattern/*
170 if (fnmatch.fnmatch(path, pattern[1:])
171 - or fnmatch.fnmatch(path, pattern[1:] + '/*')):
172 + or fnmatch.fnmatch(path, pattern[1:].rstrip('/') + '/*')):
173 ret = is_inclusive
174 # filename
175 else:
176 @@ -118,7 +121,7 @@ def install_mask_dir(base_dir, install_mask, onerror=None):
177 except IndexError:
178 break
179
180 - if install_mask.match(dir_path[base_dir_len:]):
181 + if install_mask.match(dir_path[base_dir_len:] + '/'):
182 try:
183 os.rmdir(dir_path)
184 except OSError: