55import re
66import xml .etree .ElementTree as ET
77
8- def validate_workflow (workflow_file , console ):
8+ def validate_workflow (workflow_file , source_dir , console ):
99 workflow_path = Path (workflow_file )
10+ source_root = (workflow_path .parent / source_dir )
1011
1112 console .print (f"[cyan]Validating:[/cyan] { workflow_path .name } " )
1213 console .print ()
@@ -15,31 +16,35 @@ def validate_workflow(workflow_file, console):
1516 warnings = []
1617 info = []
1718
19+ def finalize ():
20+ show_results (console , errors , warnings , info )
21+ return len (errors ) == 0
22+
1823 try :
1924 with open (workflow_path , 'r' ) as f :
2025 content = f .read ()
2126
2227 if not content .strip ():
2328 errors .append ("File is empty" )
24- return show_results ( console , errors , warnings , info )
29+ return finalize ( )
2530
2631 # strict XML syntax check
2732 try :
2833 ET .fromstring (content )
2934 except ET .ParseError as e :
3035 errors .append (f"Invalid XML: { str (e )} " )
31- return show_results ( console , errors , warnings , info )
36+ return finalize ( )
3237
3338 try :
3439 soup = BeautifulSoup (content , 'xml' )
3540 except Exception as e :
3641 errors .append (f"Invalid XML: { str (e )} " )
37- return show_results ( console , errors , warnings , info )
42+ return finalize ( )
3843
3944 root = soup .find ('graphml' )
4045 if not root :
4146 errors .append ("Not a valid GraphML file - missing <graphml> root element" )
42- return show_results ( console , errors , warnings , info )
47+ return finalize ( )
4348
4449 # check the graph attributes
4550 graph = soup .find ('graph' )
@@ -64,6 +69,9 @@ def validate_workflow(workflow_file, console):
6469 warnings .append ("No edges found in workflow" )
6570 else :
6671 info .append (f"Found { len (edges )} edge(s)" )
72+
73+ if not source_root .exists ():
74+ warnings .append (f"Source directory not found: { source_root } " )
6775
6876 node_labels = []
6977 for node in nodes :
@@ -101,6 +109,10 @@ def validate_workflow(workflow_file, console):
101109 errors .append (f"Node '{ label } ' has no filename" )
102110 elif not any (filename .endswith (ext ) for ext in ['.py' , '.cpp' , '.m' , '.v' , '.java' ]):
103111 warnings .append (f"Node '{ label } ' has unusual file extension" )
112+ elif source_root .exists ():
113+ file_path = source_root / filename
114+ if not file_path .exists ():
115+ errors .append (f"Missing source file: { filename } " )
104116 else :
105117 warnings .append (f"Node { node_id } has no label" )
106118 except Exception as e :
@@ -143,12 +155,14 @@ def validate_workflow(workflow_file, console):
143155 if file_edges > 0 :
144156 info .append (f"File-based edges: { file_edges } " )
145157
146- show_results ( console , errors , warnings , info )
147-
158+ return finalize ( )
159+
148160 except FileNotFoundError :
149161 console .print (f"[red]Error:[/red] File not found: { workflow_path } " )
162+ return False
150163 except Exception as e :
151164 console .print (f"[red]Validation failed:[/red] { str (e )} " )
165+ return False
152166
153167def show_results (console , errors , warnings , info ):
154168 if errors :
0 commit comments