@@ -102,46 +102,54 @@ def build_nix_eval_command(max_workers: int, flake_outputs: List[str]) -> List[s
102102 return nix_eval_cmd
103103
104104
105- def parse_nix_eval_line (line : str , drv_paths : Set [str ]) -> Optional [NixEvalJobsOutput ]:
105+ def parse_nix_eval_line (
106+ line : str , drv_paths : Set [str ], errors : List [str ]
107+ ) -> Optional [NixEvalJobsOutput ]:
106108 """Parse a single line of nix-eval-jobs output"""
107109 if not line .strip ():
108110 return None
109111
110112 try :
111113 data : NixEvalJobsOutput = json .loads (line )
112114 if "error" in data :
113- raise ValueError (
115+ error_msg = (
114116 f"Error in nix-eval-jobs output for { data ['attr' ]} : { data ['error' ]} "
115117 )
118+ errors .append (error_msg )
119+ return None
116120 if data ["drvPath" ] in drv_paths :
117121 return None
118122 drv_paths .add (data ["drvPath" ])
119123 return data
120124 except json .JSONDecodeError :
121- print (f"Skipping invalid JSON line: { line } " , file = sys .stderr )
125+ error_msg = f"Skipping invalid JSON line: { line } "
126+ print (error_msg , file = sys .stderr )
127+ errors .append (error_msg )
122128 return None
123129
124130
125- def run_nix_eval_jobs (cmd : List [str ]) -> Generator [NixEvalJobsOutput , None , None ]:
131+ def run_nix_eval_jobs (
132+ cmd : List [str ], errors : List [str ]
133+ ) -> Generator [NixEvalJobsOutput , None , None ]:
126134 """Run nix-eval-jobs and yield parsed package data."""
127135 print (f"Running command: { ' ' .join (cmd )} " , file = sys .stderr )
128136
129137 with subprocess .Popen (
130- cmd , stdout = subprocess .PIPE , stderr = subprocess . PIPE , text = True
138+ cmd , stdout = subprocess .PIPE , stderr = None , text = True
131139 ) as process :
132140 drv_paths : Set [str ] = set ()
133141 assert process .stdout is not None # for mypy
134- assert process .stderr is not None # for mypy
135142 for line in process .stdout :
136- package = parse_nix_eval_line (line , drv_paths )
143+ package = parse_nix_eval_line (line , drv_paths , errors )
137144 if package :
138145 yield package
139146
140147 process .wait ()
141148 if process .returncode != 0 :
142- print ("Error: Evaluation failed" , file = sys .stderr )
143- sys .stderr .write (process .stderr .read ())
144- sys .exit (process .returncode )
149+ error_msg = "Error: nix-eval-jobs process failed with non-zero exit code"
150+ print (error_msg , file = sys .stderr )
151+ errors .append (error_msg )
152+ # Don't exit here - let main() handle it after reporting all errors
145153
146154
147155def is_extension_pkg (pkg : NixEvalJobsOutput ) -> bool :
@@ -227,7 +235,9 @@ def main() -> None:
227235
228236 cmd = build_nix_eval_command (max_workers , args .flake_outputs )
229237
230- gh_action_packages = sort_pkgs_by_closures (list (run_nix_eval_jobs (cmd )))
238+ # Collect all evaluation errors
239+ errors : List [str ] = []
240+ gh_action_packages = sort_pkgs_by_closures (list (run_nix_eval_jobs (cmd , errors )))
231241
232242 def clean_package_for_output (pkg : NixEvalJobsOutput ) -> GitHubActionPackage :
233243 """Convert nix-eval-jobs output to GitHub Actions matrix package"""
@@ -277,6 +287,18 @@ def clean_package_for_output(pkg: NixEvalJobsOutput) -> GitHubActionPackage:
277287 )
278288 print (json .dumps (gh_output ))
279289
290+ # Check if any errors occurred during evaluation
291+ if errors :
292+ print ("\n === Evaluation Errors ===" , file = sys .stderr )
293+ for i , error in enumerate (errors , 1 ):
294+ print (f"\n Error { i } :" , file = sys .stderr )
295+ print (error , file = sys .stderr )
296+ print (
297+ f"\n === Total: { len (errors )} error(s) occurred during evaluation ===" ,
298+ file = sys .stderr ,
299+ )
300+ sys .exit (1 )
301+
280302
281303if __name__ == "__main__" :
282304 main ()
0 commit comments