filelist.py (7482B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\stdlib\distutils\filelist.py 2 __revision__ = '$Id: filelist.py 82110 2010-06-20 13:38:51Z kristjan.jonsson $' 3 import os, re 4 import fnmatch 5 from distutils.util import convert_path 6 from distutils.errors import DistutilsTemplateError, DistutilsInternalError 7 from distutils import log 8 9 class FileList: 10 11 def __init__(self, warn = None, debug_print = None): 12 self.allfiles = None 13 self.files = [] 14 15 def set_allfiles(self, allfiles): 16 self.allfiles = allfiles 17 18 def findall(self, dir = os.curdir): 19 self.allfiles = findall(dir) 20 21 def debug_print(self, msg): 22 from distutils.debug import DEBUG 23 if DEBUG: 24 print msg 25 26 def append(self, item): 27 self.files.append(item) 28 29 def extend(self, items): 30 self.files.extend(items) 31 32 def sort(self): 33 sortable_files = map(os.path.split, self.files) 34 sortable_files.sort() 35 self.files = [] 36 for sort_tuple in sortable_files: 37 self.files.append(os.path.join(*sort_tuple)) 38 39 def remove_duplicates(self): 40 for i in range(len(self.files) - 1, 0, -1): 41 if self.files[i] == self.files[i - 1]: 42 del self.files[i] 43 44 def _parse_template_line(self, line): 45 words = line.split() 46 action = words[0] 47 patterns = dir = dir_pattern = None 48 if action in ('include', 'exclude', 'global-include', 'global-exclude'): 49 if len(words) < 2: 50 raise DistutilsTemplateError, "'%s' expects <pattern1> <pattern2> ..." % action 51 patterns = map(convert_path, words[1:]) 52 elif action in ('recursive-include', 'recursive-exclude'): 53 if len(words) < 3: 54 raise DistutilsTemplateError, "'%s' expects <dir> <pattern1> <pattern2> ..." % action 55 dir = convert_path(words[1]) 56 patterns = map(convert_path, words[2:]) 57 elif action in ('graft', 'prune'): 58 if len(words) != 2: 59 raise DistutilsTemplateError, "'%s' expects a single <dir_pattern>" % action 60 dir_pattern = convert_path(words[1]) 61 else: 62 raise DistutilsTemplateError, "unknown action '%s'" % action 63 return (action, 64 patterns, 65 dir, 66 dir_pattern) 67 68 def process_template_line(self, line): 69 action, patterns, dir, dir_pattern = self._parse_template_line(line) 70 if action == 'include': 71 self.debug_print('include ' + ' '.join(patterns)) 72 for pattern in patterns: 73 if not self.include_pattern(pattern, anchor=1): 74 log.warn("warning: no files found matching '%s'", pattern) 75 76 elif action == 'exclude': 77 self.debug_print('exclude ' + ' '.join(patterns)) 78 for pattern in patterns: 79 if not self.exclude_pattern(pattern, anchor=1): 80 log.warn("warning: no previously-included files found matching '%s'", pattern) 81 82 elif action == 'global-include': 83 self.debug_print('global-include ' + ' '.join(patterns)) 84 for pattern in patterns: 85 if not self.include_pattern(pattern, anchor=0): 86 log.warn("warning: no files found matching '%s' " + 'anywhere in distribution', pattern) 87 88 elif action == 'global-exclude': 89 self.debug_print('global-exclude ' + ' '.join(patterns)) 90 for pattern in patterns: 91 if not self.exclude_pattern(pattern, anchor=0): 92 log.warn("warning: no previously-included files matching '%s' found anywhere in distribution", pattern) 93 94 elif action == 'recursive-include': 95 self.debug_print('recursive-include %s %s' % (dir, ' '.join(patterns))) 96 for pattern in patterns: 97 if not self.include_pattern(pattern, prefix=dir): 98 log.warn("warning: no files found matching '%s' " + "under directory '%s'", pattern, dir) 99 100 elif action == 'recursive-exclude': 101 self.debug_print('recursive-exclude %s %s' % (dir, ' '.join(patterns))) 102 for pattern in patterns: 103 if not self.exclude_pattern(pattern, prefix=dir): 104 log.warn("warning: no previously-included files matching '%s' found under directory '%s'", pattern, dir) 105 106 elif action == 'graft': 107 self.debug_print('graft ' + dir_pattern) 108 if not self.include_pattern(None, prefix=dir_pattern): 109 log.warn("warning: no directories found matching '%s'", dir_pattern) 110 elif action == 'prune': 111 self.debug_print('prune ' + dir_pattern) 112 if not self.exclude_pattern(None, prefix=dir_pattern): 113 log.warn('no previously-included directories found ' + "matching '%s'", dir_pattern) 114 else: 115 raise DistutilsInternalError, "this cannot happen: invalid action '%s'" % action 116 117 def include_pattern(self, pattern, anchor = 1, prefix = None, is_regex = 0): 118 files_found = 0 119 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) 120 self.debug_print("include_pattern: applying regex r'%s'" % pattern_re.pattern) 121 if self.allfiles is None: 122 self.findall() 123 for name in self.allfiles: 124 if pattern_re.search(name): 125 self.debug_print(' adding ' + name) 126 self.files.append(name) 127 files_found = 1 128 129 return files_found 130 131 def exclude_pattern(self, pattern, anchor = 1, prefix = None, is_regex = 0): 132 files_found = 0 133 pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) 134 self.debug_print("exclude_pattern: applying regex r'%s'" % pattern_re.pattern) 135 for i in range(len(self.files) - 1, -1, -1): 136 if pattern_re.search(self.files[i]): 137 self.debug_print(' removing ' + self.files[i]) 138 del self.files[i] 139 files_found = 1 140 141 return files_found 142 143 144 def findall(dir = os.curdir): 145 from stat import ST_MODE, S_ISREG, S_ISDIR, S_ISLNK 146 list = [] 147 stack = [dir] 148 pop = stack.pop 149 push = stack.append 150 while stack: 151 dir = pop() 152 names = os.listdir(dir) 153 for name in names: 154 if dir != os.curdir: 155 fullname = os.path.join(dir, name) 156 else: 157 fullname = name 158 stat = os.stat(fullname) 159 mode = stat[ST_MODE] 160 if S_ISREG(mode): 161 list.append(fullname) 162 elif S_ISDIR(mode) and not S_ISLNK(mode): 163 push(fullname) 164 165 return list 166 167 168 def glob_to_re(pattern): 169 pattern_re = fnmatch.translate(pattern) 170 pattern_re = re.sub('((?<!\\\\)(\\\\\\\\)*)\\.', '\\1[^/]', pattern_re) 171 return pattern_re 172 173 174 def translate_pattern(pattern, anchor = 1, prefix = None, is_regex = 0): 175 if is_regex: 176 if isinstance(pattern, str): 177 return re.compile(pattern) 178 else: 179 return pattern 180 if pattern: 181 pattern_re = glob_to_re(pattern) 182 else: 183 pattern_re = '' 184 if prefix is not None: 185 empty_pattern = glob_to_re('') 186 prefix_re = glob_to_re(prefix)[:-len(empty_pattern)] 187 pattern_re = '^' + os.path.join(prefix_re, '.*' + pattern_re) 188 elif anchor: 189 pattern_re = '^' + pattern_re 190 return re.compile(pattern_re)