blob: 69b88f2df2a613fa1af0f81f871d18ce425bd563 [file] [log] [blame]
Tarek Ziadéfaa6b122009-04-05 21:44:08 +00001"""Tests for distutils.filelist."""
Éric Araujo31378df2012-02-25 16:13:53 +01002import os
Éric Araujo5baef6d2011-10-14 18:15:31 +02003import re
Tarek Ziadéfaa6b122009-04-05 21:44:08 +00004import unittest
Tarek Ziadé6d2db372009-09-21 12:19:07 +00005from distutils import debug
Éric Araujo5baef6d2011-10-14 18:15:31 +02006from distutils.log import WARN
7from distutils.errors import DistutilsTemplateError
8from distutils.filelist import glob_to_re, translate_pattern, FileList
9
10from test.test_support import captured_stdout, run_unittest
11from distutils.tests import support
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +000012
13MANIFEST_IN = """\
14include ok
15include xo
16exclude xo
17include foo.tmp
Éric Araujo31378df2012-02-25 16:13:53 +010018include buildout.cfg
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +000019global-include *.x
20global-include *.txt
21global-exclude *.tmp
22recursive-include f *.oo
23recursive-exclude global *.x
24graft dir
25prune dir3
26"""
Tarek Ziadéfaa6b122009-04-05 21:44:08 +000027
Éric Araujo5baef6d2011-10-14 18:15:31 +020028
Éric Araujo31378df2012-02-25 16:13:53 +010029def make_local_path(s):
30 """Converts '/' in a string to os.sep"""
31 return s.replace('/', os.sep)
32
33
Éric Araujo5baef6d2011-10-14 18:15:31 +020034class FileListTestCase(support.LoggingSilencer,
35 unittest.TestCase):
36
37 def assertNoWarnings(self):
38 self.assertEqual(self.get_logs(WARN), [])
39 self.clear_logs()
40
41 def assertWarnings(self):
42 self.assertGreater(len(self.get_logs(WARN)), 0)
43 self.clear_logs()
Tarek Ziadéfaa6b122009-04-05 21:44:08 +000044
45 def test_glob_to_re(self):
Éric Araujo31378df2012-02-25 16:13:53 +010046 sep = os.sep
47 if os.sep == '\\':
48 sep = re.escape(os.sep)
Tarek Ziadéfaa6b122009-04-05 21:44:08 +000049
Éric Araujo31378df2012-02-25 16:13:53 +010050 for glob, regex in (
51 # simple cases
52 ('foo*', r'foo[^%(sep)s]*\Z(?ms)'),
53 ('foo?', r'foo[^%(sep)s]\Z(?ms)'),
54 ('foo??', r'foo[^%(sep)s][^%(sep)s]\Z(?ms)'),
55 # special cases
56 (r'foo\\*', r'foo\\\\[^%(sep)s]*\Z(?ms)'),
57 (r'foo\\\*', r'foo\\\\\\[^%(sep)s]*\Z(?ms)'),
58 ('foo????', r'foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s]\Z(?ms)'),
59 (r'foo\\??', r'foo\\\\[^%(sep)s][^%(sep)s]\Z(?ms)')):
60 regex = regex % {'sep': sep}
61 self.assertEqual(glob_to_re(glob), regex)
Tarek Ziadéfaa6b122009-04-05 21:44:08 +000062
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +000063 def test_process_template_line(self):
64 # testing all MANIFEST.in template patterns
65 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +010066 l = make_local_path
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +000067
68 # simulated file list
Tarek Ziadé91329162009-08-18 08:21:49 +000069 file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt',
Éric Araujo31378df2012-02-25 16:13:53 +010070 'buildout.cfg',
71 # filelist does not filter out VCS directories,
72 # it's sdist that does
73 l('.hg/last-message.txt'),
74 l('global/one.txt'),
75 l('global/two.txt'),
76 l('global/files.x'),
77 l('global/here.tmp'),
78 l('f/o/f.oo'),
79 l('dir/graft-one'),
80 l('dir/dir2/graft2'),
81 l('dir3/ok'),
82 l('dir3/sub/ok.txt'),
83 ]
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +000084
85 for line in MANIFEST_IN.split('\n'):
86 if line.strip() == '':
87 continue
88 file_list.process_template_line(line)
89
Éric Araujo31378df2012-02-25 16:13:53 +010090 wanted = ['ok',
91 'buildout.cfg',
92 'four.txt',
93 l('.hg/last-message.txt'),
94 l('global/one.txt'),
95 l('global/two.txt'),
96 l('f/o/f.oo'),
97 l('dir/graft-one'),
98 l('dir/dir2/graft2'),
99 ]
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +0000100
Ezio Melotti2623a372010-11-21 13:34:58 +0000101 self.assertEqual(file_list.files, wanted)
Tarek Ziadé1c8c9d12009-08-18 08:16:33 +0000102
Tarek Ziadé6d2db372009-09-21 12:19:07 +0000103 def test_debug_print(self):
104 file_list = FileList()
105 with captured_stdout() as stdout:
106 file_list.debug_print('xxx')
Éric Araujo5baef6d2011-10-14 18:15:31 +0200107 self.assertEqual(stdout.getvalue(), '')
Tarek Ziadé6d2db372009-09-21 12:19:07 +0000108
109 debug.DEBUG = True
110 try:
111 with captured_stdout() as stdout:
112 file_list.debug_print('xxx')
Éric Araujo5baef6d2011-10-14 18:15:31 +0200113 self.assertEqual(stdout.getvalue(), 'xxx\n')
Tarek Ziadé6d2db372009-09-21 12:19:07 +0000114 finally:
115 debug.DEBUG = False
116
Éric Araujo5baef6d2011-10-14 18:15:31 +0200117 def test_set_allfiles(self):
118 file_list = FileList()
119 files = ['a', 'b', 'c']
120 file_list.set_allfiles(files)
121 self.assertEqual(file_list.allfiles, files)
122
123 def test_remove_duplicates(self):
124 file_list = FileList()
125 file_list.files = ['a', 'b', 'a', 'g', 'c', 'g']
126 # files must be sorted beforehand (sdist does it)
127 file_list.sort()
128 file_list.remove_duplicates()
129 self.assertEqual(file_list.files, ['a', 'b', 'c', 'g'])
130
131 def test_translate_pattern(self):
132 # not regex
133 self.assertTrue(hasattr(
134 translate_pattern('a', anchor=True, is_regex=False),
135 'search'))
136
137 # is a regex
138 regex = re.compile('a')
139 self.assertEqual(
140 translate_pattern(regex, anchor=True, is_regex=True),
141 regex)
142
143 # plain string flagged as regex
144 self.assertTrue(hasattr(
145 translate_pattern('a', anchor=True, is_regex=True),
146 'search'))
147
148 # glob support
149 self.assertTrue(translate_pattern(
150 '*.py', anchor=True, is_regex=False).search('filelist.py'))
151
152 def test_exclude_pattern(self):
153 # return False if no match
154 file_list = FileList()
155 self.assertFalse(file_list.exclude_pattern('*.py'))
156
157 # return True if files match
158 file_list = FileList()
159 file_list.files = ['a.py', 'b.py']
160 self.assertTrue(file_list.exclude_pattern('*.py'))
161
162 # test excludes
163 file_list = FileList()
164 file_list.files = ['a.py', 'a.txt']
165 file_list.exclude_pattern('*.py')
166 self.assertEqual(file_list.files, ['a.txt'])
167
168 def test_include_pattern(self):
169 # return False if no match
170 file_list = FileList()
171 file_list.set_allfiles([])
172 self.assertFalse(file_list.include_pattern('*.py'))
173
174 # return True if files match
175 file_list = FileList()
176 file_list.set_allfiles(['a.py', 'b.txt'])
177 self.assertTrue(file_list.include_pattern('*.py'))
178
179 # test * matches all files
180 file_list = FileList()
181 self.assertIsNone(file_list.allfiles)
182 file_list.set_allfiles(['a.py', 'b.txt'])
183 file_list.include_pattern('*')
184 self.assertEqual(file_list.allfiles, ['a.py', 'b.txt'])
185
186 def test_process_template(self):
Éric Araujo31378df2012-02-25 16:13:53 +0100187 l = make_local_path
Éric Araujo5baef6d2011-10-14 18:15:31 +0200188 # invalid lines
189 file_list = FileList()
190 for action in ('include', 'exclude', 'global-include',
191 'global-exclude', 'recursive-include',
192 'recursive-exclude', 'graft', 'prune', 'blarg'):
193 self.assertRaises(DistutilsTemplateError,
194 file_list.process_template_line, action)
195
196 # include
197 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100198 file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200199
200 file_list.process_template_line('include *.py')
201 self.assertEqual(file_list.files, ['a.py'])
202 self.assertNoWarnings()
203
204 file_list.process_template_line('include *.rb')
205 self.assertEqual(file_list.files, ['a.py'])
206 self.assertWarnings()
207
208 # exclude
209 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100210 file_list.files = ['a.py', 'b.txt', l('d/c.py')]
Éric Araujo5baef6d2011-10-14 18:15:31 +0200211
212 file_list.process_template_line('exclude *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100213 self.assertEqual(file_list.files, ['b.txt', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200214 self.assertNoWarnings()
215
216 file_list.process_template_line('exclude *.rb')
Éric Araujo31378df2012-02-25 16:13:53 +0100217 self.assertEqual(file_list.files, ['b.txt', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200218 self.assertWarnings()
219
220 # global-include
221 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100222 file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200223
224 file_list.process_template_line('global-include *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100225 self.assertEqual(file_list.files, ['a.py', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200226 self.assertNoWarnings()
227
228 file_list.process_template_line('global-include *.rb')
Éric Araujo31378df2012-02-25 16:13:53 +0100229 self.assertEqual(file_list.files, ['a.py', l('d/c.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200230 self.assertWarnings()
231
232 # global-exclude
233 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100234 file_list.files = ['a.py', 'b.txt', l('d/c.py')]
Éric Araujo5baef6d2011-10-14 18:15:31 +0200235
236 file_list.process_template_line('global-exclude *.py')
237 self.assertEqual(file_list.files, ['b.txt'])
238 self.assertNoWarnings()
239
240 file_list.process_template_line('global-exclude *.rb')
241 self.assertEqual(file_list.files, ['b.txt'])
242 self.assertWarnings()
243
244 # recursive-include
245 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100246 file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'),
247 l('d/d/e.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200248
249 file_list.process_template_line('recursive-include d *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100250 self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200251 self.assertNoWarnings()
252
253 file_list.process_template_line('recursive-include e *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100254 self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200255 self.assertWarnings()
256
257 # recursive-exclude
258 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100259 file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')]
Éric Araujo5baef6d2011-10-14 18:15:31 +0200260
261 file_list.process_template_line('recursive-exclude d *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100262 self.assertEqual(file_list.files, ['a.py', l('d/c.txt')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200263 self.assertNoWarnings()
264
265 file_list.process_template_line('recursive-exclude e *.py')
Éric Araujo31378df2012-02-25 16:13:53 +0100266 self.assertEqual(file_list.files, ['a.py', l('d/c.txt')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200267 self.assertWarnings()
268
269 # graft
270 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100271 file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'),
272 l('f/f.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200273
274 file_list.process_template_line('graft d')
Éric Araujo31378df2012-02-25 16:13:53 +0100275 self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200276 self.assertNoWarnings()
277
278 file_list.process_template_line('graft e')
Éric Araujo31378df2012-02-25 16:13:53 +0100279 self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200280 self.assertWarnings()
281
282 # prune
283 file_list = FileList()
Éric Araujo31378df2012-02-25 16:13:53 +0100284 file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')]
Éric Araujo5baef6d2011-10-14 18:15:31 +0200285
286 file_list.process_template_line('prune d')
Éric Araujo31378df2012-02-25 16:13:53 +0100287 self.assertEqual(file_list.files, ['a.py', l('f/f.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200288 self.assertNoWarnings()
289
290 file_list.process_template_line('prune e')
Éric Araujo31378df2012-02-25 16:13:53 +0100291 self.assertEqual(file_list.files, ['a.py', l('f/f.py')])
Éric Araujo5baef6d2011-10-14 18:15:31 +0200292 self.assertWarnings()
293
294
Tarek Ziadéfaa6b122009-04-05 21:44:08 +0000295def test_suite():
296 return unittest.makeSuite(FileListTestCase)
297
298if __name__ == "__main__":
Éric Araujo54274ad2011-02-03 00:12:18 +0000299 run_unittest(test_suite())