[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/cider 64819740ef 1/3: Always escape clojure cli command pa
|
From: |
ELPA Syncer |
|
Subject: |
[nongnu] elpa/cider 64819740ef 1/3: Always escape clojure cli command params on MS-win |
|
Date: |
Thu, 18 May 2023 02:00:11 -0400 (EDT) |
branch: elpa/cider
commit 64819740efc952ec3d44a0e6041dca6e8f122611
Author: ikappaki <ikappaki@users.noreply.github.com>
Commit: Bozhidar Batsov <bozhidar@batsov.dev>
Always escape clojure cli command params on MS-win
even for non powershell invocations
---
.github/workflows/test.yml | 7 ++
CHANGELOG.md | 4 +
cider.el | 79 ++++++++--------
test/integration/integration-tests.el | 165 ++++++++++++++++++----------------
4 files changed, 142 insertions(+), 113 deletions(-)
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index fb8701862b..8fd31cd774 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -43,6 +43,13 @@ jobs:
curl.exe -fsSL
https://raw.github.com/doublep/eldev/master/webinstall/github-eldev.bat | cmd /Q
+ - name: Install deps.clj on MS-Windows
+ if: startsWith (matrix.os, 'windows')
+ run: |
+ iwr -Uri
https://raw.githubusercontent.com/borkdude/deps.clj/master/install.ps1 -outfile
install_clojure.ps1
+ .\install_clojure.ps1
+ get-command deps.exe | split-path -parent | Out-File -FilePath
$env:GITHUB_PATH -Encoding utf8 -Append
+
- name: Check out the source code
uses: actions/checkout@v2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6bf84be361..cd971ccfbc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## master (unreleased)
+### Bugs
+
+- [#3341](https://github.com/clojure-emacs/cider/issues/3341): Escape
clojure-cli args on MS-Windows on non powershell invocations.
+
## 1.7.0 (2023-03-23)
### New features
diff --git a/cider.el b/cider.el
index 13518e13b7..bb39bd3b23 100644
--- a/cider.el
+++ b/cider.el
@@ -744,12 +744,19 @@ removed, LEIN-PLUGINS, LEIN-MIDDLEWARES and finally
PARAMS."
"Removes the duplicates in DEPS."
(cl-delete-duplicates deps :test 'equal))
-(defun cider-clojure-cli-jack-in-dependencies (global-options params
dependencies)
+(defun cider--powershell-encode-command (cmd-params)
+ "Base64 encode the powershell command and jack-in CMD-PARAMS for
clojure-cli."
+ (let* ((quoted-params (replace-regexp-in-string "\"" "\"\"" cmd-params))
+ (command (format "clojure %s" quoted-params))
+ (utf-16le-command (encode-coding-string command 'utf-16le)))
+ (format "-encodedCommand %s" (base64-encode-string utf-16le-command t))))
+
+(defun cider-clojure-cli-jack-in-dependencies (global-options params
dependencies command)
"Create Clojure tools.deps jack-in dependencies.
-Does so by concatenating DEPENDENCIES, PARAMS and GLOBAL-OPTIONS into a
suitable
-`clojure` invocation. The main is placed in an inline alias :cider/nrepl
-so that if your aliases contain any mains, the cider/nrepl one will be the
-one used."
+Does so by concatenating DEPENDENCIES, PARAMS and GLOBAL-OPTIONS into a
+suitable `clojure` invocation and quoting it based on COMMAND if necessary.
+The main is placed in an inline alias :cider/nrepl so that if your aliases
+contain any mains, the cider/nrepl one will be the one used."
(let* ((all-deps (thread-last
dependencies
(append (cider--jack-in-required-dependencies))
@@ -770,18 +777,26 @@ one used."
(apply-partially #'format "%s")
(cider-jack-in-normalized-nrepl-middlewares)
","))
- (main-opts (format "\"-m\" \"nrepl.cmdline\" \"--middleware\"
\"[%s]\"" middleware)))
- (format "%s-Sdeps '{:deps {%s} :aliases {:cider/nrepl {:main-opts [%s]}}}'
-M%s:cider/nrepl%s"
- ;; TODO: global-options are deprecated and should be removed in
CIDER 2.0
- (if global-options (format "%s " global-options) "")
- (string-join all-deps " ")
- main-opts
- (if cider-clojure-cli-aliases
- ;; remove exec-opts flags -A -M -T or -X from
cider-clojure-cli-aliases
- ;; concatenated with :cider/nrepl to ensure :cider/nrepl comes
last
- (format "%s" (replace-regexp-in-string "^-\\(A\\|M\\|T\\|X\\)"
"" cider-clojure-cli-aliases))
- "")
- (if params (format " %s" params) ""))))
+ (main-opts (format "\"-m\" \"nrepl.cmdline\" \"--middleware\"
\"[%s]\"" middleware))
+ (deps (format "%s-Sdeps '{:deps {%s} :aliases {:cider/nrepl
{:main-opts [%s]}}}' -M%s:cider/nrepl%s"
+ ;; TODO: global-options are deprecated and should be
removed in CIDER 2.0
+ (if global-options (format "%s " global-options) "")
+ (string-join all-deps " ")
+ main-opts
+ (if cider-clojure-cli-aliases
+ ;; remove exec-opts flags -A -M -T or -X from
cider-clojure-cli-aliases
+ ;; concatenated with :cider/nrepl to ensure
:cider/nrepl comes last
+ (format "%s" (replace-regexp-in-string
"^-\\(A\\|M\\|T\\|X\\)" "" cider-clojure-cli-aliases))
+ "")
+ (if params (format " %s" params) "")))
+ (quoted (if (eq system-type 'windows-nt)
+ (if (or (string-equal command "powershell")
+ (string-equal command "pwsh"))
+ (cider--powershell-encode-command deps)
+ (thread-last (replace-regexp-in-string "\"" "\"\"" deps)
+ (replace-regexp-in-string "'" "\"")))
+ deps)))
+ quoted))
(defun cider-shadow-cljs-jack-in-dependencies (global-opts params dependencies)
"Create shadow-cljs jack-in deps.
@@ -813,13 +828,13 @@ See also `cider-jack-in-auto-inject-clojure'."
dependencies))
dependencies))
-(defun cider-inject-jack-in-dependencies (global-opts params project-type)
+(defun cider-inject-jack-in-dependencies (global-opts params project-type
command)
"Return GLOBAL-OPTS and PARAMS with injected REPL dependencies.
-These are set in `cider-jack-in-dependencies', `cider-jack-in-lein-plugins' and
-`cider-jack-in-nrepl-middlewares' are injected from the CLI according to
-the used PROJECT-TYPE. Eliminates the need for hacking profiles.clj or the
-boot script for supporting CIDER with its nREPL middleware and
-dependencies."
+These are set in `cider-jack-in-dependencies', `cider-jack-in-lein-plugins'
+and `cider-jack-in-nrepl-middlewares' are injected from the CLI according
+to the used PROJECT-TYPE and COMMAND. Eliminates the need for hacking
+profiles.clj or the boot script for supporting CIDER with its nREPL
+middleware and dependencies."
(pcase project-type
('lein (cider-lein-jack-in-dependencies
global-opts
@@ -842,7 +857,8 @@ dependencies."
global-opts
params
(cider-add-clojure-dependencies-maybe
- cider-jack-in-dependencies)))
+ cider-jack-in-dependencies)
+ command))
('babashka (concat
global-opts
(unless (seq-empty-p global-opts) " ")
@@ -1510,13 +1526,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--powershell-encode-command (cmd-params)
- "Base64 encode the powershell command and jack-in CMD-PARAMS for
clojure-cli."
- (let* ((quoted-params (replace-regexp-in-string "\"" "\"\"" cmd-params))
- (command (format "clojure %s" quoted-params))
- (utf-16le-command (encode-coding-string command 'utf-16le)))
- (format "-encodedCommand %s" (base64-encode-string utf-16le-command t))))
-
(defun cider--update-jack-in-cmd (params)
"Update :jack-in-cmd key in PARAMS.
@@ -1546,7 +1555,8 @@ PARAMS is a plist with the following keys (non-exhaustive
list)
'cider--jack-in-nrepl-params-history)
command-params))
(cmd-params (if cider-inject-dependencies-at-jack-in
- (cider-inject-jack-in-dependencies
command-global-opts command-params project-type)
+ (cider-inject-jack-in-dependencies
command-global-opts command-params
+
project-type command)
command-params)))
(if (or project-dir cider-allow-jack-in-without-project)
(when (or project-dir
@@ -1555,10 +1565,7 @@ PARAMS is a plist with the following keys
(non-exhaustive list)
(eq cider-allow-jack-in-without-project
'warn)
(or params-project-type
(y-or-n-p "Are you sure you want to run
`cider-jack-in' without a Clojure project? "))))
- (let ((cmd (format "%s %s" command-resolved (if (or
(string-equal command "powershell")
-
(string-equal command "pwsh"))
-
(cider--powershell-encode-command cmd-params)
-
cmd-params))))
+ (let ((cmd (format "%s %s" command-resolved cmd-params)))
(plist-put params :jack-in-cmd (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)
diff --git a/test/integration/integration-tests.el
b/test/integration/integration-tests.el
index dd4907a86a..fe3c853a78 100644
--- a/test/integration/integration-tests.el
+++ b/test/integration/integration-tests.el
@@ -31,72 +31,11 @@
(require 'nrepl-tests-utils "test/utils/nrepl-tests-utils")
(require 'integration-test-utils)
-(describe "jack in"
- ;; For each project tool, create a project in a temp directory,
- ;; jack-in to it, send an eval command to the REPL server specific to the
- ;; project to ensure it works, and finally exit the REPL.
+(defun jack-in-clojure-cli-test (cli-command)
+ "Run clojure cli jack in test using given CLI-COMMAND.
- (it "to babashka"
- (with-cider-test-sandbox
- (with-temp-dir temp-dir
- ;; Create a project in temp dir
- (let* ((project-dir temp-dir)
- (bb-edn (expand-file-name "bb.edn" project-dir)))
- (write-region "{}" nil bb-edn)
-
- (with-temp-buffer
- ;; set default directory to temp project
- (setq-local default-directory project-dir)
-
- (let* (;; Get a gv reference so as to poll if the client has
- ;; connected to the nREPL server.
- (client-is-connected*
(cider-itu-nrepl-client-connected-ref-make!))
-
- ;; jack in and get repl buffer
- (nrepl-proc (cider-jack-in-clj '()))
- (nrepl-buf (process-buffer nrepl-proc)))
-
- ;; wait until the client has successfully connected to the
- ;; nREPL server.
- (cider-itu-poll-until (eq (gv-deref client-is-connected*)
'connected) 5)
-
- ;; give it some time to setup the clj REPL
- (cider-itu-poll-until (cider-repls 'clj nil) 5)
-
- ;; send command to the REPL, and push stdout/stderr to
- ;; corresponding eval-xxx variables.
- (let ((repl-buffer (cider-current-repl))
- (eval-err '())
- (eval-out '()))
- (expect repl-buffer :not :to-be nil)
-
- ;; send command to the REPL
- (cider-interactive-eval
- ;; ask REPL to return a string that uniquely identifies it.
- "(print :bb? (some? (System/getProperty
\"babashka.version\")))"
- (lambda (return)
- (nrepl-dbind-response
- return
- (out err)
- (when err (push err eval-err))
- (when out (push out eval-out)))) )
-
- ;; wait for a response to come back.
- (cider-itu-poll-until (or eval-err eval-out) 5)
-
- ;; ensure there are no errors and response is as expected.
- (expect eval-err :to-equal '())
- (expect eval-out :to-equal '(":bb? true"))
-
- ;; exit the REPL.
- (cider-quit repl-buffer)
-
- ;; wait for the REPL to exit
- (cider-itu-poll-until (not (eq (process-status nrepl-proc)
'run)) 5)
- (expect (member (process-status nrepl-proc) '(exit
signal))))))))))
-
- (it "to clojure tools cli"
- (with-cider-test-sandbox
+If CLI-COMMAND is nil, then use the default."
+ (with-cider-test-sandbox
(with-temp-dir temp-dir
;; Create a project in temp dir
(let* ((project-dir temp-dir)
@@ -109,6 +48,7 @@
;; than the default timeout period to complete.
(nrepl-sync-request-timeout 30)
+ (cider-clojure-cli-command (or cli-command
cider-clojure-cli-command))
(cider-jack-in-nrepl-middlewares
(append '("ikappaki.nrepl-mdlw-log/middleware")
cider-jack-in-nrepl-middlewares)))
@@ -177,15 +117,18 @@
(message ":ikappaki/nrepl-mdlw-log-dump\n%s\n"
(buffer-string)))
(message ":!nrepl-mdlw-log-found")))))))))
- (it "to leiningen"
+(describe "jack in"
+ ;; For each project tool, create a project in a temp directory,
+ ;; jack-in to it, send an eval command to the REPL server specific to the
+ ;; project to ensure it works, and finally exit the REPL.
+
+ (it "to babashka"
(with-cider-test-sandbox
(with-temp-dir temp-dir
;; Create a project in temp dir
(let* ((project-dir temp-dir)
- (project-clj (expand-file-name "project.clj" project-dir)))
- (write-region "(defproject cider/integration \"test\"
- :dependencies [[org.clojure/clojure \"1.10.3\"]])"
- nil project-clj)
+ (bb-edn (expand-file-name "bb.edn" project-dir)))
+ (write-region "{}" nil bb-edn)
(with-temp-buffer
;; set default directory to temp project
@@ -196,15 +139,15 @@
(client-is-connected*
(cider-itu-nrepl-client-connected-ref-make!))
;; jack in and get repl buffer
- (nrepl-proc (cider-jack-in-clj `()))
+ (nrepl-proc (cider-jack-in-clj '()))
(nrepl-buf (process-buffer nrepl-proc)))
;; wait until the client has successfully connected to the
;; nREPL server.
- (cider-itu-poll-until (eq (gv-deref client-is-connected*)
'connected) 90)
+ (cider-itu-poll-until (eq (gv-deref client-is-connected*)
'connected) 5)
;; give it some time to setup the clj REPL
- (cider-itu-poll-until (cider-repls 'clj nil) 90)
+ (cider-itu-poll-until (cider-repls 'clj nil) 5)
;; send command to the REPL, and push stdout/stderr to
;; corresponding eval-xxx variables.
@@ -216,7 +159,7 @@
;; send command to the REPL
(cider-interactive-eval
;; ask REPL to return a string that uniquely identifies it.
- "(print :clojure? (some? (clojure-version)))"
+ "(print :bb? (some? (System/getProperty
\"babashka.version\")))"
(lambda (return)
(nrepl-dbind-response
return
@@ -225,19 +168,87 @@
(when out (push out eval-out)))) )
;; wait for a response to come back.
- (cider-itu-poll-until (or eval-err eval-out) 10)
+ (cider-itu-poll-until (or eval-err eval-out) 5)
;; ensure there are no errors and response is as expected.
(expect eval-err :to-equal '())
- (expect eval-out :to-equal '(":clojure? true"))
+ (expect eval-out :to-equal '(":bb? true"))
;; exit the REPL.
(cider-quit repl-buffer)
;; wait for the REPL to exit
- (cider-itu-poll-until (not (eq (process-status nrepl-proc)
'run)) 15)
+ (cider-itu-poll-until (not (eq (process-status nrepl-proc)
'run)) 5)
(expect (member (process-status nrepl-proc) '(exit
signal))))))))))
+ (it "to clojure tools cli"
+ (jack-in-clojure-cli-test nil))
+
+ (when (eq system-type 'windows-nt)
+ (it "to clojure tools cli (alternative deps.exe)"
+ (jack-in-clojure-cli-test "deps.exe")))
+
+ (it "to leiningen"
+ (with-cider-test-sandbox
+ (with-temp-dir temp-dir
+ ;; Create a project in temp dir
+ (let* ((project-dir temp-dir)
+ (project-clj (expand-file-name "project.clj"
project-dir)))
+ (write-region "(defproject cider/integration \"test\"
+ :dependencies [[org.clojure/clojure \"1.10.3\"]])"
+ nil project-clj)
+
+ (with-temp-buffer
+ ;; set default directory to temp project
+ (setq-local default-directory project-dir)
+
+ (let* (;; Get a gv reference so as to poll if the
client has
+ ;; connected to the nREPL server.
+ (client-is-connected*
(cider-itu-nrepl-client-connected-ref-make!))
+
+ ;; jack in and get repl buffer
+ (nrepl-proc (cider-jack-in-clj `()))
+ (nrepl-buf (process-buffer nrepl-proc)))
+
+ ;; wait until the client has successfully connected
to the
+ ;; nREPL server.
+ (cider-itu-poll-until (eq (gv-deref
client-is-connected*) 'connected) 90)
+
+ ;; give it some time to setup the clj REPL
+ (cider-itu-poll-until (cider-repls 'clj nil) 90)
+
+ ;; send command to the REPL, and push stdout/stderr
to
+ ;; corresponding eval-xxx variables.
+ (let ((repl-buffer (cider-current-repl))
+ (eval-err '())
+ (eval-out '()))
+ (expect repl-buffer :not :to-be nil)
+
+ ;; send command to the REPL
+ (cider-interactive-eval
+ ;; ask REPL to return a string that uniquely
identifies it.
+ "(print :clojure? (some? (clojure-version)))"
+ (lambda (return)
+ (nrepl-dbind-response
+ return
+ (out err)
+ (when err (push err eval-err))
+ (when out (push out eval-out)))) )
+
+ ;; wait for a response to come back.
+ (cider-itu-poll-until (or eval-err eval-out) 10)
+
+ ;; ensure there are no errors and response is as
expected.
+ (expect eval-err :to-equal '())
+ (expect eval-out :to-equal '(":clojure? true"))
+
+ ;; exit the REPL.
+ (cider-quit repl-buffer)
+
+ ;; wait for the REPL to exit
+ (cider-itu-poll-until (not (eq (process-status
nrepl-proc) 'run)) 15)
+ (expect (member (process-status nrepl-proc) '(exit
signal))))))))))
+
(it "to nbb"
(with-cider-test-sandbox
(with-temp-dir temp-dir