diff --git a/src/serena/agent.py b/src/serena/agent.py index 522b6c2..aa78640 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -865,7 +865,7 @@ class SerenaAgent: if len(relative_path.parts) > 0 and relative_path.parts[0] == ".git": return True - return match_path(str(relative_path), self.ignore_spec) + return match_path(str(relative_path), self.ignore_spec, root_path=self.get_project_root()) def validate_relative_path(self, relative_path: str) -> None: """ diff --git a/src/serena/util/file_system.py b/src/serena/util/file_system.py index f16b46a..26a5943 100644 --- a/src/serena/util/file_system.py +++ b/src/serena/util/file_system.py @@ -92,14 +92,14 @@ class GitignoreSpec: """Initialize the PathSpec from patterns.""" self.pathspec = PathSpec.from_lines(pathspec.patterns.GitWildMatchPattern, self.patterns) - def matches(self, path: str) -> bool: + def matches(self, relative_path: str) -> bool: """ Check if the given path matches any pattern in this gitignore spec. - :param path: Path to check (should be relative to repo root) + :param relative_path: Path to check (should be relative to repo root) :return: True if path matches any pattern """ - return self.pathspec.match_file(path) + return match_path(relative_path, self.pathspec, root_path=os.path.dirname(self.file_path)) class GitignoreParser: @@ -276,7 +276,16 @@ class GitignoreParser: self._load_gitignore_files() -def match_path(relative_path: str, path_spec: PathSpec) -> bool: +def match_path(relative_path: str, path_spec: PathSpec, root_path: str = "") -> bool: + """ + Match a relative path against a given pathspec. Just pathspec.match_file() is not enough, + we need to do some massaging to fix issues with pathspec matching. + + :param relative_path: relative path to match against the pathspec + :param path_spec: the pathspec to match against + :param root_path: the root path from which the relative path is derived + :return: + """ normalized_path = str(relative_path).replace(os.path.sep, "/") # We can have patterns like /src/..., which would only match corresponding paths from the repo root @@ -289,6 +298,7 @@ def match_path(relative_path: str, path_spec: PathSpec) -> bool: # pathspec can't handle the matching of directories if they don't end with a slash! # see https://github.com/cpburnz/python-pathspec/issues/89 - if os.path.isdir(relative_path) and not normalized_path.endswith("/"): + abs_path = os.path.abspath(os.path.join(root_path, relative_path)) + if os.path.isdir(abs_path) and not normalized_path.endswith("/"): normalized_path = normalized_path + "/" return path_spec.match_file(normalized_path) diff --git a/src/solidlsp/ls.py b/src/solidlsp/ls.py index 77d35ba..4b8163c 100644 --- a/src/solidlsp/ls.py +++ b/src/solidlsp/ls.py @@ -318,7 +318,7 @@ class SolidLanguageServer(ABC): if self.is_ignored_dirname(part): return True - return match_path(relative_path, self.get_ignore_spec()) + return match_path(relative_path, self.get_ignore_spec(), root_path=self.repository_root_path) def _shutdown(self, timeout: float = 5.0): """