Skip to content

Commit 2efe545

Browse files
committed
[draft] copy enrich script to remote; on failure: ignore enrich
1 parent ef87c71 commit 2efe545

File tree

4 files changed

+98
-35
lines changed

4 files changed

+98
-35
lines changed

cider-util.el

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,50 @@ Any other value is just returned."
515515
(mapcar #'cider--deep-vector-to-list x)
516516
x))
517517

518+
519+
;;; Files
520+
(defun cider--ensure-executable (file)
521+
(with-demoted-errors "Error trying to make file executable:\n %s"
522+
(when (or (file-executable-p file)
523+
(and (set-file-modes file "u+x")
524+
(file-executable-p file)))
525+
file)))
526+
527+
(defun cider--make-temp-name (file)
528+
(make-temp-name
529+
(concat ".cider__" (file-name-nondirectory file) "__")))
530+
531+
(defun cider--make-nearby-temp-copy (file)
532+
(with-demoted-errors "Failed to copy to temporary file:\n %s"
533+
(let ((new-file (file-name-concat (temporary-file-directory)
534+
(cider--make-temp-name file))))
535+
(copy-file file new-file :exists-ok nil nil :keep-permissions)
536+
new-file)))
537+
538+
(defun cider--inject-self-delete (bash-script)
539+
(with-demoted-errors "Failed to inject self-delete string:\n %s"
540+
(let (;; Don't create any temporary files.
541+
(remote-file-name-inhibit-locks t)
542+
(remote-file-name-inhibit-auto-save-visited t)
543+
(backup-inhibited t)
544+
(auto-save-default nil))
545+
(with-temp-buffer
546+
(insert-file-contents bash-script)
547+
;; inject after the first line, assuming it is the shebang
548+
(goto-char (point-min))
549+
(skip-chars-forward "^\n")
550+
(insert "\n")
551+
(insert (format
552+
"trap 'ARG=$?
553+
rm -v %s
554+
echo \"cider: Cleaned up temporary script after use.\"
555+
exit $ARG
556+
' EXIT"
557+
(file-local-name bash-script)))
558+
(write-file bash-script))
559+
bash-script)))
518560

561+
519562
;;; Help mode
520563

521564
;; Same as https://github.com/emacs-mirror/emacs/blob/86d083438dba60dc00e9e96414bf7e832720c05a/lisp/help-mode.el#L355

cider.el

Lines changed: 55 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -411,40 +411,59 @@ without interfering with classloaders."
411411
:package-version '(cider . "1.2.0")
412412
:safe #'booleanp)
413413

