17db96d56Sopenharmony_ci"""Tests for distutils.filelist.""" 27db96d56Sopenharmony_ciimport os 37db96d56Sopenharmony_ciimport re 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_cifrom distutils import debug 67db96d56Sopenharmony_cifrom distutils.log import WARN 77db96d56Sopenharmony_cifrom distutils.errors import DistutilsTemplateError 87db96d56Sopenharmony_cifrom distutils.filelist import glob_to_re, translate_pattern, FileList 97db96d56Sopenharmony_cifrom distutils import filelist 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_cifrom test.support import os_helper 127db96d56Sopenharmony_cifrom test.support import captured_stdout, run_unittest 137db96d56Sopenharmony_cifrom distutils.tests import support 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ciMANIFEST_IN = """\ 167db96d56Sopenharmony_ciinclude ok 177db96d56Sopenharmony_ciinclude xo 187db96d56Sopenharmony_ciexclude xo 197db96d56Sopenharmony_ciinclude foo.tmp 207db96d56Sopenharmony_ciinclude buildout.cfg 217db96d56Sopenharmony_ciglobal-include *.x 227db96d56Sopenharmony_ciglobal-include *.txt 237db96d56Sopenharmony_ciglobal-exclude *.tmp 247db96d56Sopenharmony_cirecursive-include f *.oo 257db96d56Sopenharmony_cirecursive-exclude global *.x 267db96d56Sopenharmony_cigraft dir 277db96d56Sopenharmony_ciprune dir3 287db96d56Sopenharmony_ci""" 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_cidef make_local_path(s): 327db96d56Sopenharmony_ci """Converts '/' in a string to os.sep""" 337db96d56Sopenharmony_ci return s.replace('/', os.sep) 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciclass FileListTestCase(support.LoggingSilencer, 377db96d56Sopenharmony_ci unittest.TestCase): 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci def assertNoWarnings(self): 407db96d56Sopenharmony_ci self.assertEqual(self.get_logs(WARN), []) 417db96d56Sopenharmony_ci self.clear_logs() 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_ci def assertWarnings(self): 447db96d56Sopenharmony_ci self.assertGreater(len(self.get_logs(WARN)), 0) 457db96d56Sopenharmony_ci self.clear_logs() 467db96d56Sopenharmony_ci 477db96d56Sopenharmony_ci def test_glob_to_re(self): 487db96d56Sopenharmony_ci sep = os.sep 497db96d56Sopenharmony_ci if os.sep == '\\': 507db96d56Sopenharmony_ci sep = re.escape(os.sep) 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci for glob, regex in ( 537db96d56Sopenharmony_ci # simple cases 547db96d56Sopenharmony_ci ('foo*', r'(?s:foo[^%(sep)s]*)\Z'), 557db96d56Sopenharmony_ci ('foo?', r'(?s:foo[^%(sep)s])\Z'), 567db96d56Sopenharmony_ci ('foo??', r'(?s:foo[^%(sep)s][^%(sep)s])\Z'), 577db96d56Sopenharmony_ci # special cases 587db96d56Sopenharmony_ci (r'foo\\*', r'(?s:foo\\\\[^%(sep)s]*)\Z'), 597db96d56Sopenharmony_ci (r'foo\\\*', r'(?s:foo\\\\\\[^%(sep)s]*)\Z'), 607db96d56Sopenharmony_ci ('foo????', r'(?s:foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s])\Z'), 617db96d56Sopenharmony_ci (r'foo\\??', r'(?s:foo\\\\[^%(sep)s][^%(sep)s])\Z')): 627db96d56Sopenharmony_ci regex = regex % {'sep': sep} 637db96d56Sopenharmony_ci self.assertEqual(glob_to_re(glob), regex) 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci def test_process_template_line(self): 667db96d56Sopenharmony_ci # testing all MANIFEST.in template patterns 677db96d56Sopenharmony_ci file_list = FileList() 687db96d56Sopenharmony_ci l = make_local_path 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci # simulated file list 717db96d56Sopenharmony_ci file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt', 727db96d56Sopenharmony_ci 'buildout.cfg', 737db96d56Sopenharmony_ci # filelist does not filter out VCS directories, 747db96d56Sopenharmony_ci # it's sdist that does 757db96d56Sopenharmony_ci l('.hg/last-message.txt'), 767db96d56Sopenharmony_ci l('global/one.txt'), 777db96d56Sopenharmony_ci l('global/two.txt'), 787db96d56Sopenharmony_ci l('global/files.x'), 797db96d56Sopenharmony_ci l('global/here.tmp'), 807db96d56Sopenharmony_ci l('f/o/f.oo'), 817db96d56Sopenharmony_ci l('dir/graft-one'), 827db96d56Sopenharmony_ci l('dir/dir2/graft2'), 837db96d56Sopenharmony_ci l('dir3/ok'), 847db96d56Sopenharmony_ci l('dir3/sub/ok.txt'), 857db96d56Sopenharmony_ci ] 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci for line in MANIFEST_IN.split('\n'): 887db96d56Sopenharmony_ci if line.strip() == '': 897db96d56Sopenharmony_ci continue 907db96d56Sopenharmony_ci file_list.process_template_line(line) 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ci wanted = ['ok', 937db96d56Sopenharmony_ci 'buildout.cfg', 947db96d56Sopenharmony_ci 'four.txt', 957db96d56Sopenharmony_ci l('.hg/last-message.txt'), 967db96d56Sopenharmony_ci l('global/one.txt'), 977db96d56Sopenharmony_ci l('global/two.txt'), 987db96d56Sopenharmony_ci l('f/o/f.oo'), 997db96d56Sopenharmony_ci l('dir/graft-one'), 1007db96d56Sopenharmony_ci l('dir/dir2/graft2'), 1017db96d56Sopenharmony_ci ] 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci self.assertEqual(file_list.files, wanted) 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ci def test_debug_print(self): 1067db96d56Sopenharmony_ci file_list = FileList() 1077db96d56Sopenharmony_ci with captured_stdout() as stdout: 1087db96d56Sopenharmony_ci file_list.debug_print('xxx') 1097db96d56Sopenharmony_ci self.assertEqual(stdout.getvalue(), '') 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci debug.DEBUG = True 1127db96d56Sopenharmony_ci try: 1137db96d56Sopenharmony_ci with captured_stdout() as stdout: 1147db96d56Sopenharmony_ci file_list.debug_print('xxx') 1157db96d56Sopenharmony_ci self.assertEqual(stdout.getvalue(), 'xxx\n') 1167db96d56Sopenharmony_ci finally: 1177db96d56Sopenharmony_ci debug.DEBUG = False 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci def test_set_allfiles(self): 1207db96d56Sopenharmony_ci file_list = FileList() 1217db96d56Sopenharmony_ci files = ['a', 'b', 'c'] 1227db96d56Sopenharmony_ci file_list.set_allfiles(files) 1237db96d56Sopenharmony_ci self.assertEqual(file_list.allfiles, files) 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci def test_remove_duplicates(self): 1267db96d56Sopenharmony_ci file_list = FileList() 1277db96d56Sopenharmony_ci file_list.files = ['a', 'b', 'a', 'g', 'c', 'g'] 1287db96d56Sopenharmony_ci # files must be sorted beforehand (sdist does it) 1297db96d56Sopenharmony_ci file_list.sort() 1307db96d56Sopenharmony_ci file_list.remove_duplicates() 1317db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a', 'b', 'c', 'g']) 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci def test_translate_pattern(self): 1347db96d56Sopenharmony_ci # not regex 1357db96d56Sopenharmony_ci self.assertTrue(hasattr( 1367db96d56Sopenharmony_ci translate_pattern('a', anchor=True, is_regex=False), 1377db96d56Sopenharmony_ci 'search')) 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci # is a regex 1407db96d56Sopenharmony_ci regex = re.compile('a') 1417db96d56Sopenharmony_ci self.assertEqual( 1427db96d56Sopenharmony_ci translate_pattern(regex, anchor=True, is_regex=True), 1437db96d56Sopenharmony_ci regex) 1447db96d56Sopenharmony_ci 1457db96d56Sopenharmony_ci # plain string flagged as regex 1467db96d56Sopenharmony_ci self.assertTrue(hasattr( 1477db96d56Sopenharmony_ci translate_pattern('a', anchor=True, is_regex=True), 1487db96d56Sopenharmony_ci 'search')) 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci # glob support 1517db96d56Sopenharmony_ci self.assertTrue(translate_pattern( 1527db96d56Sopenharmony_ci '*.py', anchor=True, is_regex=False).search('filelist.py')) 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci def test_exclude_pattern(self): 1557db96d56Sopenharmony_ci # return False if no match 1567db96d56Sopenharmony_ci file_list = FileList() 1577db96d56Sopenharmony_ci self.assertFalse(file_list.exclude_pattern('*.py')) 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci # return True if files match 1607db96d56Sopenharmony_ci file_list = FileList() 1617db96d56Sopenharmony_ci file_list.files = ['a.py', 'b.py'] 1627db96d56Sopenharmony_ci self.assertTrue(file_list.exclude_pattern('*.py')) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci # test excludes 1657db96d56Sopenharmony_ci file_list = FileList() 1667db96d56Sopenharmony_ci file_list.files = ['a.py', 'a.txt'] 1677db96d56Sopenharmony_ci file_list.exclude_pattern('*.py') 1687db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.txt']) 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci def test_include_pattern(self): 1717db96d56Sopenharmony_ci # return False if no match 1727db96d56Sopenharmony_ci file_list = FileList() 1737db96d56Sopenharmony_ci file_list.set_allfiles([]) 1747db96d56Sopenharmony_ci self.assertFalse(file_list.include_pattern('*.py')) 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci # return True if files match 1777db96d56Sopenharmony_ci file_list = FileList() 1787db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', 'b.txt']) 1797db96d56Sopenharmony_ci self.assertTrue(file_list.include_pattern('*.py')) 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci # test * matches all files 1827db96d56Sopenharmony_ci file_list = FileList() 1837db96d56Sopenharmony_ci self.assertIsNone(file_list.allfiles) 1847db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', 'b.txt']) 1857db96d56Sopenharmony_ci file_list.include_pattern('*') 1867db96d56Sopenharmony_ci self.assertEqual(file_list.allfiles, ['a.py', 'b.txt']) 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci def test_process_template(self): 1897db96d56Sopenharmony_ci l = make_local_path 1907db96d56Sopenharmony_ci # invalid lines 1917db96d56Sopenharmony_ci file_list = FileList() 1927db96d56Sopenharmony_ci for action in ('include', 'exclude', 'global-include', 1937db96d56Sopenharmony_ci 'global-exclude', 'recursive-include', 1947db96d56Sopenharmony_ci 'recursive-exclude', 'graft', 'prune', 'blarg'): 1957db96d56Sopenharmony_ci self.assertRaises(DistutilsTemplateError, 1967db96d56Sopenharmony_ci file_list.process_template_line, action) 1977db96d56Sopenharmony_ci 1987db96d56Sopenharmony_ci # include 1997db96d56Sopenharmony_ci file_list = FileList() 2007db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ci file_list.process_template_line('include *.py') 2037db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py']) 2047db96d56Sopenharmony_ci self.assertNoWarnings() 2057db96d56Sopenharmony_ci 2067db96d56Sopenharmony_ci file_list.process_template_line('include *.rb') 2077db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py']) 2087db96d56Sopenharmony_ci self.assertWarnings() 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ci # exclude 2117db96d56Sopenharmony_ci file_list = FileList() 2127db96d56Sopenharmony_ci file_list.files = ['a.py', 'b.txt', l('d/c.py')] 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci file_list.process_template_line('exclude *.py') 2157db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) 2167db96d56Sopenharmony_ci self.assertNoWarnings() 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci file_list.process_template_line('exclude *.rb') 2197db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) 2207db96d56Sopenharmony_ci self.assertWarnings() 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci # global-include 2237db96d56Sopenharmony_ci file_list = FileList() 2247db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci file_list.process_template_line('global-include *.py') 2277db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) 2287db96d56Sopenharmony_ci self.assertNoWarnings() 2297db96d56Sopenharmony_ci 2307db96d56Sopenharmony_ci file_list.process_template_line('global-include *.rb') 2317db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) 2327db96d56Sopenharmony_ci self.assertWarnings() 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ci # global-exclude 2357db96d56Sopenharmony_ci file_list = FileList() 2367db96d56Sopenharmony_ci file_list.files = ['a.py', 'b.txt', l('d/c.py')] 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci file_list.process_template_line('global-exclude *.py') 2397db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['b.txt']) 2407db96d56Sopenharmony_ci self.assertNoWarnings() 2417db96d56Sopenharmony_ci 2427db96d56Sopenharmony_ci file_list.process_template_line('global-exclude *.rb') 2437db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['b.txt']) 2447db96d56Sopenharmony_ci self.assertWarnings() 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci # recursive-include 2477db96d56Sopenharmony_ci file_list = FileList() 2487db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'), 2497db96d56Sopenharmony_ci l('d/d/e.py')]) 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ci file_list.process_template_line('recursive-include d *.py') 2527db96d56Sopenharmony_ci self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) 2537db96d56Sopenharmony_ci self.assertNoWarnings() 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci file_list.process_template_line('recursive-include e *.py') 2567db96d56Sopenharmony_ci self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) 2577db96d56Sopenharmony_ci self.assertWarnings() 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci # recursive-exclude 2607db96d56Sopenharmony_ci file_list = FileList() 2617db96d56Sopenharmony_ci file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')] 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci file_list.process_template_line('recursive-exclude d *.py') 2647db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) 2657db96d56Sopenharmony_ci self.assertNoWarnings() 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci file_list.process_template_line('recursive-exclude e *.py') 2687db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) 2697db96d56Sopenharmony_ci self.assertWarnings() 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci # graft 2727db96d56Sopenharmony_ci file_list = FileList() 2737db96d56Sopenharmony_ci file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'), 2747db96d56Sopenharmony_ci l('f/f.py')]) 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci file_list.process_template_line('graft d') 2777db96d56Sopenharmony_ci self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) 2787db96d56Sopenharmony_ci self.assertNoWarnings() 2797db96d56Sopenharmony_ci 2807db96d56Sopenharmony_ci file_list.process_template_line('graft e') 2817db96d56Sopenharmony_ci self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) 2827db96d56Sopenharmony_ci self.assertWarnings() 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci # prune 2857db96d56Sopenharmony_ci file_list = FileList() 2867db96d56Sopenharmony_ci file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')] 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci file_list.process_template_line('prune d') 2897db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) 2907db96d56Sopenharmony_ci self.assertNoWarnings() 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci file_list.process_template_line('prune e') 2937db96d56Sopenharmony_ci self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) 2947db96d56Sopenharmony_ci self.assertWarnings() 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ciclass FindAllTestCase(unittest.TestCase): 2987db96d56Sopenharmony_ci @os_helper.skip_unless_symlink 2997db96d56Sopenharmony_ci def test_missing_symlink(self): 3007db96d56Sopenharmony_ci with os_helper.temp_cwd(): 3017db96d56Sopenharmony_ci os.symlink('foo', 'bar') 3027db96d56Sopenharmony_ci self.assertEqual(filelist.findall(), []) 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci def test_basic_discovery(self): 3057db96d56Sopenharmony_ci """ 3067db96d56Sopenharmony_ci When findall is called with no parameters or with 3077db96d56Sopenharmony_ci '.' as the parameter, the dot should be omitted from 3087db96d56Sopenharmony_ci the results. 3097db96d56Sopenharmony_ci """ 3107db96d56Sopenharmony_ci with os_helper.temp_cwd(): 3117db96d56Sopenharmony_ci os.mkdir('foo') 3127db96d56Sopenharmony_ci file1 = os.path.join('foo', 'file1.txt') 3137db96d56Sopenharmony_ci os_helper.create_empty_file(file1) 3147db96d56Sopenharmony_ci os.mkdir('bar') 3157db96d56Sopenharmony_ci file2 = os.path.join('bar', 'file2.txt') 3167db96d56Sopenharmony_ci os_helper.create_empty_file(file2) 3177db96d56Sopenharmony_ci expected = [file2, file1] 3187db96d56Sopenharmony_ci self.assertEqual(sorted(filelist.findall()), expected) 3197db96d56Sopenharmony_ci 3207db96d56Sopenharmony_ci def test_non_local_discovery(self): 3217db96d56Sopenharmony_ci """ 3227db96d56Sopenharmony_ci When findall is called with another path, the full 3237db96d56Sopenharmony_ci path name should be returned. 3247db96d56Sopenharmony_ci """ 3257db96d56Sopenharmony_ci with os_helper.temp_dir() as temp_dir: 3267db96d56Sopenharmony_ci file1 = os.path.join(temp_dir, 'file1.txt') 3277db96d56Sopenharmony_ci os_helper.create_empty_file(file1) 3287db96d56Sopenharmony_ci expected = [file1] 3297db96d56Sopenharmony_ci self.assertEqual(filelist.findall(temp_dir), expected) 3307db96d56Sopenharmony_ci 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_cidef test_suite(): 3337db96d56Sopenharmony_ci return unittest.TestSuite([ 3347db96d56Sopenharmony_ci unittest.TestLoader().loadTestsFromTestCase(FileListTestCase), 3357db96d56Sopenharmony_ci unittest.TestLoader().loadTestsFromTestCase(FindAllTestCase), 3367db96d56Sopenharmony_ci ]) 3377db96d56Sopenharmony_ci 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ciif __name__ == "__main__": 3407db96d56Sopenharmony_ci run_unittest(test_suite()) 341