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