FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
cecli/cecli/change_tracker.py at main · cecli-dev/cecli · GitHub
cecli-dev
cecli
Repository navigation
Code
Issues
11
(11)
Pull requests
8
(8)
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
cecli
/
cecli
/
change_tracker.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
133 lines (108 loc) · 4.77 KB
Breadcrumbs
cecli
/
cecli
/
change_tracker.py
Copy path
File metadata and controls
133 lines (108 loc) · 4.77 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import
time
import
uuid
from
collections
import
defaultdict
class
ChangeTracker
:
"""
Tracks changes made to files for the undo functionality.
This enables granular editing operations with the ability to undo specific changes.
"""
def
__init__
(
self
):
self
.
changes
=
{}
# change_id -> change_info
self
.
files_changed
=
defaultdict
(
list
)
# file_path -> [change_ids]
def
track_change
(
self
,
file_path
,
change_type
,
original_content
,
new_content
,
metadata
=
None
,
change_id
=
None
):
"""
Record a change to enable future undo operations.
Parameters:
- file_path: Path to the file that was changed
- change_type: Type of change (e.g., 'editfile', 'insertlines')
- original_content: Original content before the change
- new_content: New content after the change
- metadata: Additional information about the change (line numbers, positions, etc.)
- change_id: Optional custom ID for the change (if None, one will be generated)
Returns:
- change_id: Unique identifier for the change
"""
if
change_id
is
None
:
generated_id
=
self
.
_generate_change_id
()
# Ensure the generated ID is treated as a string
current_change_id
=
str
(
generated_id
)
else
:
# If an ID is provided, ensure it's treated as a string key/value
current_change_id
=
str
(
change_id
)
# Defensive check: Ensure the ID isn't literally the string 'False' or boolean False
# which might indicate an upstream issue or unexpected input.
if
current_change_id
==
"False"
or
current_change_id
is
False
:
# Log a warning? For now, generate a new ID to prevent storing False.
print
(
f"Warning: change_id evaluated to False for
{
file_path
}
. Generating new ID."
)
current_change_id
=
self
.
_generate_change_id
()
change
=
{
# Use the confirmed string ID here
"id"
:
current_change_id
,
"file_path"
:
file_path
,
"type"
:
change_type
,
"original"
:
original_content
,
"new"
:
new_content
,
"metadata"
:
metadata
or
{},
"timestamp"
:
time
.
time
(),
}
# Use the confirmed string ID for storage and return
self
.
changes
[
current_change_id
]
=
change
self
.
files_changed
[
file_path
].
append
(
current_change_id
)
return
current_change_id
def
undo_change
(
self
,
change_id
):
"""
Get information needed to reverse a specific change by ID.
Parameters:
- change_id: ID of the change to undo
Returns:
- (success, message, change_info): Tuple with success flag, message, and change information
"""
if
change_id
not
in
self
.
changes
:
return
False
,
f"Change ID
{
change_id
}
not found"
,
None
change
=
self
.
changes
[
change_id
]
# Mark this change as undone by removing it from the tracking dictionaries
self
.
files_changed
[
change
[
"file_path"
]].
remove
(
change_id
)
if
not
self
.
files_changed
[
change
[
"file_path"
]]:
del
self
.
files_changed
[
change
[
"file_path"
]]
# Keep the change in the changes dict but mark it as undone
change
[
"undone"
]
=
True
change
[
"undone_at"
]
=
time
.
time
()
return
True
,
f"Undid change
{
change_id
}
in
{
change
[
'file_path'
]
}
"
,
change
def
get_last_change
(
self
,
file_path
):
"""
Get the most recent change for a specific file.
Parameters:
- file_path: Path to the file
Returns:
- change_id or None if no changes found
"""
changes
=
self
.
files_changed
.
get
(
file_path
, [])
if
not
changes
:
return
None
return
changes
[
-
1
]
def
list_changes
(
self
,
file_path
=
None
,
limit
=
10
):
"""
List recent changes, optionally filtered by file.
Parameters:
- file_path: Optional path to filter changes by file
- limit: Maximum number of changes to list
Returns:
- List of change dictionaries
"""
if
file_path
:
# Get changes only for the specified file
change_ids
=
self
.
files_changed
.
get
(
file_path
, [])
changes
=
[
self
.
changes
[
cid
]
for
cid
in
change_ids
if
cid
in
self
.
changes
]
else
:
# Get all changes
changes
=
list
(
self
.
changes
.
values
())
# Filter out undone changes and sort by timestamp (most recent first)
changes
=
[
c
for
c
in
changes
if
not
c
.
get
(
"undone"
,
False
)]
changes
=
sorted
(
changes
,
key
=
lambda
c
:
c
[
"timestamp"
],
reverse
=
True
)
# Apply limit
return
changes
[:
limit
]
def
_generate_change_id
(
self
):
"""Generate a unique ID for a change."""
return
str
(
uuid
.
uuid4
())[:
8
]
# Short, readable ID
Back
|
FazBrowse Home
|
New Git URL