66
77import sys
88from pathlib import Path
9- from typing import Dict , List , Tuple
109
1110import click
12-
1311from src .utils .schema_validator import CompetitionSchemaValidator , create_validation_summary
1412
1513
1614def print_validation_results (
17- results : Dict [str , Tuple [bool , List [str ]]],
18- verbose : bool = False ,
19- show_valid : bool = False
15+ results : dict [str , tuple [bool , list [str ]]], verbose : bool = False , show_valid : bool = False
2016) -> None :
2117 """Print validation results in a readable format"""
22-
18+
2319 for file_path , (is_valid , errors ) in results .items ():
2420 file_name = Path (file_path ).name
25-
21+
2622 if is_valid :
2723 click .echo (f"✅ { file_name } : VALID" , color = True )
2824 if show_valid and verbose :
@@ -42,28 +38,28 @@ def print_validation_results(
4238 click .echo (f" └─ { clean_error } " )
4339
4440
45- def print_summary (summary : Dict , show_details : bool = True ) -> None :
41+ def print_summary (summary : dict , show_details : bool = True ) -> None :
4642 """Print validation summary"""
4743 click .echo ("\n " + "=" * 60 )
4844 click .echo ("📊 VALIDATION SUMMARY" )
4945 click .echo ("=" * 60 )
50-
46+
5147 click .echo (f"Total files: { summary ['total_files' ]} " )
5248 click .echo (f"✅ Valid files: { summary ['valid_files' ]} " )
5349 click .echo (f"❌ Invalid files: { summary ['invalid_files' ]} " )
5450 click .echo (f"📈 Success rate: { summary ['success_rate' ]:.1f} %" )
55-
56- if summary [' total_errors' ] > 0 :
51+
52+ if summary [" total_errors" ] > 0 :
5753 click .echo (f"🔍 Total errors: { summary ['total_errors' ]} " )
58-
59- if show_details and summary .get (' error_summary' ):
60- click .echo (f "\n 📋 Common errors:" )
61- for i , error in enumerate (summary [' error_summary' ], 1 ):
54+
55+ if show_details and summary .get (" error_summary" ):
56+ click .echo ("\n 📋 Common errors:" )
57+ for i , error in enumerate (summary [" error_summary" ], 1 ):
6258 clean_error = error .split (": " , 1 )[- 1 ] if ": " in error else error
6359 click .echo (f" { i } . { clean_error } " )
64-
65- if summary .get (' truncated' ):
66- remaining = summary [' total_errors' ] - len (summary [' error_summary' ])
60+
61+ if summary .get (" truncated" ):
62+ remaining = summary [" total_errors" ] - len (summary [" error_summary" ])
6763 click .echo (f" ... and { remaining } more errors (use --verbose to see all)" )
6864
6965
@@ -75,50 +71,45 @@ def print_summary(summary: Dict, show_details: bool = True) -> None:
7571@click .option ("--show-valid" , is_flag = True , help = "Show details for valid files too" )
7672@click .option ("--quiet" , "-q" , is_flag = True , help = "Only show summary" )
7773def main (
78- path : str ,
79- verbose : bool ,
80- schema : str ,
81- pattern : str ,
82- show_valid : bool ,
83- quiet : bool
74+ path : str , verbose : bool , schema : str , pattern : str , show_valid : bool , quiet : bool
8475) -> None :
8576 """🔍 Validate competition JSON files against schema
86-
77+
8778 Validates individual JSON files or all JSON files in a directory against
8879 the competition findings schema specification.
89-
80+
9081 \b
9182 Examples:
9283 uv run validate findings/quesma.findings.1.json
9384 uv run validate findings/ --verbose
9485 uv run validate findings/ --pattern "competition_*.json"
9586 uv run validate findings/ --schema custom/schema.json
96-
87+
9788 \b
9889 Arguments:
9990 PATH Path to JSON file or directory containing JSON files
100-
91+
10192 \b
10293 Exit codes:
10394 0 - All files are valid
10495 1 - Some files are invalid
10596 2 - Error (schema not found, no files, etc.)
10697 """
107-
98+
10899 try :
109100 # Initialize validator
110101 if not quiet :
111102 click .echo (f"🔧 Loading schema from: { schema } " )
112-
103+
113104 validator = CompetitionSchemaValidator (schema )
114-
105+
115106 if not quiet :
116107 schema_info = validator .get_schema_info ()
117108 click .echo (f"📋 Schema: { schema_info ['title' ]} " )
118109 click .echo (f"🔗 Schema ID: { schema_info ['schema_id' ]} " )
119-
110+
120111 path_obj = Path (path )
121-
112+
122113 # Determine if we're validating a single file or directory
123114 if path_obj .is_file ():
124115 if not quiet :
@@ -128,33 +119,36 @@ def main(
128119 if not quiet :
129120 click .echo (f"📁 Validating directory: { path } (pattern: { pattern } )" )
130121 results = validator .validate_directory (path , pattern )
131-
122+
132123 # Check if we found any files
133124 if not results :
134125 click .echo ("❌ No files found to validate" , err = True )
135126 sys .exit (2 )
136-
127+
137128 # Print results
138129 if not quiet :
139130 click .echo ("\n " + "=" * 60 )
140131 click .echo ("🔍 VALIDATION RESULTS" )
141132 click .echo ("=" * 60 )
142133 print_validation_results (results , verbose , show_valid )
143-
134+
144135 # Print summary
145136 summary = create_validation_summary (results )
146137 print_summary (summary , show_details = verbose and not quiet )
147-
138+
148139 # Determine exit code
149- if summary [' invalid_files' ] == 0 :
140+ if summary [" invalid_files" ] == 0 :
150141 if not quiet :
151142 click .echo (f"\n 🎉 All { summary ['total_files' ]} files are valid!" , color = True )
152143 sys .exit (0 )
153144 else :
154145 if not quiet :
155- click .echo (f"\n ⚠️ { summary ['invalid_files' ]} of { summary ['total_files' ]} files have validation errors" , color = True )
146+ click .echo (
147+ f"\n ⚠️ { summary ['invalid_files' ]} of { summary ['total_files' ]} files have validation errors" ,
148+ color = True ,
149+ )
156150 sys .exit (1 )
157-
151+
158152 except FileNotFoundError as e :
159153 click .echo (f"❌ Error: { e } " , err = True )
160154 sys .exit (2 )
@@ -168,4 +162,4 @@ def main(
168162
169163
170164if __name__ == "__main__" :
171- main ()
165+ main ()
0 commit comments