Skip to content

Commit f53dda9

Browse files
committed
enable second pass, introduce git graph
1 parent bf83ab7 commit f53dda9

File tree

4 files changed

+97
-13
lines changed

4 files changed

+97
-13
lines changed

code_graph/analyzers/source_analyzer.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ def process_file(path: Path) -> None:
7373
# Wait for all tasks to complete
7474
#concurrent.futures.wait(tasks)
7575

76-
def second_pass(self, base: str, root: str,
77-
executor: concurrent.futures.Executor) -> None:
76+
def second_pass(self, ignore: List[str], executor: concurrent.futures.Executor) -> None:
7877
"""
7978
Recursively analyze the contents of a directory.
8079
@@ -85,7 +84,16 @@ def second_pass(self, base: str, root: str,
8584
"""
8685

8786
tasks = []
88-
for dirpath, dirnames, filenames in os.walk(root):
87+
for dirpath, dirnames, filenames in os.walk("."):
88+
89+
# skip current directory if it is within the ignore list
90+
if dirpath in ignore:
91+
# in-place clear dirnames to prevent os.walk from recursing into
92+
# any of the nested directories
93+
logger.info(f'ignoring directory: {dirpath}')
94+
dirnames[:] = []
95+
continue
96+
8997
logger.info(f'Processing directory: {dirpath}')
9098

9199
# Process each file in the current directory
@@ -101,9 +109,8 @@ def second_pass(self, base: str, root: str,
101109

102110
def process_file(path: Path) -> None:
103111
with open(path, 'rb') as f:
104-
relative_path = str(path).replace(base, '')
105112
ext = path.suffix
106-
analyzers[ext].second_pass(Path(relative_path), f, self.graph)
113+
analyzers[ext].second_pass(path, f, self.graph)
107114

108115
task = executor.submit(process_file, file_path)
109116
tasks.append(task)
@@ -117,7 +124,7 @@ def analyze_sources(self, ignore: List[str]) -> None:
117124
self.first_pass(ignore, executor)
118125

119126
# Second pass analysis of the source code
120-
#self.second_pass(ignore, executor)
127+
self.second_pass(ignore, executor)
121128

122129
def analyze_github_repository(self, url: str) -> None:
123130
"""

code_graph/git_utils/git_graph.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class GitGraph():
2+
"""
3+
Represents a git commit graph
4+
nodes are commits where one commit leads to its parents and children
5+
edges contains queries and parameters for transitioning the code-graph
6+
from the current commit to parent / child
7+
"""
8+
9+
def __init__(self, name: str, host: str = 'localhost', port: int = 6379,
10+
username: Optional[str] = None, password: Optional[str] = None):
11+
12+
self.db = FalkorDB(host=host, port=port, username=username,
13+
password=password)
14+
self.g = self.db.select_graph(name)
15+
16+
# create indicies
17+
# index commit hash
18+
try:
19+
self.g.create_node_range_index("Commit", "hash")
20+
except Exception:
21+
pass
22+
23+
24+
def add_commit(self, commit_hash: str, author: str, message: str, date, int) -> None:
25+
"""
26+
Add a new commit to the graph
27+
"""
28+
q = "MERGE (c:Commit {hash: $hash, author: $author, message: $message, date: $date})"
29+
params = {'hash': commit_hash, 'author': author, 'message': message, 'date': $date}
30+
self.g.query(q, params)
31+
32+
33+
def connect_commits(child: str, parent: str) -> None:
34+
"""
35+
connect commits via both PARENT and CHILD edges
36+
"""
37+
38+
q = """MATCH (child :Commit {hash: $child_hash}), (parent :Commit {hash: $parent_hash})
39+
MERGE (child)-[:PARENT]->(parent)
40+
MERGE (parent)-[:CHILD]->(child)"""
41+
42+
params = {'child_hash': child, 'parent_hash': parent}
43+
44+
self.g.query(q, parent)
45+
46+
def set_parent_transition(child: str, parent: str, queries: [tuple[str: dict]]) -> None:
47+
"""
48+
Sets the queries and parameters needed to transition the code-graph
49+
from the child commit to the parent commit
50+
"""
51+
52+
q = """MATCH (child: Commit {hash: $child})-[e:PARENT]->(parent {hash: $parent})
53+
SET e.queries = $queries, e.params = $params"""
54+
55+
params = {'child': child, 'parent': parent, 'queries': queries}
56+
57+
self.g.query(q, params)
58+
59+
def set_child_transition(child: str, parent: str, queries: [tuple[str: dict]]) -> None:
60+
"""
61+
Sets the queries and parameters needed to transition the code-graph
62+
from the parent commit to the child commit
63+
"""
64+
65+
q = """MATCH (parent {hash: $parent})-[e:CHILD]->(child: Commit {hash: $child})
66+
SET e.queries = $queries, e.params = $params"""
67+
68+
params = {'child': child, 'parent': parent, 'queries': queries}
69+
70+
self.g.query(q, params)

code_graph/git_utils/git_utils.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ def build_commit_graph(path: str):
104104
repo_name = os.path.split(os.path.normpath(path))[-1]
105105
g = Graph(repo_name)
106106

107-
# TODO: need to wait for replication to sync with its master
108-
setup_replication()
107+
#setup_replication()
109108

110109
# start monitoring graph effects
111110
# these capture the changes a graph goes through when moving from one
@@ -160,12 +159,15 @@ def build_commit_graph(path: str):
160159
'ext' : os.path.splitext(path)[1]} for path in deleted]
161160

162161
# remove deleted files from the graph
163-
g.delete_files(deleted_files)
162+
q, params = g.delete_files(deleted_files, True)
163+
if(q is not None):
164+
# log transition action
165+
164166
input("Press Enter to continue...")
165167

166168
# clean up
167-
stop_monitor_effects()
168-
teardown_replica()
169+
#stop_monitor_effects()
170+
#teardown_replica()
169171

170172
if __name__ == "__main__":
171173
build_commit_graph("/Users/roilipman/Dev/FalkorDB")

code_graph/graph.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def add_file(self, file: File) -> None:
240240
res = self.g.query(q, params)
241241
file.id = res.result_set[0][0]
242242

243-
def delete_files(self, files: List[dict]) -> None:
243+
def delete_files(self, files: List[dict], log: bool = False) -> tuple[str, dict]:
244244
"""
245245
Deletes file(s) from the graph in addition to any other entity
246246
defined in the file
@@ -260,7 +260,12 @@ def delete_files(self, files: List[dict]) -> None:
260260
"""
261261

262262
params = {'files': files}
263-
self.g.query(q, params)
263+
res = self.g.query(q, params)
264+
265+
if log and (res.relationships_deleted > 0 or res.nodes_deleted > 0):
266+
return (q, params)
267+
268+
return None
264269

265270
def get_file(self, path: str, name: str, ext: str) -> Optional[File]:
266271
"""

0 commit comments

Comments
 (0)