I am trying to run from clojure.tools.build.api:
(api/process {:command-args ["git" "log" "--after=2025-01-01" "--pretty=format:%D%n%B"]
:out :capture
:err :capture})
and the REPL just blocks. When I do this instead:
(:out (apply sh "git" "log" "--after=2025-01-01" "--pretty=format:%D%n%B"))
it executes instantly. Am I forgetting something?Released tools.build 0.10.8 with a fix for this (basically just replacing the impl with calls into the Clojure 1.12 clojure.java.process)
@alexmiller I'm curious, this means tools.build requires Clojure 1.12, yes? How long has it required 1.12, vs 1.11 or earlier?
Since 1.12 came out
The former works fine for me in a fresh REPL started with clj -A:build in my next.jdbc project.
How big is the git log for your project (from the apply sh)?
Also, what version of tools.build? what version of Clojure? what O/S environment?
121kb, tools.build 0.10.7 version, Clojure 1.12.0, MacOS
121Kb seems big but not outrageously. macOS vs Ubuntu shouldn't make a difference. How are you starting your REPL / running that code?
I’ve started the REPL in IntelliJ. Let me try that from cmd
yeah that blocks too
so I run:
clj -T:build get-history
and I got this:
:build {:deps {io.github.clojure/tools.build {:git/url ""
:tag "v0.9.0"
:sha "8c93e0c"}}
:extra-deps {babashka/fs {:mvn/version "0.4.19"}
babashka/process {:mvn/version "0.5.21"}}
:paths ["scripts"]
:ns-default build}
And the build.clj file has this:
(defn get-history [_]
(let [delimiter "===COMMIT_DELIMITER==="
;; Added --after to filter commits after 2025-01-01
output (b/git-process {:git-args ["log" "--after=2025-01-01" (str "--pretty=format:%D%n%B" delimiter)]})]
(if (str/blank? output)
[]
(str/split output (re-pattern (str delimiter "\n"))))))If I simplify function to:
(defn get-history [_]
(b/git-process {:git-args ["log" "--after=2025-01-01" "--pretty=format:%D%n%B"]}))same result
debugger shows the thread is waiting on ProcessImpl.waitFor
I just tried that via build.clj in a much bigger project and it works fine -- doesn't show any output (unless I add println into get-history).
Maybe it's something about your git version/install?
> git --version
git version 2.48.1I think its about pipe size
If I add `
:capture nil
then it works
Hmm, maybe.
this code is wrong:
(let [proc (.start pb)
exit (.waitFor proc)
out-str (when (= out :capture) (copy-stream (.getInputStream proc)))
err-str (when (= err :capture) (copy-stream (.getErrorStream proc)))]
(cond-> {:exit exit}
out-str (assoc :out out-str)
err-str (assoc :err err-str)))in clojure.tools.build.tasks.process
you cannot await for process exit before setting up something that will drain the streams
that will cause process to block if the output is big enough
I guess my pipe is small
Ah, winding the date back a year, I've managed to repro. Put it up on http://ask.clojure.org and Alex will make a Jira issue about it.
and git-process doesn’t even let me redirect to file, I only have option to capture out OR capture err OR inherit (so it spills into my own process stdout
I think we had this same conversation multiple times
for now I’ll avoid using this library for running processes
@alexmiller FYI point_up::skin-tone-2 I can repro locally with a large enough output.
Possibly related to https://ask.clojure.org/index.php/11510/clojure-tools-build-process-ignore-hangs-process-large-output ?
that is just one of the modes and yes, he is right, if you’re going for ignore, you need to use discard mode otherwise it will block if there’s too much data in pipe
this process stuff (which was the precursor of the new 1.12 clojure.java.process api) definitely needs some clean up in this area. I actually thought I had done that but must have confused it with the work there
probably best to add it to the existing ask question if there is new info/repro
I added it as a comment on your answer there (where you linked to TBUILD-1)