branch: elpa/cider
commit cdf46363721c8b5eb6a6cda075096265f758b7c6
Author: vemv <v...@users.noreply.github.com>
Commit: vemv <v...@users.noreply.github.com>

    Make Lein enrich-classpath jack-in async
    
    Fixes https://github.com/clojure-emacs/cider/issues/3446
---
 cider.el            | 69 +++++++++++++++--------------------------------------
 clojure.sh          |  2 +-
 lein.sh             | 31 ++++++++++++++++++++++++
 test/cider-tests.el | 14 +++++------
 4 files changed, 58 insertions(+), 58 deletions(-)

diff --git a/cider.el b/cider.el
index 25569ce1a0..c6febb2046 100644
--- a/cider.el
+++ b/cider.el
@@ -411,6 +411,12 @@ without interfering with classloaders."
   :package-version '(cider . "1.2.0")
   :safe #'booleanp)
 
+(defun cider--get-enrich-classpath-lein-script ()
+  "Returns the location of enrich-classpath's lein.sh wrapper script."
+  (when-let ((cider-location (locate-library "cider.el" t)))
+    (concat (file-name-directory cider-location)
+            "lein.sh")))
+
 (defun cider--get-enrich-classpath-clojure-cli-script ()
   "Returns the location of enrich-classpath's clojure.sh wrapper script."
   (when-let ((cider-location (locate-library "cider.el" t)))
@@ -421,13 +427,21 @@ without interfering with classloaders."
   "Determine the resolved file path to `cider-jack-in-command'.
 Throws an error if PROJECT-TYPE is unknown."
   (pcase project-type
-    ('lein (cider--resolve-command cider-lein-command))
+    ('lein (let ((r (cider--resolve-command cider-lein-command)))
+             (if (and cider-enrich-classpath
+                      (not (eq system-type 'windows-nt))
+                      (executable-find 
(cider--get-enrich-classpath-lein-script)))
+                 (concat "bash " ;; don't assume lein.sh is executable - MELPA 
might change that
+                         (cider--get-enrich-classpath-lein-script)
+                         " "
+                         r)
+               r)))
     ('boot (cider--resolve-command cider-boot-command))
     ('clojure-cli (if (and cider-enrich-classpath
                            (not (eq system-type 'windows-nt))
                            (executable-find 
(cider--get-enrich-classpath-clojure-cli-script)))
                       (concat "bash " ;; don't assume clojure.sh is executable 
- MELPA might change that
-                              (executable-find 
(cider--get-enrich-classpath-clojure-cli-script))
+                              (cider--get-enrich-classpath-clojure-cli-script)
                               " "
                               (cider--resolve-command 
cider-clojure-cli-command))
                     (cider--resolve-command cider-clojure-cli-command)))
@@ -584,7 +598,7 @@ returned by this function does not include keyword 
arguments."
   (let ((plugins (if cider-enrich-classpath
                      (append cider-jack-in-lein-plugins
                              `(("cider/cider-nrepl" 
,cider-injected-middleware-version)
-                               ("mx.cider/lein-enrich-classpath" "1.15.4")))
+                               ("mx.cider/lein-enrich-classpath" "1.15.5")))
                    (append cider-jack-in-lein-plugins
                            `(("cider/cider-nrepl" 
,cider-injected-middleware-version))))))
     (thread-last
@@ -1588,43 +1602,6 @@ Params is a plist with the following keys 
(non-exhaustive)
 (defvar cider--jack-in-cmd-history nil
   "History list for user-specified jack-in commands.")
 
-(defun cider--expand-command-with-enrich-classpath (command fallback-cmd 
project-type)
-  "When possible for PROJECT-TYPE, expands COMMAND or fallback to FALLBACK-CMD.
-For example, `lein ... repl :headless ...' will be turned into a
-  `java -cp ...' invocation, which is the result of applying
-the enrich-classpath middleware."
-  (if (and cider-enrich-classpath
-           (eq project-type 'lein)
-           (not (eq system-type 'windows-nt)))
-      (let* ((_ (message (concat "CIDER enrich-classpath replacing: " 
(prin1-to-string command))))
-             (_ (shell-command-to-string "mkdir -p $HOME/.emacs.d"))
-             (logfile (expand-file-name "~/.emacs.d/cider-error.log"))
-             (result (thread-first
-                       command
-                       (concat " 2>" logfile)
-                       shell-command-to-string))
-             (enriched-command (thread-first
-                                 result
-                                 (split-string "\n")
-                                 (thread-last (seq-filter (lambda (s)
-                                                            ;; -cp is the 
marker that indicates that we've found a `java -cp` invocation (as emitted by 
enrich-classpath)
-                                                            (string-match " 
-cp " s))))
-                                 last
-                                 car)))
-        (if (not enriched-command)
-            (progn
-              (condition-case nil
-                  (progn
-                    (write-region "\n\nFull enrich-classpath output:\n\n" nil 
logfile 'append)
-                    (write-region result nil logfile 'append))
-                (error nil))
-              (message "CIDER enrich-classpath failed. Falling back to the 
original command. `~/.emacs.d/cider-error.log' may contain debug information.")
-              fallback-cmd)
-          (progn
-            (message (concat "CIDER enrich-classpath replaced: " 
(prin1-to-string enriched-command)))
-            enriched-command)))
-    command))
-
 (defun cider--format-cmd (command-resolved command cmd-params)
   "Format COMMAND-RESOLVED or COMMAND followed by CMD-PARAMS."
   (format "%s %s" command-resolved
@@ -1660,12 +1637,6 @@ PARAMS is a plist with the following keys 
(non-exhaustive list)
                                                       command-params
                                                       
'cider--jack-in-nrepl-params-history)
                                        command-params))
-                     ;; create a command without the Enrich plugin or 
middleware:
-                     (fallback-cmd-params (let ((cider-enrich-classpath nil))
-                                            (if 
cider-inject-dependencies-at-jack-in
-                                                
(cider-inject-jack-in-dependencies command-global-opts command-params
-                                                                               
    project-type command)
-                                              command-params)))
                      (cmd-params (if cider-inject-dependencies-at-jack-in
                                      (cider-inject-jack-in-dependencies 
command-global-opts command-params
                                                                         
project-type command)
@@ -1678,13 +1649,11 @@ PARAMS is a plist with the following keys 
(non-exhaustive list)
                                    (or params-project-type
                                        (y-or-n-p "Are you sure you want to run 
`cider-jack-in' without a Clojure project? "))))
                       (let* ((cmd          (cider--format-cmd command-resolved 
command cmd-params))
-                             (fallback-cmd (cider--format-cmd command-resolved 
command fallback-cmd-params))
                              (edited-command (if (or cider-edit-jack-in-command
                                                      (plist-get params 
:edit-jack-in-command))
                                                  (read-string "jack-in 
command: " cmd 'cider--jack-in-cmd-history)
-                                               cmd))
-                             (enriched-command 
(cider--expand-command-with-enrich-classpath edited-command fallback-cmd 
project-type)))
-                        (plist-put params :jack-in-cmd enriched-command)))
+                                               cmd)))
+                        (plist-put params :jack-in-cmd edited-command)))
                   (user-error "`cider-jack-in' is not allowed without a 
Clojure project"))))
           (user-error "The %s executable isn't on your `exec-path'" 
command))))))
 
diff --git a/clojure.sh b/clojure.sh
index ea6ffeb02a..7164a8d189 100755
--- a/clojure.sh
+++ b/clojure.sh
@@ -28,7 +28,7 @@ else
   cd "$there"
 
   # enrich-classpath will emit a command starting by "clojure", or print a 
stacktrace:
-  output=$(2>&1 "$clojure" -Sforce -Srepro -J-XX:-OmitStackTraceInFastThrow 
-J-Dclojure.main.report=stderr -Sdeps '{:deps 
{mx.cider/tools.deps.enrich-classpath {:mvn/version "1.15.4"}}}' -M -m 
cider.enrich-classpath.clojure "$clojure" "$here" "true" "$@")
+  output=$(2>&1 "$clojure" -Sforce -Srepro -J-XX:-OmitStackTraceInFastThrow 
-J-Dclojure.main.report=stderr -Sdeps '{:deps 
{mx.cider/tools.deps.enrich-classpath {:mvn/version "1.15.5"}}}' -M -m 
cider.enrich-classpath.clojure "$clojure" "$here" "true" "$@")
   cmd=$(tail -n1 <(echo "$output"))
 
   cd "$here"
diff --git a/lein.sh b/lein.sh
new file mode 100755
index 0000000000..811e1263f0
--- /dev/null
+++ b/lein.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env bash
+# there's no -Ee -o pipefail, intentionally
+
+# This wrapper script invokes lein with the provided args (which must include 
the enrich-classpath middleware),
+# detecting success, and invoking in return the generated `java` command.
+# It falls back to lein with the same args, except that the enrich middleware 
will be replaced with a no-op middleware.
+# By having all this logic as a .sh script (vs. inline in Elisp), we can keep 
using the same process/async machinery,
+# which is concise and results in a non-blocking UX.
+
+lein="$1"
+shift
+
+output=$(2>&1 "$lein" "$@")
+cmd=$(grep "\s-cp\s"<<< "$output")
+
+if grep --silent "\s-cp\s"<<< "$cmd"; then
+  eval "$cmd"
+else
+  # Print errors:
+  mkdir -p ~/.emacs.d
+  echo "$output" >> ~/.emacs.d/cider-error.log
+  no_enrich=()
+  for arg in "$@"; do
+    if [ "$arg" == "cider.enrich-classpath.plugin-v2/middleware" ]; then
+      no_enrich+=("cider.enrich-classpath.fallback/middleware")
+    else
+      no_enrich+=("$arg")
+    fi
+  done
+  $lein "${no_enrich[@]}"
+fi
diff --git a/test/cider-tests.el b/test/cider-tests.el
index c8163f78d0..6a46dbc2a1 100644
--- a/test/cider-tests.el
+++ b/test/cider-tests.el
@@ -156,7 +156,7 @@
                                 " -- update-in :plugins conj "
                                 (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                                 " -- update-in :plugins conj "
-                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                                 " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                                 " -- repl :headless")))
 
@@ -169,7 +169,7 @@
                          " -- update-in :plugins conj "
                          (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                          " -- update-in :plugins conj "
-                         (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                         (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                          " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                          " -- repl :headless")))
 
@@ -181,7 +181,7 @@
                                 " -- update-in :plugins conj "
                                 (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                                 " -- update-in :plugins conj "
-                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                                 " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                                 " -- repl :headless")))
 
@@ -220,7 +220,7 @@
                                 " -- update-in :plugins conj "
                                 (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                                 " -- update-in :plugins conj "
-                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                                 " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                                 " -- repl :headless")))
 
@@ -255,7 +255,7 @@
                                 " -- update-in :plugins conj "
                                 (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                                 " -- update-in :plugins conj "
-                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                                 " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                                 " -- repl :headless")))
     (it "can concat in a boot project"
@@ -324,7 +324,7 @@
       (spy-on 'cider-jack-in-normalized-lein-plugins
               :and-return-value '(("refactor-nrepl" "2.0.0")
                                   ("cider/cider-nrepl" "0.37.0")
-                                  ("mx.cider/lein-enrich-classpath" "1.15.4")))
+                                  ("mx.cider/lein-enrich-classpath" "1.15.5")))
       (setq-local cider-jack-in-dependencies-exclusions '())
       (setq-local cider-enrich-classpath t))
     (it "uses them in a lein project"
@@ -336,7 +336,7 @@
                                 " -- update-in :plugins conj "
                                 (shell-quote-argument "[cider/cider-nrepl 
\"0.37.0\"]")
                                 " -- update-in :plugins conj "
-                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.4\"]")
+                                (shell-quote-argument 
"[mx.cider/lein-enrich-classpath \"1.15.5\"]")
                                 " -- update-in :middleware conj 
cider.enrich-classpath.plugin-v2/middleware"
                                 " -- repl :headless"))))
 

Reply via email to