Skip to content

Commit 47b5019

Browse files
committed
Fix in path listing (were not relative). Minor other changes
1 parent ec50e1a commit 47b5019

4 files changed

Lines changed: 35 additions & 28 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,8 @@ on how to use Serena's tools.
192192
We also recommend that you index your code once before starting (especially for larger projects), it will accelerate the symbolic operations.
193193

194194
```shell
195-
uvx --from git+https://github.com/oraios/serena index-project $(pwd)
195+
# from the project directory, or pass the path to the project as argument
196+
uvx --from git+https://github.com/oraios/serena index-project
196197
```
197198

198199

src/multilspy/language_server.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,7 +1210,6 @@ def retrieve_symbol_body(self, symbol: multilspy_types.UnifiedSymbolInformation
12101210
symbol_body = symbol_body[symbol_start_column:]
12111211
return symbol_body
12121212

1213-
12141213
async def request_parsed_files(self) -> list[str]:
12151214
"""Retrieves relative paths of all files analyzed by the Language Server."""
12161215
if not self.server_started:
@@ -1221,13 +1220,9 @@ async def request_parsed_files(self) -> list[str]:
12211220
raise MultilspyException("Language Server not started")
12221221
rel_file_paths = []
12231222
for root, dirs, files in os.walk(self.repository_root_path):
1224-
# Don't go into directories that are ignored by modifying dirs inplace
1225-
# Explanation for the + "/" part:
1226-
# pathspec can't handle the matching of directories if they don't end with a slash!
1227-
# see https://github.com/cpburnz/python-pathspec/issues/89
1228-
dirs[:] = [d for d in dirs if not self.is_ignored_path(os.path.join(root, d) + "/")]
1223+
dirs[:] = [d for d in dirs if not self.is_ignored_path(os.path.join(root, d))]
12291224
for file in files:
1230-
rel_file_path = os.path.join(root, file)
1225+
rel_file_path = os.path.relpath(os.path.join(root, file), start=self.repository_root_path)
12311226
if not self.is_ignored_path(rel_file_path):
12321227
rel_file_paths.append(rel_file_path)
12331228
return rel_file_paths
@@ -1596,7 +1591,10 @@ async def request_defining_symbol(
15961591
return defining_symbol
15971592

15981593
@property
1599-
def _cache_path(self) -> Path:
1594+
def cache_path(self) -> Path:
1595+
"""
1596+
The path to the cache file for the document symbols.
1597+
"""
16001598
return Path(self.repository_root_path) / ".serena" / "cache" / self.language_id / "document_symbols_cache_v20-05-25.pkl"
16011599

16021600
async def index_repository(self, progress_bar: bool = True, save_after_n_files: int = 10) -> None:
@@ -1623,33 +1621,33 @@ def save_cache(self):
16231621
self.logger.log("No changes to document symbols cache, skipping save", logging.DEBUG)
16241622
return
16251623

1626-
self.logger.log(f"Saving updated document symbols cache to {self._cache_path}", logging.INFO)
1627-
self._cache_path.parent.mkdir(parents=True, exist_ok=True)
1624+
self.logger.log(f"Saving updated document symbols cache to {self.cache_path}", logging.INFO)
1625+
self.cache_path.parent.mkdir(parents=True, exist_ok=True)
16281626
try:
1629-
with open(self._cache_path, "wb") as f:
1627+
with open(self.cache_path, "wb") as f:
16301628
pickle.dump(self._document_symbols_cache, f)
16311629
self._cache_has_changed = False
16321630
except Exception as e:
16331631
self.logger.log(
1634-
f"Failed to save document symbols cache to {self._cache_path}: {e}. "
1632+
f"Failed to save document symbols cache to {self.cache_path}: {e}. "
16351633
"Note: this may have resulted in a corrupted cache file.",
16361634
logging.ERROR,
16371635
)
16381636

16391637
def load_cache(self):
1640-
if not self._cache_path.exists():
1638+
if not self.cache_path.exists():
16411639
return
16421640

16431641
with self._cache_lock:
1644-
self.logger.log(f"Loading document symbols cache from {self._cache_path}", logging.INFO)
1642+
self.logger.log(f"Loading document symbols cache from {self.cache_path}", logging.INFO)
16451643
try:
1646-
with open(self._cache_path, "rb") as f:
1644+
with open(self.cache_path, "rb") as f:
16471645
self._document_symbols_cache = pickle.load(f)
16481646
self.logger.log(f"Loaded {len(self._document_symbols_cache)} document symbols from cache.", logging.INFO)
16491647
except Exception as e:
16501648
# cache often becomes corrupt, so just skip loading it
16511649
self.logger.log(
1652-
f"Failed to load document symbols cache from {self._cache_path}: {e}. Possible cause: the cache file is corrupted. "
1650+
f"Failed to load document symbols cache from {self.cache_path}: {e}. Possible cause: the cache file is corrupted. "
16531651
"Check for any errors related to saving the cache in the logs.",
16541652
logging.ERROR,
16551653
)
@@ -1704,6 +1702,13 @@ def __init__(self, language_server: LanguageServer, timeout: Optional[float] = N
17041702
self._shutdown_lock = threading.Lock()
17051703
self._is_shutting_down = False
17061704

1705+
@property
1706+
def cache_path(self) -> Path:
1707+
"""
1708+
The path to the cache file for the document symbols.
1709+
"""
1710+
return self.language_server.cache_path
1711+
17071712
@classmethod
17081713
def create(
17091714
cls, config: MultilspyConfig, logger: MultilspyLogger, repository_root_path: str,

src/serena/agent.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -667,20 +667,21 @@ def create_ls_for_project(
667667

668668

669669
@click.command()
670-
@click.argument("project", type=click.Path(exists=True))
670+
@click.argument("project", type=click.Path(exists=True), required=False, default=os.getcwd())
671671
@click.option("--log-level", type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]), default="WARNING")
672672
def index_project(project: str, log_level: str = "INFO") -> None:
673673
"""
674674
Index a project by saving the symbols of files to Serena's language server cache.
675675
676-
:param project: the project to index
676+
:param project: the project to index. By default, the current working directory is used.
677677
"""
678678
log_level_int = logging.getLevelNamesMapping()[log_level.upper()]
679679
project = os.path.abspath(project)
680-
log.info(f"Indexing project {project}")
680+
print(f"Indexing symbols in project {project}")
681681
ls = create_ls_for_project(project, log_level=log_level_int)
682682
with ls.start_server():
683683
ls.index_repository()
684+
print(f"Symbols saved to {ls.cache_path}")
684685

685686

686687
class SerenaAgent:
@@ -2138,21 +2139,19 @@ def apply(
21382139
)
21392140
else:
21402141
# we walk through all files in the project starting from the root
2141-
files_to_search = []
2142-
for root, dirs, files in os.walk(self.get_project_root()):
2143-
# Don't go into directories that are ignored by modifying dirs inplace
2144-
# Explanation for the + "/" part:
2145-
# pathspec can't handle the matching of directories if they don't end with a slash!
2146-
# see https://github.com/cpburnz/python-pathspec/issues/89
2142+
project_root = self.get_project_root()
2143+
rel_paths_to_search = []
2144+
for root, dirs, files in os.walk(project_root):
21472145
dirs[:] = [d for d in dirs if not self.agent.path_is_gitignored(os.path.join(root, d))]
21482146
for file in files:
21492147
file_path = os.path.join(root, file)
21502148
if not self.agent.path_is_gitignored(file_path):
2151-
files_to_search.append(file_path)
2149+
relative_path = os.path.relpath(file_path, project_root)
2150+
rel_paths_to_search.append(relative_path)
21522151
# TODO (maybe): not super efficient to walk through the files again and filter if glob patterns are provided
21532152
# but it probably never matters and this version required no further refactoring
21542153
matches = search_files(
2155-
files_to_search,
2154+
rel_paths_to_search,
21562155
pattern,
21572156
paths_include_glob=paths_include_glob,
21582157
paths_exclude_glob=paths_exclude_glob,

src/serena/text_utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ def glob_match(pattern: str, path: str) -> bool:
271271
:param path: File path to match against
272272
:return: True if path matches pattern
273273
"""
274+
pattern = pattern.replace("\\", "/") # Normalize backslashes to forward slashes
275+
274276
# Handle ** patterns that should match zero or more directories
275277
if "**" in pattern:
276278
# Method 1: Standard fnmatch (matches one or more directories)

0 commit comments

Comments
 (0)