mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 08:15:59 +00:00
Extended CLI with helper commands for debugging
This commit is contained in:
1 parent
5a1bfa0838
commit
3a61c999d3
2 files changed
+56
-8
No files matched your search
@@ -460,6 +460,52 @@ class ProjectCommands(AutoRegisteringGroup):
|
||||
ls.save_cache()
|
||||
print(f"Symbols saved to {ls.cache_path}")
|
||||
|
||||
@staticmethod
|
||||
@click.command("is_ignored_path", help="Check if a path is ignored by the project configuration.")
|
||||
@click.argument("path", type=click.Path(exists=False, file_okay=True, dir_okay=True))
|
||||
@click.argument("project", type=click.Path(exists=True, file_okay=False, dir_okay=True), default=os.getcwd())
|
||||
def is_ignored_path(path: str, project: str) -> None:
|
||||
"""
|
||||
Check if a given path is ignored by the project configuration.
|
||||
|
||||
:param path: The path to check.
|
||||
:param project: The path to the project directory, defaults to the current working directory.
|
||||
"""
|
||||
proj = Project.load(os.path.abspath(project))
|
||||
if os.path.isabs(path):
|
||||
path = os.path.relpath(path, start=proj.project_root)
|
||||
is_ignored = proj.is_ignored_path(path)
|
||||
click.echo(f"Path '{path}' IS {'ignored' if is_ignored else 'IS NOT ignored'} by the project configuration.")
|
||||
|
||||
@staticmethod
|
||||
@click.command("index-file", help="Index a single file by saving its symbols to the LSP cache.")
|
||||
@click.argument("file", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
||||
@click.argument("project", type=click.Path(exists=True, file_okay=False, dir_okay=True), default=os.getcwd())
|
||||
@click.option("--verbose", "-v", is_flag=True, help="Print detailed information about the indexed symbols.")
|
||||
def index_file(file: str, project: str, verbose: bool) -> None:
|
||||
"""
|
||||
Index a single file by saving its symbols to the LSP cache, useful for debugging.
|
||||
:param file: path to the file to index, must be inside the project directory.
|
||||
:param project: path to the project directory, defaults to the current working directory.
|
||||
:param verbose: if set, prints detailed information about the indexed symbols.
|
||||
"""
|
||||
proj = Project.load(os.path.abspath(project))
|
||||
if os.path.isabs(file):
|
||||
file = os.path.relpath(file, start=proj.project_root)
|
||||
if proj.is_ignored_path(file, ignore_non_source_files=True):
|
||||
click.echo(f"'{file}' is ignored or declared as non-code file by the project configuration, won't index.")
|
||||
exit(1)
|
||||
ls = proj.create_language_server()
|
||||
with ls.start_server():
|
||||
symbols, _ = ls.request_document_symbols(file, include_body=False)
|
||||
ls.request_document_symbols(file, include_body=True)
|
||||
if verbose:
|
||||
click.echo(f"Symbols in file '{file}':")
|
||||
for symbol in symbols:
|
||||
click.echo(f" - {symbol['name']} at line {symbol['selectionRange']['start']['line']} of kind {symbol['kind']}")
|
||||
ls.save_cache()
|
||||
click.echo(f"Successfully indexed file '{file}', {len(symbols)} symbols saved to {ls.cache_path}.")
|
||||
|
||||
|
||||
class ToolCommands(AutoRegisteringGroup):
|
||||
"""Group for 'tool' subcommands."""
|
||||
|
||||
+10
-8
@@ -87,7 +87,7 @@ class Project:
|
||||
def _is_ignored_dirname(self, dirname: str) -> bool:
|
||||
return dirname.startswith(".")
|
||||
|
||||
def _is_ignored_relative_path(self, relative_path: str, ignore_non_source_files: bool = True) -> bool:
|
||||
def _is_ignored_relative_path(self, relative_path: str | Path, ignore_non_source_files: bool = True) -> bool:
|
||||
"""
|
||||
Determine whether a path should be ignored based on file type and ignore patterns.
|
||||
|
||||
@@ -111,6 +111,10 @@ class Project:
|
||||
# Create normalized path for consistent handling
|
||||
rel_path = Path(relative_path)
|
||||
|
||||
# always ignore paths inside .git
|
||||
if len(rel_path.parts) > 0 and rel_path.parts[0] == ".git":
|
||||
return True
|
||||
|
||||
# Check each part of the path against always fulfilled ignore conditions
|
||||
dir_parts = rel_path.parts
|
||||
if is_file:
|
||||
@@ -121,13 +125,15 @@ class Project:
|
||||
if self._is_ignored_dirname(part):
|
||||
return True
|
||||
|
||||
return match_path(relative_path, self.get_ignore_spec(), root_path=self.project_root)
|
||||
return match_path(str(relative_path), self.get_ignore_spec(), root_path=self.project_root)
|
||||
|
||||
def is_ignored_path(self, path: str | Path) -> bool:
|
||||
def is_ignored_path(self, path: str | Path, ignore_non_source_files: bool = False) -> bool:
|
||||
"""
|
||||
Checks whether the given path is ignored
|
||||
|
||||
:param path: the path to check, can be absolute or relative
|
||||
:param ignore_non_source_files: whether to ignore files that are not source files
|
||||
(according to the file masks determined by the project's programming language)
|
||||
"""
|
||||
path = Path(path)
|
||||
if path.is_absolute():
|
||||
@@ -135,11 +141,7 @@ class Project:
|
||||
else:
|
||||
relative_path = path
|
||||
|
||||
# always ignore paths inside .git
|
||||
if len(relative_path.parts) > 0 and relative_path.parts[0] == ".git":
|
||||
return True
|
||||
|
||||
return match_path(str(relative_path), self.get_ignore_spec(), root_path=self.project_root)
|
||||
return self._is_ignored_relative_path(str(relative_path), ignore_non_source_files=ignore_non_source_files)
|
||||
|
||||
def is_path_in_project(self, path: str | Path) -> bool:
|
||||
"""
|
||||
|
||||
Reference in new issue
Block a user