414-
(defun cider--get-enrich-classpath-lein-script ()
415-
"Returns the location of enrich-classpath's lein.sh wrapper script."
416-
(when-let ((cider-location (locate-library "cider.el" t)))
417-
(concat (file-name-directory cider-location)
418-
"lein.sh")))
419-
420-
(defun cider--get-enrich-classpath-clojure-cli-script ()
421-
"Returns the location of enrich-classpath's clojure.sh wrapper script."
422-
(when-let ((cider-location (locate-library "cider.el" t)))
423-
(concat (file-name-directory cider-location)
424-
"clojure.sh")))
414+
(defvar cider--enrich-classpath-script-names
415+
'((lein . "enrich_lein.sh")
416+
(clojure-cli . "enrich_clojure.sh")))
417+
418+
(defun cider--enriched-cmd-p (cmd)
419+
"Test if the shell-quoted CMD contains the name of an enrich-classpath script.
420+
Returns the local path to the script or nil."
421+
(let* ((script-names (map-values cider--enrich-classpath-script-names))
422+
(any-name (rx-to-string `(or ,@script-names)))
423+
(script (thread-last
424+
(split-string-shell-command cmd)
425+
(seq-filter (lambda (part) (string-match any-name part)))
426+
(seq-first))))
427+
(when script
428+
(shell-quote-argument script))))
429+
430+
(defun cider--get-enrich-classpath-script (project-type)
431+
"Get or create an executable enrich-classpath script for PROJECT-TYPE.
432+
If `default-directory' is remote, create a copy at
433+
'<remote-tempdir>/.cider__<script-name>__<random>' that deletes itself after
434+
use. The search for <remote-tempdir> is handled by tramp and falls back to
435+
`default-directory'. Returns nil if anything goes wrong."
436+
(when-let* ((cider-dir (file-name-directory (locate-library "cider.el" t)))
437+
(name (map-elt cider--enrich-classpath-script-names project-type))
438+
(location (concat cider-dir name))
439+
(script (cider--ensure-executable location)))
440+
(if (file-remote-p default-directory)
441+
(thread-first
442+
(cider--make-nearby-temp-copy script)
443+
(cider--ensure-executable)
444+
(cider--inject-self-delete))
445+
script)))
446+
447+
(defun cider--jack-in-resolve-command-enrich (project-type)
448+
"Conditionally wrap the command for PROJECT-TYPE with an enrich-classpath script.
449+
Resolves to the non-wrapped `cider-jack-in-command' if `cider-enrich-classpath' is nil or the
450+
wrapper-script can't be initialized."
451+
(when-let ((command (cider--resolve-command (cider-jack-in-command project-type))))
452+
(if-let ((wrapper-script (and cider-enrich-classpath
453+
(not (eq system-type 'windows-nt))
454+
(cider--get-enrich-classpath-script project-type))))
455+
(concat "bash "
456+
(shell-quote-argument (file-local-name wrapper-script)) " "
457+
command)
458+
command)))
425459

426460
(defun cider-jack-in-resolve-command (project-type)
427461
"Determine the resolved file path to `cider-jack-in-command'.
428462
Throws an error if PROJECT-TYPE is unknown."
429463
(pcase project-type
430-
('lein (let ((r (cider--resolve-command cider-lein-command)))
431-
(if (and cider-enrich-classpath
432-
(not (eq system-type 'windows-nt))
433-
(executable-find (cider--get-enrich-classpath-lein-script)))
434-
(concat "bash " ;; don't assume lein.sh is executable - MELPA might change that
435-
(cider--get-enrich-classpath-lein-script)
436-
" "
437-
r)
438-
r)))
464+
('lein (cider--jack-in-resolve-command-enrich 'lein))
439465
('boot (cider--resolve-command cider-boot-command))
440-
('clojure-cli (if (and cider-enrich-classpath
441-
(not (eq system-type 'windows-nt))
442-
(executable-find (cider--get-enrich-classpath-clojure-cli-script)))
443-
(concat "bash " ;; don't assume clojure.sh is executable - MELPA might change that
444-
(cider--get-enrich-classpath-clojure-cli-script)
445-
" "
446-
(cider--resolve-command cider-clojure-cli-command))
447-
(cider--resolve-command cider-clojure-cli-command)))
466+
('clojure-cli (cider--jack-in-resolve-command-enrich 'clojure-cli))
448467
('babashka (cider--resolve-command cider-babashka-command))
449468
;; here we have to account for the possibility that the command is either
450469
;; "npx shadow-cljs" or just "shadow-cljs"
@@ -1661,7 +1680,11 @@ PARAMS is a plist with the following keys (non-exhaustive list)
16611680
(command-resolved (cider-jack-in-resolve-command project-type))
16621681
;; TODO: global-options are deprecated and should be removed in CIDER 2.0
16631682
(command-global-opts (cider-jack-in-global-options project-type))
1664-
(command-params (cider-jack-in-params project-type)))
1683+
(command-params (cider-jack-in-params project-type))
1684+
;; ignore `cider-enrich-classpath' if the jack-in-command does not include
1685+
;; the neccessary wrapper script at this point
1686+
(cider-enrich-classpath (and cider-enrich-classpath
1687+
(cider--enriched-cmd-p command-resolved))))
16651688
(if command-resolved
16661689
(with-current-buffer (or (plist-get params :--context-buffer)
16671690
(current-buffer))
@@ -2114,13 +2137,10 @@ M-2 \\[cider-jack-in-universal]."
21142137
(cider-jack-in-clj arg))))
21152138

21162139

2117-
;; TODO: Implement a check for command presence over tramp
21182140
(defun cider--resolve-command (command)
2119-
"Find COMMAND in exec path (see variable `exec-path').
2120-
Return nil if not found. In case `default-directory' is non-local we
2121-
assume the command is available."
2122-
(when-let* ((command (or (and (file-remote-p default-directory) command)
2123-
(executable-find command)
2141+
"Find COMMAND in exec-path and shell-quote it.
2142+
Return nil if not found."
2143+
(when-let* ((command (or (executable-find command :remote)
21242144
(executable-find (concat command ".bat")))))
21252145
(shell-quote-argument command)))
21262146

File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)