2
2
3
3
import os
4
4
from collections import Counter , defaultdict
5
- from concurrent .futures import ThreadPoolExecutor
6
5
from contextlib import contextmanager
7
6
from enum import IntEnum , auto , unique
8
7
from functools import lru_cache
16
15
from codegen .sdk .codebase .config_parser import ConfigParser , get_config_parser_for_language
17
16
from codegen .sdk .codebase .diff_lite import ChangeType , DiffLite
18
17
from codegen .sdk .codebase .flagging .flags import Flags
18
+ from codegen .sdk .codebase .io .file_io import FileIO
19
19
from codegen .sdk .codebase .transaction_manager import TransactionManager
20
20
from codegen .sdk .codebase .validation import get_edges , post_reset_validation
21
21
from codegen .sdk .core .autocommit import AutoCommit , commiter
22
22
from codegen .sdk .core .directory import Directory
23
23
from codegen .sdk .core .external .dependency_manager import DependencyManager , get_dependency_manager
24
24
from codegen .sdk .core .external .language_engine import LanguageEngine , get_language_engine
25
25
from codegen .sdk .enums import Edge , EdgeType , NodeType , ProgrammingLanguage
26
- from codegen .sdk .extensions .io import write_changes
27
26
from codegen .sdk .extensions .sort import sort_editables
28
27
from codegen .sdk .extensions .utils import uncache_all
29
28
from codegen .sdk .typescript .external .ts_declassify .ts_declassify import TSDeclassify
37
36
from git import Commit as GitCommit
38
37
39
38
from codegen .git .repo_operator .repo_operator import RepoOperator
39
+ from codegen .sdk .codebase .io .io import IO
40
40
from codegen .sdk .codebase .node_classes .node_classes import NodeClasses
41
41
from codegen .sdk .core .dataclasses .usage import Usage
42
42
from codegen .sdk .core .expressions import Expression
@@ -92,7 +92,6 @@ class CodebaseContext:
92
92
pending_syncs : list [DiffLite ] # Diffs that have been applied to disk, but not the graph (to be used for sync graph)
93
93
all_syncs : list [DiffLite ] # All diffs that have been applied to the graph (to be used for graph reset)
94
94
_autocommit : AutoCommit
95
- pending_files : set [SourceFile ]
96
95
generation : int
97
96
parser : Parser [Expression ]
98
97
synced_commit : GitCommit | None
@@ -110,6 +109,7 @@ class CodebaseContext:
110
109
session_options : SessionOptions = SessionOptions ()
111
110
projects : list [ProjectConfig ]
112
111
unapplied_diffs : list [DiffLite ]
112
+ io : IO
113
113
114
114
def __init__ (
115
115
self ,
@@ -134,6 +134,7 @@ def __init__(
134
134
135
135
# =====[ __init__ attributes ]=====
136
136
self .projects = projects
137
+ self .io = FileIO ()
137
138
context = projects [0 ]
138
139
self .node_classes = get_node_classes (context .programming_language )
139
140
self .config = config
@@ -165,7 +166,6 @@ def __init__(
165
166
self .pending_syncs = []
166
167
self .all_syncs = []
167
168
self .unapplied_diffs = []
168
- self .pending_files = set ()
169
169
self .flags = Flags ()
170
170
171
171
def __repr__ (self ):
@@ -259,7 +259,13 @@ def _reset_files(self, syncs: list[DiffLite]) -> None:
259
259
files_to_remove .append (sync .path )
260
260
modified_files .add (sync .path )
261
261
logger .info (f"Writing { len (files_to_write )} files to disk and removing { len (files_to_remove )} files" )
262
- write_changes (files_to_remove , files_to_write )
262
+ for file in files_to_remove :
263
+ self .io .delete_file (file )
264
+ to_save = set ()
265
+ for file , content in files_to_write :
266
+ self .io .write_file (file , content )
267
+ to_save .add (file )
268
+ self .io .save_files (to_save )
263
269
264
270
@stopwatch
265
271
def reset_codebase (self ) -> None :
@@ -270,7 +276,7 @@ def reset_codebase(self) -> None:
270
276
def undo_applied_diffs (self ) -> None :
271
277
self .transaction_manager .clear_transactions ()
272
278
self .reset_codebase ()
273
- self .check_changes ()
279
+ self .io . check_changes ()
274
280
self .pending_syncs .clear () # Discard pending changes
275
281
if len (self .all_syncs ) > 0 :
276
282
logger .info (f"Unapplying { len (self .all_syncs )} diffs to graph. Current graph commit: { self .synced_commit } " )
@@ -432,7 +438,7 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr
432
438
433
439
# Step 5: Add new files as nodes to graph (does not yet add edges)
434
440
for filepath in files_to_sync [SyncType .ADD ]:
435
- content = filepath . read_text (errors = "ignore" )
441
+ content = self . io . read_text (filepath )
436
442
# TODO: this is wrong with context changes
437
443
if filepath .suffix in self .extensions :
438
444
file_cls = self .node_classes .file_cls
@@ -634,17 +640,6 @@ def remove_edge(self, u: NodeId, v: NodeId, *, edge_type: EdgeType | None = None
634
640
continue
635
641
self ._graph .remove_edge_from_index (edge )
636
642
637
- def check_changes (self ) -> None :
638
- for file in self .pending_files :
639
- file .check_changes ()
640
- self .pending_files .clear ()
641
-
642
- def write_files (self , files : set [Path ] | None = None ) -> None :
643
- to_write = set (filter (lambda f : f .filepath in files , self .pending_files )) if files is not None else self .pending_files
644
- with ThreadPoolExecutor () as exec :
645
- exec .map (lambda f : f .write_pending_content (), to_write )
646
- self .pending_files .difference_update (to_write )
647
-
648
643
@lru_cache (maxsize = 10000 )
649
644
def to_absolute (self , filepath : PathLike | str ) -> Path :
650
645
path = Path (filepath )
@@ -684,7 +679,7 @@ def commit_transactions(self, sync_graph: bool = True, sync_file: bool = True, f
684
679
685
680
# Write files if requested
686
681
if sync_file :
687
- self .write_files (files )
682
+ self .io . save_files (files )
688
683
689
684
# Sync the graph if requested
690
685
if sync_graph and len (self .pending_syncs ) > 0 :
0 commit comments