Skip to content

Commit

Permalink
gitignore_parser: Collect logic matching many rules into match_rules()
Browse files Browse the repository at this point in the history
This replace the last half of parse_gitignore_lines() with a dedicated
function for applying a list of matching rules to a single path. Also,
take over the call from DirectoryTraversal._do_ignore() which had
duplicated this logic.
  • Loading branch information
jherland committed Nov 3, 2023
1 parent 3d3acbf commit 64be0b6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 25 deletions.
12 changes: 2 additions & 10 deletions fawltydeps/dir_traversal.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
TypeVar,
)

from fawltydeps.gitignore_parser import IgnoreRule
from fawltydeps.gitignore_parser import IgnoreRule, match_rules
from fawltydeps.utils import dirs_between

T = TypeVar("T")
Expand Down Expand Up @@ -149,15 +149,7 @@ def ignore(self, pattern: str, base_dir: Optional[Path] = None) -> None:

def _do_ignore(self, path: Path, is_dir: bool) -> bool:
"""Check if given path is ignored by any of our ignore rules."""
abs_path = path.resolve()
for rule in reversed(self.ignore_rules):
try:
if rule.match(abs_path, is_dir):
logger.debug(f" ignore rule {rule!r} matches {abs_path}")
return not rule.negated
except ValueError: # abs_path not relative to rule.base_path
pass
return False
return match_rules(self.ignore_rules, path.resolve(), is_dir)

def traverse(self) -> Iterator[TraversalStep[T]]:
"""Perform the traversal of the added directories.
Expand Down
33 changes: 18 additions & 15 deletions fawltydeps/gitignore_parser.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
"""A spec-compliant gitignore parser for Python."""

import functools
import logging
import os
import re
import sys
from pathlib import Path
from typing import TYPE_CHECKING, Callable, Dict, Iterable, NamedTuple, Optional, Tuple
from typing import (
TYPE_CHECKING,
Callable,
Dict,
Iterable,
List,
NamedTuple,
Optional,
Tuple,
)

from fawltydeps.types import Location

Expand Down Expand Up @@ -76,22 +86,15 @@ def parse_gitignore_lines(
# Blank lines and comments are ok when parsing multiple lines
logger.debug(str(exc))

if not any(r.negated for r in rules):
return functools.partial(match_rules, rules)

def handle_straightforward(file_path: Path, is_dir: bool) -> bool:
return any(r.match(file_path, is_dir) for r in rules)

return handle_straightforward

# We have negation rules. We can't use a simple "any" to evaluate them.
# Later rules override earlier rules.
def handle_negation(file_path: Path, is_dir: bool) -> bool:
for rule in reversed(rules):
if rule.match(file_path, is_dir):
return not rule.negated
return False

return handle_negation
def match_rules(rules: List["IgnoreRule"], path: Path, is_dir: bool) -> bool:
"""Match the given path against the given list of rules."""
for rule in reversed(rules):
if rule.match(path, is_dir):
return not rule.negated
return False


class IgnoreRule(NamedTuple):
Expand Down

0 comments on commit 64be0b6

Please sign in to comment.