From 9e8c114b738ddc633b50ca48e828676b92be784f Mon Sep 17 00:00:00 2001 From: Bruno BARBIER Date: Sat, 18 Jun 2022 09:48:01 +0200 Subject: [PATCH] ob-shell: Use 'process-file' when stdin or cmdline lib/ob-shell.el (org-babel-sh-evaluate): Use 'process-file' (instead of 'call-process-shell-command') so that 'org-babel-sh-evaluate' will invoke file name handlers based on 'default-directory', if needed, like when using a remote directory. testing/lisp/test-ob-shell.el (ob-shell/remote-with-stdin-or-cmdline): New test. testing/org-test.el (org-test-tramp-remote-dir): New constant. --- lisp/ob-shell.el | 17 ++++++++---- testing/lisp/test-ob-shell.el | 52 +++++++++++++++++++++++++++++++++++ testing/org-test.el | 4 +++ 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el index 4454e3b5d..515095f9b 100644 --- a/lisp/ob-shell.el +++ b/lisp/ob-shell.el @@ -249,12 +249,17 @@ (defun org-babel-sh-evaluate (session body &optional params stdin cmdline) (set-file-modes script-file #o755) (with-temp-file stdin-file (insert (or stdin ""))) (with-temp-buffer - (call-process-shell-command - (concat (if shebang script-file - (format "%s %s" shell-file-name script-file)) - (and cmdline (concat " " cmdline))) - stdin-file - (current-buffer)) + (with-connection-local-variables + (apply #'process-file + (if shebang (file-local-name script-file) + shell-file-name) + stdin-file + (current-buffer) + nil + (if shebang (when cmdline (list cmdline)) + (list shell-command-switch + (concat (file-local-name script-file) " " cmdline))) + )) (buffer-string)))) (session ; session evaluation (mapconcat diff --git a/testing/lisp/test-ob-shell.el b/testing/lisp/test-ob-shell.el index 2f346f699..05ee810a0 100644 --- a/testing/lisp/test-ob-shell.el +++ b/testing/lisp/test-ob-shell.el @@ -106,6 +106,58 @@ (ert-deftest ob-shell/simple-list () "#+BEGIN_SRC sh :results output :var l='(1 2)\necho ${l}\n#+END_SRC" (org-trim (org-babel-execute-src-block)))))) +(ert-deftest ob-shell/remote-with-stdin-or-cmdline () + "Test :stdin and :cmdline with a remote directory." + ;; We assume 'default-directory' is a local directory. + (dolist (spec `( () + (:dir ,org-test-tramp-remote-dir) + (:dir ,org-test-tramp-remote-dir :cmdline t) + (:dir ,org-test-tramp-remote-dir :stdin t) + (:dir ,org-test-tramp-remote-dir :cmdline t :shebang t) + (:dir ,org-test-tramp-remote-dir :stdin t :shebang t) + (:dir ,org-test-tramp-remote-dir :cmdline t :stdin t :shebang t) + (:cmdline t) + (:stdin t) + (:cmdline t :shebang t) + (:stdin t :shebang t) + (:cmdline t :stdin t :shebang t) + )) + (let ((default-directory (or (plist-get :dir spec) default-directory)) + (org-confirm-babel-evaluate nil) + (params-line "") + (who-line " export who=tramp") + (args-line " echo ARGS: --verbose 23 71") + ) + (when-let ((dir (plist-get :dir spec))) + (setq params-line (concat params-line " " ":dir " dir))) + (when (plist-get :stdin spec) + (setq who-line " read -r who") + (setq params-line (concat params-line " :stdin input"))) + (when (plist-get :cmdline spec) + (setq args-line " echo \"ARGS: $*\"") + (setq params-line (concat params-line " :cmdline \"--verbose 23 71\""))) + (when (plist-get :shebang spec) + (setq params-line (concat params-line " :shebang \"#!/bin/sh\""))) + (let* ((result (org-test-with-temp-text + (mapconcat #'identity + (list "#+name: input" + "tramp" + "" + (concat "" + "#+begin_src sh :results output " params-line) + args-line + who-line + " echo \"hello $who from $(pwd)/\"" + "#+end_src") + "\n") + (org-trim (org-babel-execute-src-block)))) + (expected (concat "ARGS: --verbose 23 71" + "\nhello tramp from " (file-local-name default-directory))) + (correct (equal result expected)) + ) + (should (equal result expected)) + )))) + (provide 'test-ob-shell) ;;; test-ob-shell.el ends here diff --git a/testing/org-test.el b/testing/org-test.el index 0f1e254aa..7212544f6 100644 --- a/testing/org-test.el +++ b/testing/org-test.el @@ -96,6 +96,10 @@ (defconst org-test-link-in-heading-file (defconst org-id-locations-file (expand-file-name ".test-org-id-locations" org-test-dir)) +(defconst org-test-tramp-remote-dir "/mock::/tmp/" + "Remote tramp directory. +We really should use 'tramp-test-temporary-file-directory', but that would require TRAMP sources.") + ;;; Functions for writing tests (put 'missing-test-dependency -- 2.35.1