Adding src_exclude_filter to exclude files - makes common operations like 'all but X' easier
This commit is contained in:
parent
5b84fa35e6
commit
a2d7c0def1
|
@ -398,9 +398,12 @@ class RuleContext(object):
|
|||
OSError: A source path was not found or could not be accessed.
|
||||
RuntimeError: Internal runtime error (rule executed out of order/etc)
|
||||
"""
|
||||
src_filter_list = None
|
||||
include_filter_list = []
|
||||
if apply_src_filter and self.rule.src_filter:
|
||||
src_filter_list = self.rule.src_filter.split('|')
|
||||
include_filter_list = self.rule.src_filter.split('|')
|
||||
exclude_filter_list = []
|
||||
if apply_src_filter and self.rule.src_exclude_filter:
|
||||
exclude_filter_list = self.rule.src_exclude_filter.split('|')
|
||||
|
||||
base_path = os.path.dirname(self.rule.parent_module.path)
|
||||
input_paths = []
|
||||
|
@ -420,16 +423,20 @@ class RuleContext(object):
|
|||
else:
|
||||
# File or folder path
|
||||
src_path = os.path.join(base_path, src)
|
||||
mode = os.stat(src_path).st_mode
|
||||
if stat.S_ISDIR(mode):
|
||||
if not os.path.exists(src_path):
|
||||
raise OSError('Source path "%s" not found' % (src_path))
|
||||
elif os.path.isdir(src_path):
|
||||
src_items = os.listdir(src_path)
|
||||
else:
|
||||
src_items = [src_path]
|
||||
|
||||
# Apply the src_filter, if any
|
||||
if src_filter_list:
|
||||
if len(include_filter_list) or len(exclude_filter_list):
|
||||
for file_path in src_items:
|
||||
if any(fnmatch.fnmatch(file_path, f) for f in src_filter_list):
|
||||
if any(fnmatch.fnmatch(file_path, f) for f in exclude_filter_list):
|
||||
continue
|
||||
if (not len(include_filter_list) or
|
||||
any(fnmatch.fnmatch(file_path, f) for f in include_filter_list)):
|
||||
input_paths.append(file_path)
|
||||
else:
|
||||
input_paths.extend(src_items)
|
||||
|
|
|
@ -331,6 +331,22 @@ class RuleContextTest(FixtureTestCase):
|
|||
set([os.path.basename(f) for f in rule_outputs]),
|
||||
set(['a.txt', 'b.txt', 'c.txt', 'd.txt', 'e.txt']))
|
||||
|
||||
rule = project.resolve_rule(':exclude_txt_filter')
|
||||
d = build_ctx._execute_rule(rule)
|
||||
self.assertTrue(d.is_done())
|
||||
rule_outputs = build_ctx.get_rule_outputs(rule)
|
||||
self.assertEqual(
|
||||
set([os.path.basename(f) for f in rule_outputs]),
|
||||
set(['dir_2', 'a.txt-a', 'b.txt-b', 'c.txt-c', 'g.not-txt', 'BUILD']))
|
||||
|
||||
rule = project.resolve_rule(':include_exclude_filter')
|
||||
d = build_ctx._execute_rule(rule)
|
||||
self.assertTrue(d.is_done())
|
||||
rule_outputs = build_ctx.get_rule_outputs(rule)
|
||||
self.assertEqual(
|
||||
set([os.path.basename(f) for f in rule_outputs]),
|
||||
set(['a.txt-a', 'b.txt-b']))
|
||||
|
||||
rule = project.resolve_rule(':multi_exts')
|
||||
build_ctx._execute_rule(rule)
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class Rule(object):
|
|||
_whitespace_re = re.compile('\s', re.M)
|
||||
|
||||
def __init__(self, name, srcs=None, deps=None, src_filter=None,
|
||||
rule_name=None, *args, **kwargs):
|
||||
src_exclude_filter=None, rule_name=None, *args, **kwargs):
|
||||
"""Initializes a rule.
|
||||
|
||||
Args:
|
||||
|
@ -50,6 +50,9 @@ class Rule(object):
|
|||
deps: A list of depdendency strings or a single dependency string.
|
||||
src_filter: An inclusionary file name filter for all non-rule paths. If
|
||||
defined only srcs that match this filter will be included.
|
||||
src_exclude_filter: An exclusionary file name filter for all non-rule
|
||||
paths. If defined only srcs that do not match this filter will be
|
||||
included.
|
||||
rule_name: Name of the rule in BUILD files, making it easier to debug.
|
||||
|
||||
Raises:
|
||||
|
@ -97,6 +100,9 @@ class Rule(object):
|
|||
self.src_filter = None
|
||||
if src_filter and len(src_filter):
|
||||
self.src_filter = src_filter
|
||||
self.src_exclude_filter = None
|
||||
if src_exclude_filter and len(src_exclude_filter):
|
||||
self.src_exclude_filter = src_exclude_filter
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.rule_name, self.path)
|
||||
|
|
|
@ -188,6 +188,14 @@ class RuleTest(unittest2.TestCase):
|
|||
rule = Rule('a', src_filter='*.js')
|
||||
self.assertEqual(rule.src_filter, '*.js')
|
||||
|
||||
def testRuleExclusionFilter(self):
|
||||
rule = Rule('a')
|
||||
self.assertIsNone(rule.src_exclude_filter)
|
||||
rule = Rule('a', src_filter='')
|
||||
self.assertIsNone(rule.src_exclude_filter)
|
||||
rule = Rule('a', src_exclude_filter='*.js')
|
||||
self.assertEqual(rule.src_exclude_filter, '*.js')
|
||||
|
||||
|
||||
class RuleNamespaceTest(FixtureTestCase):
|
||||
"""Behavioral tests of the Rule type."""
|
||||
|
|
|
@ -26,6 +26,13 @@ file_set('local_txt_filter',
|
|||
file_set('recursive_txt_filter',
|
||||
srcs=glob('**/*'),
|
||||
src_filter='*.txt')
|
||||
file_set('exclude_txt_filter',
|
||||
srcs=glob('*'),
|
||||
src_exclude_filter='*.txt')
|
||||
file_set('include_exclude_filter',
|
||||
srcs=glob('*'),
|
||||
src_filter='*.txt-a|*.txt-b',
|
||||
src_exclude_filter='*.txt')
|
||||
|
||||
file_set('file_input',
|
||||
srcs='a.txt')
|
||||
|
|
Loading…
Reference in New Issue