1212import java .util .concurrent .ExecutorService ;
1313import java .util .concurrent .Executors ;
1414import java .util .concurrent .Future ;
15+ import java .util .concurrent .TimeUnit ;
1516import java .util .regex .Matcher ;
1617import java .util .regex .Pattern ;
1718import java .nio .file .Paths ;
@@ -152,7 +153,7 @@ private String toJson() {
152153 private final java .util .function .Function <String , CliResult > cliInvoker ;
153154
154155 public CliBridge (Path workspaceRoot ) {
155- this (workspaceRoot , defaultCliCommandArgs (), null );
156+ this (workspaceRoot , defaultCliCommandArgs (workspaceRoot ), null );
156157 }
157158
158159 public CliBridge () {
@@ -164,7 +165,7 @@ public CliBridge(Path workspaceRoot, String cliCommand) {
164165 }
165166
166167 CliBridge (Path workspaceRoot , java .util .function .Function <String , CliResult > cliInvoker ) {
167- this (workspaceRoot , defaultCliCommandArgs (), cliInvoker );
168+ this (workspaceRoot , defaultCliCommandArgs (workspaceRoot ), cliInvoker );
168169 }
169170
170171 CliBridge (
@@ -183,14 +184,14 @@ private static List<String> shellCommand(String cliCommand) {
183184 return List .of ("sh" , "-lc" , cliCommand );
184185 }
185186
186- private static List <String > defaultCliCommandArgs () {
187+ private static List <String > defaultCliCommandArgs (Path workspaceRoot ) {
187188 String configuredCli = System .getenv ("GIT_TESTKIT_CLI" );
188189 if (configuredCli != null && !configuredCli .isBlank ()) {
189190 Path cliPath = Paths .get (configuredCli );
190191 if (!cliPath .isAbsolute ()) {
191- cliPath = detectWorkspaceRoot () .resolve (cliPath ).normalize ();
192+ cliPath = workspaceRoot .resolve (cliPath ).normalize ();
192193 }
193- return shellCommand (cliPath .toString ());
194+ return List . of (cliPath .toString ());
194195 }
195196 return List .of ("go" , "run" , "./cmd/git-testkit-cli" );
196197 }
@@ -371,21 +372,28 @@ private CliResult runCli(String payload) {
371372 if (cliInvoker != null ) {
372373 return cliInvoker .apply (payload );
373374 }
375+ Process process = null ;
374376 ExecutorService streamReaderPool = null ;
377+ Future <String > stdoutFuture = null ;
378+ Future <String > stderrFuture = null ;
375379 try {
376380 ProcessBuilder pb = new ProcessBuilder (cliCommandArgs );
377381 pb .directory (workspaceRoot .toFile ());
378- Process process = pb .start ();
382+ process = pb .start ();
379383 streamReaderPool = Executors .newFixedThreadPool (2 );
380- Future < String > stdoutFuture =
384+ stdoutFuture =
381385 streamReaderPool .submit (
382386 () -> new String (process .getInputStream ().readAllBytes (), StandardCharsets .UTF_8 ));
383- Future < String > stderrFuture =
387+ stderrFuture =
384388 streamReaderPool .submit (
385389 () -> new String (process .getErrorStream ().readAllBytes (), StandardCharsets .UTF_8 ));
386390 process .getOutputStream ().write (payload .getBytes (StandardCharsets .UTF_8 ));
387391 process .getOutputStream ().close ();
388- int code = process .waitFor ();
392+ boolean completed = process .waitFor (120 , TimeUnit .SECONDS );
393+ if (!completed ) {
394+ throw new RuntimeException ("CLI process timed out after 120 seconds" );
395+ }
396+ int code = process .exitValue ();
389397 String stdout = stdoutFuture .get ();
390398 String stderr = stderrFuture .get ();
391399 return new CliResult (stdout , stderr , code );
@@ -397,8 +405,22 @@ private CliResult runCli(String payload) {
397405 Thread .currentThread ().interrupt ();
398406 throw new RuntimeException ("interrupted while invoking CLI" , ex );
399407 } finally {
408+ if (process != null && process .isAlive ()) {
409+ process .destroyForcibly ();
410+ }
411+ if (stdoutFuture != null ) {
412+ stdoutFuture .cancel (true );
413+ }
414+ if (stderrFuture != null ) {
415+ stderrFuture .cancel (true );
416+ }
400417 if (streamReaderPool != null ) {
401418 streamReaderPool .shutdownNow ();
419+ try {
420+ streamReaderPool .awaitTermination (5 , TimeUnit .SECONDS );
421+ } catch (InterruptedException ex ) {
422+ Thread .currentThread ().interrupt ();
423+ }
402424 }
403425 }
404426 }
@@ -589,4 +611,4 @@ private static String stringListToJson(List<String> values) {
589611 sb .append (']' );
590612 return sb .toString ();
591613 }
592- }
614+ }
0 commit comments