This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-09-04
Channels
- # architecture (9)
- # babashka (33)
- # beginners (53)
- # biff (3)
- # cljdoc (11)
- # clojure (8)
- # clojure-austria (2)
- # clojure-dev (9)
- # clojure-europe (64)
- # clojure-nl (2)
- # clojure-norway (49)
- # clojure-sweden (4)
- # clojure-uk (4)
- # clojurescript (16)
- # cursive (14)
- # datahike (31)
- # datalevin (6)
- # datascript (9)
- # events (1)
- # fulcro (4)
- # honeysql (8)
- # hyperfiddle (116)
- # introduce-yourself (1)
- # kaocha (2)
- # malli (13)
- # nyc (2)
- # off-topic (4)
- # polylith (5)
- # portal (1)
- # reagent (1)
- # reitit (18)
- # releases (1)
- # spacemacs (6)
How to make a Babashka program running external shell commands work on Windows? ๐งต
Suppose I have curl installed on Windows and curl.exe is on the PATH. (Note that curl is just an example here - I know better options for making HTTP requests exist in bb, but the q is not about that).
Some observations (please correct if wrong):
1. babashka.process/shell seems to work differently on Windows than on Unix. For one thing, if you specify a bare command like "curl", the command finds it in PATH, whereas on Windows it doesn't seem to look at PATH at all.
2. Binaries on Windows have the .exe
extension. bash
on Windows or cmd.exe
allow you to run curl
and will find a binary called curl.exe
for you if necessary, but babashka.process/shell doesn't.
3. These differences are not due to babashka.process but originate in ProcessBuilder, which takes an agnostic approach, forwarding the command to the OS. From the https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/lang/ProcessBuilder.html: "a command, a list of strings which signifies the external program file to be invoked and its arguments, if any. Which string lists represent a valid operating system command is system-dependent."
So what I'm looking for is guidance on how to write a cross-platform bb program. What are the best practices here?
Do you mean that if I run
(shell "curl")
, it'll look for an exe file in PATH?OK, then my whole mental model may be off. I'll try this and get back to you
(Part of the problem is that it's a PITA to get a working Windows shell... without a Windows box)
What I do is to spin up an SSH on CircleCI, but it takes a while and the ssh terminal is pretty janky
C:\Users\borkdude>bb
Babashka v1.3.177 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> (require '[babashka.process :refer [shell]])
nil
user=> (shell "curl")
curl: try 'curl --help' or 'curl --manual' for more information
clojure.lang.ExceptionInfo [at <repl>:2:1]
so to confirm, it "just works" on Windows, by design. This is babashka.process doing extra work on top of processbuilder
You're right โ it seems to be working just fine
Babashka v1.3.184 REPL.
Use :repl/quit or :repl/exit to quit the REPL.
Clojure rocks, Bash reaches.
user=> (babashka.process/shell "java" "-version")
openjdk version "20.0.2" 2023-07-18
OpenJDK Runtime Environment (build 20.0.2+9-78)
OpenJDK 64-Bit Server VM (build 20.0.2+9-78, mixed mode, sharing)
{:proc #object[java.lang.ProcessImpl 0x379b0638 "Process[pid=8328, exitValue=0]"], :exit 0, :in #object[java.lang.ProcessBuilder$NullOutputStream 0x5adbebf2 "java.lang.ProcessBuilder$NullOutputStream@5adbebf2"], :out #object[java.lang.ProcessBuilder$NullInputStream 0x3743635c "java.lang.ProcessBuilder$NullInputStream@3743635c"], :err #object[java.lang.ProcessBuilder$NullInputStream 0x3743635c "java.lang.ProcessBuilder$NullInputStream@3743635c"], :prev nil, :cmd ["C:\\Program Files\\OpenJDK\\jdk-20.0.2\\bin\\java.exe" "-version"]}
1. "java" find java.exe 2. find that exe in PATH
I am getting an error running
(b/write-pom {:src-pom pom-template
:src-dirs src-dirs
:class-dir class-dir
:lib lib
:version (version/string repo-config)
:basis (basis project-config)
:scm (assoc scm :tag (version/sha))})
----- Error --------------------------------------------------------------------
Type: java.lang.Exception
Message: Unable to resolve classname: java.util.concurrent.ConcurrentMap
Location: clojure/tools/deps/alpha/util/session.clj:12:3
----- Context ------------------------------------------------------------------
8:
9: (ns ^{:skip-wiki true}
10: clojure.tools.deps.alpha.util.session
11: "Maintains session resources during or across runs of the resolver"
12: (:import
^--- Unable to resolve classname: java.util.concurrent.ConcurrentMap
13: [java.util.concurrent ConcurrentMap ConcurrentHashMap]
14: [java.util.function Function]))
15:
16: (def session (ConcurrentHashMap.)) ;; should never be nil
17:
----- Stack trace --------------------------------------------------------------
clojure.tools.deps.alpha.util.session - clojure/tools/deps/alpha/util/session.clj:12:3
clojure.tools.deps.alpha - clojure/tools/deps/alpha.clj:10:3
clojure.tools.build.tasks.process - /home/timo/.gitlibs/libs/io.github.babashka/tools.bbuild/0a4959d2b1147f79e9fb37e0243727390b8ba2b3/src/main/clojure/clojure/tools/build/tasks/process.clj:10:3
clojure.tools.build.api/process - /home/timo/.gitlibs/libs/io.github.babashka/tools.bbuild/0a4959d2b1147f79e9fb37e0243727390b8ba2b3/src/main/clojure/clojure/tools/build/api.clj:205:3
clojure.tools.build.api/process - /home/timo/.gitlibs/libs/io.github.babashka/tools.bbuild/0a4959d2b1147f79e9fb37e0243727390b8ba2b3/src/main/clojure/clojure/tools/build/api.clj:180:1
... (run with --debug to see elided elements)
tools.build - /home/timo/projects/datahike/bb/src/tools/build.clj:50:26
clojure.tools.build.api/write-pom - /home/timo/.gitlibs/libs/io.github.babashka/tools.bbuild/0a4959d2b1147f79e9fb37e0243727390b8ba2b3/src/main/clojure/clojure/tools/build/api.clj:344:1
tools.build/pom - /home/timo/projects/datahike/bb/src/tools/build.clj:46:3
tools.build/pom - /home/timo/projects/datahike/bb/src/tools/build.clj:43:1
user-8e1ba67e-6b46-4b05-8393-8d0f8269567a - <expr>:26:1
Is this expected when running with latest tools.deps.native?@U4GEXTNGZ Looks like it isn't exposed https://github.com/babashka/babashka/blob/master/src/babashka/impl/classes.clj#L450