Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in Clojure CLI by
edited by

Hi,

there appears to be a discrepancy with regards to the exit code
between the ClojureTools running on MS-Windows versus the equivalent
bash script running on the other platforms. Failure is not reflected in
the script's exit code, making it nearly impossible to pragmatically
check if the script has succeeded or failed, something that is
extremely important to do in tests or build tools . A potential fix is
given at the end.

For example on GNU/Linux, it is possible to programmatically check when
the clojure/clj scripts have succeeded or failed (0 for success):

$ clojure -P
$ echo $?
0

$ clojure -xyz
WARNING: Implicit use of clojure.main with options is deprecated, use -M
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
-xyz (No such file or directory)

Full report at:
/tmp/clojure-628210293108097879.edn 
$ echo $?
1

$ clojure -e '(System/exit 9)'
WARNING: Implicit use of clojure.main with options is deprecated, use -M
$ echo $?
9

While on MS-Windows the ClojureTools PowerShell module always indicates success (i.e. 0).

When invoked from the command prompt:

> powershell -command clojure -P
> echo %errorlevel%
0

> powershell -command clojure -xyz
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
-xyz (The system cannot find the file specified)

Full report at:
C:\Users\ikappaki\AppData\Local\Temp\clojure-7295297239959331514.edn    
>echo %errorlevel%
0

> powershell -command clojure -e '(System/exit 9)'
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M    
>echo %errorlevel%
0

the same is true when the module is invoked from PowerShell directly
(success is indicated by "True").

PS > clojure -P
PS > echo $?
True

PS > clojure -xyz
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
-xyz (The system cannot find the file specified)

Full report at:
C:\Users\ikappaki\AppData\Local\Temp\clojure-3534624963016063488.edn
PS > echo $?
True

PS > clojure -e '(System/exit 9)'
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M
PS > echo $?
True

A potential fix for this (which is only tested in isolation) is to
check the exit code of the java invocations in the PowerShell script
and throw if it is not zero to indicate failure.

e.g by placing the following after each java command (the throw
message of course can be changed to something more meaningful)

if ($LastExitCode -gt 0) { throw $LastExitCode; }

We get the following results

On the command prompt (notice how that the exit code though is 1 not 9, a
limitation of this fix, but still good enough since it indicates that the
module has failed):

> powershell -command clojure -e '(System/exit 9)'
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M
At C:\Users\ikappaki\Documents\WindowsPowerShell\Modules\ClojureTools\ClojureTools.psm1:455 char:29
+     if ($LastExitCode -gt 0) { throw $LastExitCode; }
+                                ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (9:Int32) [], RuntimeException
    + FullyQualifiedErrorId : 9


> echo %errorlevel%
1

On the PS shell (failure is "False")

PS > clojure -e '(System/exit 9)'
WARNING: WARNING: Implicit use of clojure.main with options is deprecated, use -M
At C:\Users\ikappaki\Documents\WindowsPowerShell\Modules\ClojureTools\ClojureTools.psm1:455 char:29
+     if ($LastExitCode -gt 0) { throw $LastExitCode; }
+                                ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (9:Int32) [], RuntimeException
    + FullyQualifiedErrorId : 9

PS > echo $?
False

Thanks

1 Answer

0 votes
by

As discussed in #clj-on-windows with Alex Miller (Clojure team), the plan is to depracate the powershell ClojureTools module in favor of deps.clj and the MSI installer, thus no further action was deemed necessary.

Just for reference, as part of this invistigation a question was raised on stackoverflow about what is the best way to indicate failure to the calling program from a PowerShell module at https://stackoverflow.com/questions/74244663/how-to-best-indicate-failure-of-a-powershell-module-to-the-calling-shell-process.

...