Coverage for src\llm_code_lens\utils\gitignore.py: 25%
36 statements
« prev ^ index » next coverage.py v7.7.0, created at 2025-05-25 12:07 +0300
« prev ^ index » next coverage.py v7.7.0, created at 2025-05-25 12:07 +0300
1"""
2Gitignore Parser Utility Module
3Handles parsing and applying .gitignore patterns.
4"""
6from pathlib import Path
7import re
8from typing import List, Optional
10class GitignoreParser:
11 """
12 Parses .gitignore files and provides methods to check if a file should be ignored.
14 Attributes:
15 root_path (Path): The root directory where the .gitignore file is located.
16 patterns (List[str]): List of ignore patterns parsed from .gitignore.
17 """
19 def __init__(self, root_path: Path):
20 """Initialize with the root path containing .gitignore."""
21 self.root_path = root_path
22 self.patterns = []
24 def load_gitignore(self) -> None:
25 """
26 Load and parse the .gitignore file from the root directory.
27 This method populates the patterns list.
28 """
29 gitignore_path = self.root_path / '.gitignore'
31 if not gitignore_path.exists():
32 return
34 try:
35 with open(gitignore_path, 'r') as f:
36 for line in f:
37 # Skip empty lines and comments
38 line = line.strip()
39 if line and not line.startswith('#'):
40 self.patterns.append(line)
41 except Exception as e:
42 print(f"Warning: Error reading {gitignore_path}: {e}")
44 def get_ignore_patterns(self) -> List[str]:
45 """
46 Get the list of ignore patterns.
48 Returns:
49 List[str]: List of ignore patterns.
50 """
51 return self.patterns
53 def should_ignore(self, path: Path) -> bool:
54 """
55 Check if a file or directory matches any of the .gitignore patterns.
57 Args:
58 path (Path): The file or directory to check.
60 Returns:
61 bool: True if the path should be ignored, False otherwise.
62 """
63 path_str = str(path.relative_to(self.root_path))
65 for pattern in self.patterns:
66 # Convert gitignore pattern to regex
67 regex_pattern = self._convert_to_regex(pattern)
69 # Check if the path matches the pattern
70 if re.search(regex_pattern, path_str):
71 return True
73 return False
75 def _convert_to_regex(self, pattern: str) -> str:
76 """
77 Convert a gitignore pattern to a regular expression.
79 Args:
80 pattern (str): The gitignore pattern.
82 Returns:
83 str: The equivalent regular expression.
84 """
85 # Escape special regex characters in the pattern
86 escaped_pattern = re.escape(pattern)
88 # Handle wildcards and special patterns
89 escaped_pattern = (
90 escaped_pattern.replace(r'\*', '.*') # * -> .*
91 .replace(r'\?', '.') # ? -> .
92 .replace(r'\[', '[') # [ -> [
93 .replace(r'\]', ']') # ] -> ]
94 )
96 # Handle directory-specific patterns
97 if pattern.endswith('/'):
98 escaped_pattern += '/'
99 elif not pattern.startswith('/'):
100 # If the pattern doesn't start with a slash, it's relative to the current directory
101 escaped_pattern = f'.*{escaped_pattern}'
103 return escaped_pattern