Commit c014b4de authored by Dom Sekotill's avatar Dom Sekotill
Browse files

Refactor the git loader

The git loader generates the rule graph from the bottom up so that no
rules short-cut to a decision. (Which was a bug introduced while
attempting to prevent exceptions caused by dangling rules; wrong way of
fixing it, past self!)
parent cd61c5df
Loading
Loading
Loading
Loading
+32 −27
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ class GitLoader(loaders.Loader):
		super(GitLoader, self).__init__(project_root, target_path)
		pattern = patterns.FileMatchPattern('.git')
		self.rules = rules.Rule(project_root, '', pattern, with_path=False)
		self.tails = [self.rules, None]
		self.__rules = [None, self.rules], [None]

		git_dir = environ['GIT_DIR']
		home = environ['HOME']
@@ -85,8 +85,7 @@ class GitLoader(loaders.Loader):


	def load_patterns(self, directory, filename):
		last_exclude_rule, last_include_rule = self.tails

		rule_list = []
		with open(path.join(self.project_root, directory, filename)) as f:
			for line in f:
				rule_opts = dict(with_path=True)
@@ -113,27 +112,33 @@ class GitLoader(loaders.Loader):
				rule = rules.Rule(self.project_root, directory, pattern,
						**rule_opts)

				if not self.rules:
					self.rules = rule
				rule_list.append(('invert' in rule_opts, rule))

				if 'invert' in rule_opts:
					if last_exclude_rule:
						last_exclude_rule.next_if_match = rule
					if last_include_rule:
						last_include_rule.next_if_fail = rule
					last_include_rule = rule
		excl_rules = [rules.IncludeRule()]
		incl_rules = [rules.ExcludeRule()]
		for inverted, rule in reversed(rule_list):
			if inverted:
				rule.next_if_match = excl_rules[-1]
				rule.next_if_fail = incl_rules[-1]
				incl_rules.append(rule)
			else:
					if last_exclude_rule:
						last_exclude_rule.next_if_fail = rule
					if last_include_rule:
						last_include_rule.next_if_match = rule
					last_exclude_rule = rule

		if last_exclude_rule:
			last_exclude_rule.next_if_match = rules.ExcludeRule()
			last_exclude_rule.next_if_fail = rules.IncludeRule()
		if last_include_rule:
			last_include_rule.next_if_match = rules.IncludeRule()
			last_include_rule.next_if_fail = rules.ExcludeRule()

		self.tails[:] = last_exclude_rule, last_include_rule
				rule.next_if_match = incl_rules[-1]
				rule.next_if_fail = excl_rules[-1]
				excl_rules.append(rule)


		all_excl_rules, all_incl_rules = self.__rules
		try:
			all_excl_rules[1].next_if_match = incl_rules[-1]
			all_excl_rules[1].next_if_fail = excl_rules[-1]
		except IndexError:
			pass
		try:
			all_incl_rules[1].next_if_match = excl_rules[-1]
			all_incl_rules[1].next_if_fail = incl_rules[-1]
		except IndexError:
			pass

		excl_rules.extend(all_excl_rules[1:])
		incl_rules.extend(all_incl_rules[1:])
		self.__rules = excl_rules, incl_rules