|
46 | 46 | from codegen.sdk.core.dataclasses.usage import Usage |
47 | 47 | from codegen.sdk.core.expressions import Expression |
48 | 48 | from codegen.sdk.core.external_module import ExternalModule |
49 | | - from codegen.sdk.core.file import SourceFile |
| 49 | + from codegen.sdk.core.file import File, SourceFile |
50 | 50 | from codegen.sdk.core.interfaces.importable import Importable |
51 | 51 | from codegen.sdk.core.node_id_factory import NodeId |
52 | 52 | from codegen.sdk.core.parser import Parser |
@@ -345,33 +345,15 @@ def prune_graph(self) -> None: |
345 | 345 | self.remove_node(module.node_id) |
346 | 346 | self._ext_module_idx.pop(module._idx_key, None) |
347 | 347 |
|
348 | | - def build_directory_tree(self, files: list[SourceFile]) -> None: |
| 348 | + def build_directory_tree(self) -> None: |
349 | 349 | """Builds the directory tree for the codebase""" |
350 | 350 | # Reset and rebuild the directory tree |
351 | 351 | self.directories = dict() |
352 | | - created_dirs = set() |
353 | | - for file in files: |
354 | | - directory = self.get_directory(file.path.parent, create_on_missing=True) |
355 | | - directory.add_file(file) |
356 | | - file._set_directory(directory) |
357 | | - created_dirs.add(file.path.parent) |
358 | | - |
359 | | - def _dir_has_file(filepath): |
360 | | - gen = os.scandir(filepath) |
361 | | - while entry := next(gen, None): |
362 | | - if entry.is_file(): |
363 | | - return True |
364 | | - return False |
365 | | - |
366 | | - for ctx in self.projects: |
367 | | - for rel_filepath in ctx.repo_operator.get_filepaths_for_repo(GLOBAL_FILE_IGNORE_LIST): |
368 | | - abs_filepath = self.to_absolute(rel_filepath) |
369 | | - if not abs_filepath.is_dir(): |
370 | | - abs_filepath = abs_filepath.parent |
371 | | - |
372 | | - if abs_filepath not in created_dirs and self.is_subdir(abs_filepath) and _dir_has_file(abs_filepath): |
373 | | - directory = self.get_directory(abs_filepath, create_on_missing=True) |
374 | | - created_dirs.add(abs_filepath) |
| 352 | + |
| 353 | + for file_path, _ in self.projects[0].repo_operator.iter_files(subdirs=self.projects[0].subdirectories, ignore_list=GLOBAL_FILE_IGNORE_LIST): |
| 354 | + file_path = Path(file_path) |
| 355 | + directory = self.get_directory(file_path.parent, create_on_missing=True) |
| 356 | + directory._add_file(file_path.name) |
375 | 357 |
|
376 | 358 | def get_directory(self, directory_path: PathLike, create_on_missing: bool = False, ignore_case: bool = False) -> Directory | None: |
377 | 359 | """Returns the directory object for the given path, or None if the directory does not exist. |
@@ -399,16 +381,16 @@ def get_directory(self, directory_path: PathLike, create_on_missing: bool = Fals |
399 | 381 |
|
400 | 382 | # Base Case |
401 | 383 | if str(absolute_path) == str(self.repo_path) or str(absolute_path) == str(parent_path): |
402 | | - root_directory = Directory(path=absolute_path, dirpath="", parent=None) |
| 384 | + root_directory = Directory(ctx=self, path=absolute_path, dirpath="") |
403 | 385 | self.directories[absolute_path] = root_directory |
404 | 386 | return root_directory |
405 | 387 |
|
406 | 388 | # Recursively create the parent directory |
407 | 389 | parent = self.get_directory(parent_path, create_on_missing=True) |
408 | 390 | # Create the directory |
409 | | - directory = Directory(path=absolute_path, dirpath=str(self.to_relative(absolute_path)), parent=parent) |
| 391 | + directory = Directory(ctx=self, path=absolute_path, dirpath=str(self.to_relative(absolute_path))) |
410 | 392 | # Add the directory to the parent |
411 | | - parent.add_subdirectory(directory) |
| 393 | + parent._add_subdirectory(directory.name) |
412 | 394 | # Add the directory to the tree |
413 | 395 | self.directories[absolute_path] = directory |
414 | 396 | return directory |
@@ -514,7 +496,7 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr |
514 | 496 | # Step 6: Build directory tree |
515 | 497 | logger.info("> Building directory tree") |
516 | 498 | files = [f for f in sort_editables(self.get_nodes(NodeType.FILE), alphabetical=True, dedupe=False)] |
517 | | - self.build_directory_tree(files) |
| 499 | + self.build_directory_tree() |
518 | 500 |
|
519 | 501 | # Step 7: Build configs |
520 | 502 | if self.config_parser is not None: |
@@ -613,13 +595,20 @@ def get_file(self, file_path: os.PathLike, ignore_case: bool = False) -> SourceF |
613 | 595 | if node_id is not None: |
614 | 596 | return self.get_node(node_id) |
615 | 597 | if ignore_case: |
616 | | - parent = self.to_absolute(file_path).parent |
617 | | - if parent == Path(self.repo_path): |
618 | | - for file in self.to_absolute(self.repo_path).iterdir(): |
619 | | - if str(file_path).lower() == str(self.to_absolute(file)).lower(): |
620 | | - return self.get_file(file, ignore_case=False) |
621 | | - if directory := self.get_directory(parent, ignore_case=ignore_case): |
622 | | - return directory.get_file(os.path.basename(file_path), ignore_case=ignore_case) |
| 598 | + # Using `get_directory` so that the case insensitive lookup works |
| 599 | + parent = self.get_directory(self.to_absolute(file_path).parent, ignore_case=ignore_case).path |
| 600 | + for file in parent.iterdir(): |
| 601 | + if str(file_path).lower() == str(self.to_relative(file)).lower(): |
| 602 | + return self.get_file(file, ignore_case=False) |
| 603 | + |
| 604 | + def _get_raw_file_from_path(self, path: Path) -> File | None: |
| 605 | + from codegen.sdk.core.file import File |
| 606 | + |
| 607 | + try: |
| 608 | + return File.from_content(path, self.io.read_text(path), self, sync=False) |
| 609 | + except UnicodeDecodeError: |
| 610 | + # Handle when file is a binary file |
| 611 | + return File.from_content(path, self.io.read_bytes(path), self, sync=False, binary=True) |
623 | 612 |
|
624 | 613 | def get_external_module(self, module: str, import_name: str) -> ExternalModule | None: |
625 | 614 | node_id = self._ext_module_idx.get(module + "::" + import_name, None) |
|
0 commit comments