mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 22:16:23 +00:00
Project.validate_relative_path: Make handling of ignored files explicit #672
This commit is contained in:
1 parent
5f114d9e05
commit
39a11657a9
2 files changed
+14
-10
No files matched your search
@@ -170,18 +170,22 @@ class Project:
|
||||
abs_path = Path(self.project_root) / relative_path
|
||||
return abs_path.exists()
|
||||
|
||||
def validate_relative_path(self, relative_path: str) -> None:
|
||||
def validate_relative_path(self, relative_path: str, require_not_ignored: bool = False) -> None:
|
||||
"""
|
||||
Validates that the given relative path to an existing file/dir is safe to read or edit,
|
||||
meaning it's inside the project directory and is not ignored by git.
|
||||
meaning it's inside the project directory.
|
||||
|
||||
Passing a path to a non-existing file will lead to a `FileNotFoundError`.
|
||||
|
||||
:param relative_path: the path to validate, relative to the project root
|
||||
:param require_not_ignored: if True, the path must not be ignored according to the project's ignore settings
|
||||
"""
|
||||
if not self.is_path_in_project(relative_path):
|
||||
raise ValueError(f"{relative_path=} points to path outside of the repository root; cannot access for safety reasons")
|
||||
|
||||
if self.is_ignored_path(relative_path):
|
||||
raise ValueError(f"Path {relative_path} is ignored; cannot access for safety reasons")
|
||||
if require_not_ignored:
|
||||
if self.is_ignored_path(relative_path):
|
||||
raise ValueError(f"Path {relative_path} is ignored; cannot access for safety reasons")
|
||||
|
||||
def gather_source_files(self, relative_path: str = "") -> list[str]:
|
||||
"""Retrieves relative paths of all source files, optionally limited to the given path
|
||||
|
||||
@@ -36,7 +36,7 @@ class ReadFileTool(Tool):
|
||||
required for the task.
|
||||
:return: the full text of the file at the given relative path
|
||||
"""
|
||||
self.project.validate_relative_path(relative_path)
|
||||
self.project.validate_relative_path(relative_path, require_not_ignored=True)
|
||||
|
||||
result = self.project.read_file(relative_path)
|
||||
result_lines = result.splitlines()
|
||||
@@ -67,7 +67,7 @@ class CreateTextFileTool(Tool, ToolMarkerCanEdit):
|
||||
will_overwrite_existing = abs_path.exists()
|
||||
|
||||
if will_overwrite_existing:
|
||||
self.project.validate_relative_path(relative_path)
|
||||
self.project.validate_relative_path(relative_path, require_not_ignored=True)
|
||||
else:
|
||||
assert abs_path.is_relative_to(
|
||||
self.get_project_root()
|
||||
@@ -88,7 +88,7 @@ class ListDirTool(Tool):
|
||||
|
||||
def apply(self, relative_path: str, recursive: bool, skip_ignored_files: bool = False, max_answer_chars: int = -1) -> str:
|
||||
"""
|
||||
Lists all non-gitignored files and directories in the given directory (optionally with recursion).
|
||||
Lists files and directories in the given directory (optionally with recursion).
|
||||
|
||||
:param relative_path: the relative path to the directory to list; pass "." to scan the project root
|
||||
:param recursive: whether to scan subdirectories recursively
|
||||
@@ -107,7 +107,7 @@ class ListDirTool(Tool):
|
||||
}
|
||||
return json.dumps(error_info)
|
||||
|
||||
self.project.validate_relative_path(relative_path)
|
||||
self.project.validate_relative_path(relative_path, require_not_ignored=skip_ignored_files)
|
||||
|
||||
dirs, files = scan_directory(
|
||||
os.path.join(self.get_project_root(), relative_path),
|
||||
@@ -134,7 +134,7 @@ class FindFileTool(Tool):
|
||||
:param relative_path: the relative path to the directory to search in; pass "." to scan the project root
|
||||
:return: a JSON object with the list of matching files
|
||||
"""
|
||||
self.project.validate_relative_path(relative_path)
|
||||
self.project.validate_relative_path(relative_path, require_not_ignored=True)
|
||||
|
||||
dir_to_scan = os.path.join(self.get_project_root(), relative_path)
|
||||
|
||||
@@ -192,7 +192,7 @@ class ReplaceRegexTool(Tool, ToolMarkerCanEdit):
|
||||
If this is set to False and the regex matches multiple occurrences, an error will be returned
|
||||
(and you may retry with a revised, more specific regex).
|
||||
"""
|
||||
self.project.validate_relative_path(relative_path)
|
||||
self.project.validate_relative_path(relative_path, require_not_ignored=True)
|
||||
with EditedFileContext(relative_path, self.agent) as context:
|
||||
original_content = context.get_original_content()
|
||||
updated_content, n = re.subn(regex, repl, original_content, flags=re.DOTALL | re.MULTILINE)
|
||||
|
||||
Reference in new issue
Block a user