1# 2# Permission is hereby granted, free of charge, to any person obtaining a copy 3# of this software and associated documentation files (the "Software"), to deal 4# in the Software without restriction, including without limitation the rights 5# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 6# copies of the Software, and to permit persons to whom the Software is 7# furnished to do so, subject to the following conditions: 8# 9# The above copyright notice and this permission notice shall be included in 10# all copies or substantial portions of the Software. 11# 12# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 18# THE SOFTWARE 19# 20# Copyright (c) 2014, Joyent, Inc. 21# 22 23''' 24Process our ignore/exception_list file format. 25 26The format is broadly similar, if not identical, to .gitignore and .hgignore 27files. 28''' 29 30import re 31import fnmatch 32 33RE_SYNTAX = re.compile(r'^syntax:\s*(.*)\s*$') 34 35# 36# It is important that this module not rely on Mercurial 37# 38 39def _read_ignore_file(ignorefile): 40 '''Read an ignore file and return an array of regular expressions 41 to match ignored paths.''' 42 43 syntax = 'regex' 44 ignore_list = [] 45 lc = 0 46 47 with open(ignorefile, 'r') as f: 48 for l in f: 49 lc += 1 50 # Remove comments and blank lines 51 l = l.split('#', 2)[0].strip() 52 if l == '': 53 continue 54 # Process "syntax:" lines 55 m = RE_SYNTAX.match(l) 56 if m: 57 syntax = m.group(1) 58 continue 59 # All other lines are considered patterns 60 if (syntax == 'glob'): 61 ignore_list.append(re.compile('.*' + fnmatch.translate(l))) 62 elif (syntax == 'regex'): 63 ignore_list.append(re.compile(l)) 64 else: 65 raise Exception('%s:%d: syntax "%s" is not supported' % 66 (ignorefile, lc, syntax)) 67 68 return ignore_list 69 70def ignore(root, ignorefiles): 71 # If we aren't provided any ignore files, we'll never ignore 72 # any paths: 73 if (len(ignorefiles) < 1): 74 return lambda x: False 75 76 ignore_list = [] 77 for ignorefile in ignorefiles: 78 ignore_list.extend(_read_ignore_file(ignorefile)) 79 80 # If the ignore files contained no patterns, we'll never ignore 81 # any paths: 82 if (len(ignore_list) < 1): 83 return lambda x: False 84 85 def _ignore_func(path): 86 for regex in ignore_list: 87 if (regex.match(path)): 88 return True 89 return False 90 91 return _ignore_func 92