* [BUG] ob-shell: cmdline and stdin broken when used with TRAMP @ 2022-06-10 18:42 Felix Freeman via General discussions about Org-mode. 2022-06-18 18:54 ` Bruno Barbier 0 siblings, 1 reply; 10+ messages in thread From: Felix Freeman via General discussions about Org-mode. @ 2022-06-10 18:42 UTC (permalink / raw) To: emacs-orgmode [-- Attachment #1.1: Type: text/plain, Size: 824 bytes --] When using TRAMP, ob-shell's :cmdline and :stdin header options are broken on org-babel. I've noticed that when those options are present, it takes other route on ob-shell.el, but I lack the proper background to fix or debug it further. Probably cmdline is more complicated to get working right, but stdin seems to do most things just fine (it creates the file within the remote part) but isn't able to read it when needed. I'm attaching: - A file to test the functionality: test-tramp.org - The backtrace: backtrace.el - Emacs generated "current state": current-state.el Emacs : GNU Emacs 28.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.33, cairo version 1.17.6) of 2022-04-27 Package: Org mode version 9.5.4 (release_9.5.4-521-g1105da.dirty @ /home/me/src/org-mode/lisp/) Felix Freeman [-- Attachment #2: test-tramp.org --] [-- Type: text/org, Size: 284 bytes --] #+name: input tramp * Works #+begin_src sh :stdin input read -r who echo "hello $who" #+end_src #+begin_src sh :dir /ssh:user@host: who=tramp echo "hello $who" #+end_src * Fails #+begin_src sh :dir /ssh:user@host: :stdin input read -r who echo "hello $who" #+end_src [-- Attachment #3: current-state.el --] [-- Type: text/x-emacs-lisp, Size: 10660 bytes --] (setq org-link-elisp-confirm-function 'yes-or-no-p org-bibtex-headline-format-function '(closure (org-id-locations org-agenda-search-view-always-boolean org-agenda-overriding-header t) (entry) (cdr (assq :title entry))) org-persist-after-read-hook '(org-element--cache-persist-after-read) org-export-before-parsing-hook '(org-attach-expand-links) org-cycle-tab-first-hook '(org-babel-hide-result-toggle-maybe org-babel-header-arg-expand) org-archive-hook '(org-attach-archive-delete-maybe) org-file-apps '(("\\.png\\'" . "setsid -w xdg-open %s") (auto-mode . emacs) (directory . emacs) ("\\.mm\\'" . default) ("\\.x?html?\\'" . default) ("\\.pdf\\'" . default)) org-cycle-hook '(org-cycle-hide-archived-subtrees org-cycle-show-empty-lines org-cycle-optimize-window-after-visibility-change) org-persist-before-read-hook '(org-element--cache-persist-before-read) org-mode-hook '((closure (org--rds reftex-docstruct-symbol org-element-greater-elements visual-fill-column-width org-clock-history org-agenda-current-date org-with-time org-defdecode org-def org-read-date-inactive org-ans2 org-ans1 org-columns-current-fmt-compiled org-clock-current-task org-clock-effort org-agenda-skip-function org-agenda-skip-comment-trees org-agenda-archives-mode org-end-time-was-given org-time-was-given org-log-note-extra org-log-note-purpose org-log-post-message org-last-inserted-timestamp org-last-changed-timestamp org-entry-property-inherited-from org-blocked-by-checkboxes org-state org-agenda-headline-snapshot-before-repeat org-agenda-buffer-name org-agenda-start-on-weekday org-agenda-buffer-tmp-name org-priority-regexp org-mode-abbrev-table org-mode-syntax-table org-element-use-cache org-element-cache-persistent buffer-face-mode-face org-tbl-menu org-org-menu org-struct-menu org-entities org-last-state org-id-track-globally org-clock-start-time texmathp-why remember-data-file org-agenda-tags-todo-honor-ignore-options iswitchb-temp-buflist align-mode-rules-list org-emphasis-alist org-emphasis-regexp-components org-export-registered-backends org-modules crm-separator org-babel-load-languages org-id-overriding-file-name org-indent-indentation-per-level org-element--timestamp-regexp org-element-cache-map-continue-from org-element-paragraph-separate org-agenda-buffer-name org-inlinetask-min-level t) nil (add-hook 'change-major-mode-hook 'org-fold-show-all 'append 'local) ) (closure (org-src-window-setup *this* org-babel-confirm-evaluate-answer-no org-babel-tangle-uncomment-comments org-src-preserve-indentation org-src-lang-modes org-edit-src-content-indentation org-babel-library-of-babel t) nil (add-hook 'change-major-mode-hook #'org-babel-show-result-all 'append 'local) ) org-babel-result-hide-spec org-babel-hide-all-hashes (closure (org-agenda-skip-regexp org-fold-core-style org-table1-hline-regexp org-table-tab-recognizes-table\.el org-table-dataline-regexp org-table-any-border-regexp org-agenda-restriction-lock-overlay org-agenda-overriding-restriction org-agenda-diary-file org-complex-heading-regexp t) nil (setq imenu-create-index-function 'org-imenu-get-tree)) org-setup) org-babel-load-languages '((emacs-lisp . t) (shell . t) (http . t)) org-confirm-shell-link-function 'yes-or-no-p outline-isearch-open-invisible-function 'outline-isearch-open-invisible org-agenda-before-write-hook '(org-agenda-add-entry-text) org-src-mode-hook '(org-src-babel-configure-edit-buffer org-src-mode-configure-edit-buffer) org-confirm-elisp-link-function 'yes-or-no-p org-speed-command-hook '(org-speed-command-activate org-babel-speed-command-activate) org-confirm-babel-evaluate nil org-fold-core-isearch-open-function 'org-fold--isearch-reveal org-persist-before-write-hook '(org-element--cache-persist-before-write) org-tab-first-hook '(org-babel-hide-result-toggle-maybe org-babel-header-arg-expand) org-link-shell-confirm-function 'yes-or-no-p org-babel-pre-tangle-hook '(save-buffer) org-agenda-loop-over-headlines-in-active-region nil org-occur-hook '(org-first-headline-recenter) org-metadown-hook '(org-babel-pop-to-session-maybe) org-link-parameters '(("attachment" :follow org-attach-follow :complete org-attach-complete-link) ("id" :follow org-id-open) ("eww" :follow org-eww-open :store org-eww-store-link) ("rmail" :follow org-rmail-open :store org-rmail-store-link) ("mhe" :follow org-mhe-open :store org-mhe-store-link) ("irc" :follow org-irc-visit :store org-irc-store-link :export org-irc-export) ("info" :follow org-info-open :export org-info-export :store org-info-store-link) ("gnus" :follow org-gnus-open :store org-gnus-store-link) ("docview" :follow org-docview-open :export org-docview-export :store org-docview-store-link) ("bibtex" :follow org-bibtex-open :store org-bibtex-store-link) ("bbdb" :follow org-bbdb-open :export org-bbdb-export :complete org-bbdb-complete-link :store org-bbdb-store-link) ("w3m" :store org-w3m-store-link) ("doi" :follow org-link-doi-open :export org-link-doi-export) ("treemacs" :store treemacs-store-org-link) ("file+sys") ("file+emacs") ("shell" :follow org-link--open-shell) ("news" :follow (closure ((scheme . "news") (--dolist-tail--) org-ts-regexp org-time-stamp-formats org-src-source-file-name org-outline-regexp-bol org-inhibit-startup org-id-link-to-org-use-id org-highlight-links org-comment-string org-agenda-buffer-name clean-buffer-list-kill-buffer-names t) (url arg) (browse-url (concat scheme ":" url) arg)) ) ("mailto" :follow (closure ((scheme . "mailto") (--dolist-tail--) org-ts-regexp org-time-stamp-formats org-src-source-file-name org-outline-regexp-bol org-inhibit-startup org-id-link-to-org-use-id org-highlight-links org-comment-string org-agenda-buffer-name clean-buffer-list-kill-buffer-names t) (url arg) (browse-url (concat scheme ":" url) arg)) ) ("https" :follow (closure ((scheme . "https") (--dolist-tail--) org-ts-regexp org-time-stamp-formats org-src-source-file-name org-outline-regexp-bol org-inhibit-startup org-id-link-to-org-use-id org-highlight-links org-comment-string org-agenda-buffer-name clean-buffer-list-kill-buffer-names t) (url arg) (browse-url (concat scheme ":" url) arg)) ) ("http" :follow (closure ((scheme . "http") (--dolist-tail--) org-ts-regexp org-time-stamp-formats org-src-source-file-name org-outline-regexp-bol org-inhibit-startup org-id-link-to-org-use-id org-highlight-links org-comment-string org-agenda-buffer-name clean-buffer-list-kill-buffer-names t) (url arg) (browse-url (concat scheme ":" url) arg)) ) ("ftp" :follow (closure ((scheme . "ftp") (--dolist-tail--) org-ts-regexp org-time-stamp-formats org-src-source-file-name org-outline-regexp-bol org-inhibit-startup org-id-link-to-org-use-id org-highlight-links org-comment-string org-agenda-buffer-name clean-buffer-list-kill-buffer-names t) (url arg) (browse-url (concat scheme ":" url) arg)) ) ("help" :follow org-link--open-help :store org-link--store-help) ("file" :complete org-link-complete-file) ("elisp" :follow org-link--open-elisp)) org-metaup-hook '(org-babel-load-in-session-maybe) org-src-lang-modes '(("http" . "ob-http") ("C" . c) ("C++" . c++) ("asymptote" . asy) ("bash" . sh) ("beamer" . latex) ("calc" . fundamental) ("cpp" . c++) ("ditaa" . artist) ("desktop" . conf-desktop) ("dot" . fundamental) ("elisp" . emacs-lisp) ("ocaml" . tuareg) ("screen" . shell-script) ("shell" . sh) ("sqlite" . sql) ("toml" . conf-toml)) ) [-- Attachment #4: backtrace.el --] [-- Type: text/x-emacs-lisp, Size: 32328 bytes --] Debugger entered--Lisp error: (file-missing "Opening process input file" "No such file or directory" "/ssh:root@coreboot.lxd:/tmp/sh-stdin-sTc4vy") call-process("sh" "/ssh:root@coreboot.lxd:/tmp/sh-stdin-sTc4vy" #<buffer *temp*> nil "-c" "sh /ssh:root@coreboot.lxd:/tmp/sh-script-dOOrGA") call-process-shell-command("sh /ssh:root@coreboot.lxd:/tmp/sh-script-dOOrGA" "/ssh:root@coreboot.lxd:/tmp/sh-stdin-sTc4vy" #<buffer *temp*>) (progn (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)) (buffer-string)) (unwind-protect (progn (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)) (buffer-string)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (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)) (buffer-string)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (let ((temp-buffer (generate-new-buffer " *temp*" t))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (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)) (buffer-string)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))) (let ((script-file (org-babel-temp-file "sh-script-")) (stdin-file (org-babel-temp-file "sh-stdin-")) (padline (not (string= "no" (cdr (assq :padline params)))))) (let ((temp-file script-file) (temp-buffer (generate-new-buffer " *temp file*" t))) (unwind-protect (prog1 (save-current-buffer (set-buffer temp-buffer) (if shebang (progn (insert shebang "\n"))) (if padline (progn (insert "\n"))) (insert body)) (save-current-buffer (set-buffer temp-buffer) (write-region nil nil temp-file nil 0))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (set-file-modes script-file 493) (let ((temp-file stdin-file) (temp-buffer (generate-new-buffer " *temp file*" t))) (unwind-protect (prog1 (save-current-buffer (set-buffer temp-buffer) (insert (or stdin ""))) (save-current-buffer (set-buffer temp-buffer) (write-region nil nil temp-file nil 0))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (let ((temp-buffer (generate-new-buffer " *temp*" t))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (call-process-shell-command (concat (if shebang script-file ...) (and cmdline ...)) stdin-file (current-buffer)) (buffer-string)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))) (cond ((or stdin cmdline) (let ((script-file (org-babel-temp-file "sh-script-")) (stdin-file (org-babel-temp-file "sh-stdin-")) (padline (not (string= "no" (cdr ...))))) (let ((temp-file script-file) (temp-buffer (generate-new-buffer " *temp file*" t))) (unwind-protect (prog1 (save-current-buffer (set-buffer temp-buffer) (if shebang ...) (if padline ...) (insert body)) (save-current-buffer (set-buffer temp-buffer) (write-region nil nil temp-file nil 0))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (set-file-modes script-file 493) (let ((temp-file stdin-file) (temp-buffer (generate-new-buffer " *temp file*" t))) (unwind-protect (prog1 (save-current-buffer (set-buffer temp-buffer) (insert ...)) (save-current-buffer (set-buffer temp-buffer) (write-region nil nil temp-file nil 0))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (let ((temp-buffer (generate-new-buffer " *temp*" t))) (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (call-process-shell-command ... stdin-file ...) (buffer-string)) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))))) (session (mapconcat #'org-babel-sh-strip-weird-long-prompt (mapcar #'org-trim (butlast (progn (if (org-babel-comint-buffer-livep session) nil (error "Buffer %s does not exist or has no process" session)) (let (...) (unwind-protect ... ...))) 2)) "\n")) ((org-string-nw-p shebang) (let ((script-file (org-babel-temp-file "sh-script-")) (padline (not (equal "no" (cdr ...))))) (let ((temp-file script-file) (temp-buffer (generate-new-buffer " *temp file*" t))) (unwind-protect (prog1 (save-current-buffer (set-buffer temp-buffer) (insert shebang "\n") (if padline ...) (insert body)) (save-current-buffer (set-buffer temp-buffer) (write-region nil nil temp-file nil 0))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))) (set-file-modes script-file 493) (org-babel-eval script-file ""))) (t (org-babel-eval shell-file-name (org-trim body)))) (let* ((shebang (cdr (assq :shebang params))) (results-params (cdr (assq :result-params params))) (value-is-exit-status (or (and (equal '("replace") results-params) (not org-babel-shell-results-defaults-to-output)) (member "value" results-params))) (results (cond ((or stdin cmdline) (let ((script-file ...) (stdin-file ...) (padline ...)) (let (... ...) (unwind-protect ... ...)) (set-file-modes script-file 493) (let (... ...) (unwind-protect ... ...)) (let (...) (save-current-buffer ... ...)))) (session (mapconcat #'org-babel-sh-strip-weird-long-prompt (mapcar #'org-trim (butlast ... 2)) "\n")) ((org-string-nw-p shebang) (let ((script-file ...) (padline ...)) (let (... ...) (unwind-protect ... ...)) (set-file-modes script-file 493) (org-babel-eval script-file ""))) (t (org-babel-eval shell-file-name (org-trim body)))))) (if value-is-exit-status (progn (setq results (car (reverse (split-string results "\n" t)))))) (if results (progn (let ((result-params (cdr (assq :result-params params)))) (let ((--params result-params)) (if (member "none" --params) nil (if (or ... ... ... ... ... ... ...) results (let ... ... ...)))))))) org-babel-sh-evaluate(nil "read -r who\necho \"hello $who\"" ((:colname-names) (:rowname-names) (:result-params "replace") (:result-type . value) (:results . "replace") (:exports . "code") (:session . "none") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no") (:dir . "/ssh:root@coreboot.lxd:") (:stdin . "input")) "tramp\n" nil) (org-babel-reassemble-table (org-babel-sh-evaluate session full-body params stdin cmdline) (org-babel-pick-name (cdr (assq :colname-names params)) (cdr (assq :colnames params))) (org-babel-pick-name (cdr (assq :rowname-names params)) (cdr (assq :rownames params)))) (let* ((session (org-babel-sh-initiate-session (cdr (assq :session params)))) (stdin (let ((stdin (cdr (assq :stdin params)))) (if stdin (progn (org-babel-sh-var-to-string (org-babel-ref-resolve stdin)))))) (results-params (cdr (assq :result-params params))) (value-is-exit-status (or (and (equal '("replace") results-params) (not org-babel-shell-results-defaults-to-output)) (member "value" results-params))) (cmdline (cdr (assq :cmdline params))) (full-body (concat (org-babel-expand-body:generic body params (org-babel-variable-assignments:shell params)) (if value-is-exit-status (progn "\necho $?"))))) (org-babel-reassemble-table (org-babel-sh-evaluate session full-body params stdin cmdline) (org-babel-pick-name (cdr (assq :colname-names params)) (cdr (assq :colnames params))) (org-babel-pick-name (cdr (assq :rowname-names params)) (cdr (assq :rownames params))))) org-babel-execute:shell("read -r who\necho \"hello $who\"" ((:colname-names) (:rowname-names) (:result-params "replace") (:result-type . value) (:results . "replace") (:exports . "code") (:session . "none") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no") (:dir . "/ssh:root@coreboot.lxd:") (:stdin . "input"))) (let ((shell-file-name "sh")) (org-babel-execute:shell body params)) org-babel-execute:sh("read -r who\necho \"hello $who\"" ((:colname-names) (:rowname-names) (:result-params "replace") (:result-type . value) (:results . "replace") (:exports . "code") (:session . "none") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no") (:dir . "/ssh:root@coreboot.lxd:") (:stdin . "input"))) funcall(org-babel-execute:sh "read -r who\necho \"hello $who\"" ((:colname-names) (:rowname-names) (:result-params "replace") (:result-type . value) (:results . "replace") (:exports . "code") (:session . "none") (:cache . "no") (:noweb . "no") (:hlines . "no") (:tangle . "no") (:dir . "/ssh:root@coreboot.lxd:") (:stdin . "input"))) (let ((r (funcall cmd body params))) (if (and (eq (cdr (assq :result-type params)) 'value) (or (member "vector" result-params) (member "table" result-params)) (not (listp r))) (list (list r)) r)) (setq result (let ((r (funcall cmd body params))) (if (and (eq (cdr (assq :result-type params)) 'value) (or (member "vector" result-params) (member "table" result-params)) (not (listp r))) (list (list r)) r))) (if (member "none" result-params) (progn (funcall cmd body params) (message "result silenced")) (setq result (let ((r (funcall cmd body params))) (if (and (eq (cdr (assq :result-type params)) 'value) (or (member "vector" result-params) (member "table" result-params)) (not (listp r))) (list (list r)) r))) (let ((file (and (member "file" result-params) (cdr (assq :file params))))) (if file (progn (if (and result (not (or ... ...))) (progn (let (... ...) (unwind-protect ... ...)) (if (assq :file-mode params) (progn ...)))) (setq result file))) (let ((post (cdr (assq :post params)))) (if post (progn (let ((*this* ...)) (setq result (org-babel-ref-resolve post)) (if file (progn ...)))))) (org-babel-insert-result result result-params info new-hash lang))) (let* ((lang (nth 0 info)) (result-params (cdr (assq :result-params params))) (body (org-babel--expand-body info)) (dir (cdr (assq :dir params))) (mkdirp (cdr (assq :mkdirp params))) (default-directory (cond ((not dir) default-directory) ((member mkdirp '("no" "nil" nil)) (file-name-as-directory (expand-file-name dir))) (t (let ((d ...)) (make-directory d 'parents) d)))) (cmd (intern (concat "org-babel-execute:" lang))) result) (if (fboundp cmd) nil (error "No org-babel-execute function for %s!" lang)) (message "executing %s code block%s..." (capitalize lang) (let ((name (nth 4 info))) (if name (format " (%s)" name) ""))) (if (member "none" result-params) (progn (funcall cmd body params) (message "result silenced")) (setq result (let ((r (funcall cmd body params))) (if (and (eq (cdr ...) 'value) (or (member "vector" result-params) (member "table" result-params)) (not (listp r))) (list (list r)) r))) (let ((file (and (member "file" result-params) (cdr (assq :file params))))) (if file (progn (if (and result (not ...)) (progn (let ... ...) (if ... ...))) (setq result file))) (let ((post (cdr (assq :post params)))) (if post (progn (let (...) (setq result ...) (if file ...))))) (org-babel-insert-result result result-params info new-hash lang))) (run-hooks 'org-babel-after-execute-hook) result) (cond (current-cache (save-excursion (goto-char (org-babel-where-is-src-block-result nil info)) (forward-line) (skip-chars-forward " \11") (let ((result (org-babel-read-result))) (message (replace-regexp-in-string "%" "%%" (format "%S" result))) result))) ((org-babel-confirm-evaluate info) (let* ((lang (nth 0 info)) (result-params (cdr (assq :result-params params))) (body (org-babel--expand-body info)) (dir (cdr (assq :dir params))) (mkdirp (cdr (assq :mkdirp params))) (default-directory (cond ((not dir) default-directory) ((member mkdirp ...) (file-name-as-directory ...)) (t (let ... ... d)))) (cmd (intern (concat "org-babel-execute:" lang))) result) (if (fboundp cmd) nil (error "No org-babel-execute function for %s!" lang)) (message "executing %s code block%s..." (capitalize lang) (let ((name (nth 4 info))) (if name (format " (%s)" name) ""))) (if (member "none" result-params) (progn (funcall cmd body params) (message "result silenced")) (setq result (let ((r ...)) (if (and ... ... ...) (list ...) r))) (let ((file (and ... ...))) (if file (progn (if ... ...) (setq result file))) (let ((post ...)) (if post (progn ...))) (org-babel-insert-result result result-params info new-hash lang))) (run-hooks 'org-babel-after-execute-hook) result))) (let* ((params (nth 2 info)) (cache (let ((c (cdr (assq :cache params)))) (and (not arg) c (string= "yes" c)))) (new-hash (and cache (org-babel-sha1-hash info :eval))) (old-hash (and cache (org-babel-current-result-hash))) (current-cache (and new-hash (equal new-hash old-hash)))) (cond (current-cache (save-excursion (goto-char (org-babel-where-is-src-block-result nil info)) (forward-line) (skip-chars-forward " \11") (let ((result (org-babel-read-result))) (message (replace-regexp-in-string "%" "%%" (format "%S" result))) result))) ((org-babel-confirm-evaluate info) (let* ((lang (nth 0 info)) (result-params (cdr (assq :result-params params))) (body (org-babel--expand-body info)) (dir (cdr (assq :dir params))) (mkdirp (cdr (assq :mkdirp params))) (default-directory (cond (... default-directory) (... ...) (t ...))) (cmd (intern (concat "org-babel-execute:" lang))) result) (if (fboundp cmd) nil (error "No org-babel-execute function for %s!" lang)) (message "executing %s code block%s..." (capitalize lang) (let ((name ...)) (if name (format " (%s)" name) ""))) (if (member "none" result-params) (progn (funcall cmd body params) (message "result silenced")) (setq result (let (...) (if ... ... r))) (let ((file ...)) (if file (progn ... ...)) (let (...) (if post ...)) (org-babel-insert-result result result-params info new-hash lang))) (run-hooks 'org-babel-after-execute-hook) result)))) (progn (let* ((c (nthcdr 2 info))) (setcar c (org-babel-process-params (car c)))) (let* ((params (nth 2 info)) (cache (let ((c (cdr ...))) (and (not arg) c (string= "yes" c)))) (new-hash (and cache (org-babel-sha1-hash info :eval))) (old-hash (and cache (org-babel-current-result-hash))) (current-cache (and new-hash (equal new-hash old-hash)))) (cond (current-cache (save-excursion (goto-char (org-babel-where-is-src-block-result nil info)) (forward-line) (skip-chars-forward " \11") (let ((result ...)) (message (replace-regexp-in-string "%" "%%" ...)) result))) ((org-babel-confirm-evaluate info) (let* ((lang (nth 0 info)) (result-params (cdr ...)) (body (org-babel--expand-body info)) (dir (cdr ...)) (mkdirp (cdr ...)) (default-directory (cond ... ... ...)) (cmd (intern ...)) result) (if (fboundp cmd) nil (error "No org-babel-execute function for %s!" lang)) (message "executing %s code block%s..." (capitalize lang) (let (...) (if name ... ""))) (if (member "none" result-params) (progn (funcall cmd body params) (message "result silenced")) (setq result (let ... ...)) (let (...) (if file ...) (let ... ...) (org-babel-insert-result result result-params info new-hash lang))) (run-hooks 'org-babel-after-execute-hook) result))))) (if (org-babel-check-evaluate info) (progn (let* ((c (nthcdr 2 info))) (setcar c (org-babel-process-params (car c)))) (let* ((params (nth 2 info)) (cache (let ((c ...)) (and (not arg) c (string= "yes" c)))) (new-hash (and cache (org-babel-sha1-hash info :eval))) (old-hash (and cache (org-babel-current-result-hash))) (current-cache (and new-hash (equal new-hash old-hash)))) (cond (current-cache (save-excursion (goto-char (org-babel-where-is-src-block-result nil info)) (forward-line) (skip-chars-forward " \11") (let (...) (message ...) result))) ((org-babel-confirm-evaluate info) (let* ((lang ...) (result-params ...) (body ...) (dir ...) (mkdirp ...) (default-directory ...) (cmd ...) result) (if (fboundp cmd) nil (error "No org-babel-execute function for %s!" lang)) (message "executing %s code block%s..." (capitalize lang) (let ... ...)) (if (member "none" result-params) (progn ... ...) (setq result ...) (let ... ... ... ...)) (run-hooks 'org-babel-after-execute-hook) result)))))) (let* ((org-babel-current-src-block-location (or org-babel-current-src-block-location (nth 5 info) (org-babel-where-is-src-block-head))) (info (if info (copy-tree info) (org-babel-get-src-block-info)))) (let* ((c (nthcdr 2 info))) (setcar c (org-babel-merge-params (car c) params))) (if (org-babel-check-evaluate info) (progn (let* ((c (nthcdr 2 info))) (setcar c (org-babel-process-params (car c)))) (let* ((params (nth 2 info)) (cache (let (...) (and ... c ...))) (new-hash (and cache (org-babel-sha1-hash info :eval))) (old-hash (and cache (org-babel-current-result-hash))) (current-cache (and new-hash (equal new-hash old-hash)))) (cond (current-cache (save-excursion (goto-char ...) (forward-line) (skip-chars-forward " \11") (let ... ... result))) ((org-babel-confirm-evaluate info) (let* (... ... ... ... ... ... ... result) (if ... nil ...) (message "executing %s code block%s..." ... ...) (if ... ... ... ...) (run-hooks ...) result))))))) org-babel-execute-src-block(nil ("sh" "read -r who\necho \"hello $who\"" ((:colname-names) (:rowname-names) (:result-params "replace") (:result-type . value) (:results . "replace") (:exports . "code") (:stdin . "input") (:dir . "/ssh:root@coreboot.lxd:") (:tangle . "no") (:hlines . "no") (:noweb . "no") (:cache . "no") (:session . "none")) "" nil 234 "(ref:%s)")) (if org-babel-no-eval-on-ctrl-c-ctrl-c nil (org-babel-eval-wipe-error-buffer) (org-babel-execute-src-block current-prefix-arg (org-babel-get-src-block-info nil context))) (let nil (if org-babel-no-eval-on-ctrl-c-ctrl-c nil (org-babel-eval-wipe-error-buffer) (org-babel-execute-src-block current-prefix-arg (org-babel-get-src-block-info nil context)))) (cond ((memq type '(src-block inline-src-block)) (let nil (if org-babel-no-eval-on-ctrl-c-ctrl-c nil (org-babel-eval-wipe-error-buffer) (org-babel-execute-src-block current-prefix-arg (org-babel-get-src-block-info nil context))))) ((org-match-line "[ \11]*$") (let nil (or (run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) (user-error (substitute-command-keys "`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))) ((memq type '(inline-babel-call babel-call)) (let nil (let ((info (org-babel-lob-get-info context))) (if info (progn (org-babel-execute-src-block nil info)))))) ((eq type 'clock) (let nil (org-clock-update-time-maybe))) ((eq type 'dynamic-block) (let nil (save-excursion (goto-char (org-element-property :post-affiliated context)) (org-update-dblock)))) ((eq type 'footnote-definition) (let nil (goto-char (org-element-property :post-affiliated context)) (call-interactively 'org-footnote-action))) ((eq type 'footnote-reference) (let nil (call-interactively #'org-footnote-action))) ((memq type '(inlinetask headline)) (let nil (save-excursion (goto-char (org-element-property :begin context)) (call-interactively #'org-set-tags-command)))) ((eq type 'item) (let nil (if (or radio-list-p (and (boundp org-list-checkbox-radio-mode) org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* ((box (org-element-property :checkbox context)) (struct (org-element-property :structure context)) (old-struct (copy-tree struct)) (parents (org-list-parents-alist struct)) (prevs (org-list-prevs-alist struct)) (orderedp (org-not-nil ...))) (org-list-set-checkbox (org-element-property :begin context) struct (cond (... "[-]") (... "[ ]") (... nil) (... "[ ]") (t "[X]"))) (org-list-struct-fix-ind struct parents 2) (org-list-struct-fix-item-end struct) (org-list-struct-fix-bul struct prevs) (org-list-struct-fix-ind struct parents) (let ((block-item ...)) (if (and box ...) (if ... ... ...) (org-list-struct-apply-struct struct old-struct) (org-update-checkbox-count-maybe)) (if block-item (progn ...))))))) ((eq type 'plain-list) (let nil (if (or radio-list-p (and (boundp org-list-checkbox-radio-mode) org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* ((begin (org-element-property :contents-begin context)) (struct (org-element-property :structure context)) (old-struct (copy-tree struct)) (first-box (save-excursion ... ... ...)) (new-box (cond ... ... ... ...))) (cond (arg (let ... ...)) ((and first-box ...) (org-list-set-checkbox begin struct new-box))) (if (equal (org-list-write-struct struct ... old-struct) old-struct) (progn (message "Cannot update this checkbox"))) (org-update-checkbox-count-maybe))))) ((eq type 'keyword) (let nil (let ((org-inhibit-startup-visibility-stuff t) (org-startup-align-all-tables nil)) (if (boundp 'org-table-coordinate-overlays) (progn (mapc #'delete-overlay org-table-coordinate-overlays) (setq org-table-coordinate-overlays nil))) (if (eq org-fold-core-style 'text-properties) (let* ((--specs ...) (--markers\? ...) (--data ...)) (unwind-protect (progn ...) (save-excursion ...))) (let* ((--invisible-types ...) (--markers\? ...) (--data ...)) (unwind-protect (progn ...) (save-excursion ...))))) (message "Local setup has been refreshed"))) ((memq type '(node-property property-drawer)) (let nil (call-interactively #'org-property-action))) ((eq type 'radio-target) (let nil (call-interactively #'org-update-radio-target-regexp))) ((eq type 'statistics-cookie) (let nil (call-interactively #'org-update-statistics-cookies))) ((memq type '(table-row table-cell table)) (let nil (cond ((and (org-match-line "[ \11]*#\\+plot:") (< (point) (org-element-property :post-affiliated context))) (org-plot/gnuplot)) ((eq (org-element-property :type context) 'table\.el) (message "%s" (substitute-command-keys "\\<org-mode-map>Use `\\[org-edit-special]' to edit t..."))) ((or (eq type 'table) (and (eq type ...) (= ... ...))) (save-excursion (if (org-at-TBLFM-p) (progn ... ...) (goto-char ...) (org-call-with-arg ... ...) (orgtbl-send-table ...)))) (t (org-table-maybe-eval-formula) (cond (arg (call-interactively ...)) ((org-table-maybe-recalculate-line)) (t (org-table-align))))))) ((eq type 'timestamp) (funcall pcase-1)) ((eq type 'planning) (cond ((org-at-timestamp-p 'lax) (funcall pcase-1)) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((null type) (cond ((org-at-heading-p) (let nil (call-interactively #'org-set-tags-command))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0))) (let* ((pcase-1 #'(lambda nil (org-timestamp-change 0 'day))) (pcase-0 #'(lambda nil (user-error (substitute-command-keys "`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))) (cond ((memq type '(src-block inline-src-block)) (let nil (if org-babel-no-eval-on-ctrl-c-ctrl-c nil (org-babel-eval-wipe-error-buffer) (org-babel-execute-src-block current-prefix-arg (org-babel-get-src-block-info nil context))))) ((org-match-line "[ \11]*$") (let nil (or (run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) (user-error (substitute-command-keys "`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))) ((memq type '(inline-babel-call babel-call)) (let nil (let ((info (org-babel-lob-get-info context))) (if info (progn (org-babel-execute-src-block nil info)))))) ((eq type 'clock) (let nil (org-clock-update-time-maybe))) ((eq type 'dynamic-block) (let nil (save-excursion (goto-char (org-element-property :post-affiliated context)) (org-update-dblock)))) ((eq type 'footnote-definition) (let nil (goto-char (org-element-property :post-affiliated context)) (call-interactively 'org-footnote-action))) ((eq type 'footnote-reference) (let nil (call-interactively #'org-footnote-action))) ((memq type '(inlinetask headline)) (let nil (save-excursion (goto-char (org-element-property :begin context)) (call-interactively #'org-set-tags-command)))) ((eq type 'item) (let nil (if (or radio-list-p (and (boundp org-list-checkbox-radio-mode) org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* ((box ...) (struct ...) (old-struct ...) (parents ...) (prevs ...) (orderedp ...)) (org-list-set-checkbox (org-element-property :begin context) struct (cond ... ... ... ... ...)) (org-list-struct-fix-ind struct parents 2) (org-list-struct-fix-item-end struct) (org-list-struct-fix-bul struct prevs) (org-list-struct-fix-ind struct parents) (let (...) (if ... ... ... ...) (if block-item ...)))))) ((eq type 'plain-list) (let nil (if (or radio-list-p (and (boundp org-list-checkbox-radio-mode) org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* ((begin ...) (struct ...) (old-struct ...) (first-box ...) (new-box ...)) (cond (arg ...) (... ...)) (if (equal ... old-struct) (progn ...)) (org-update-checkbox-count-maybe))))) ((eq type 'keyword) (let nil (let ((org-inhibit-startup-visibility-stuff t) (org-startup-align-all-tables nil)) (if (boundp 'org-table-coordinate-overlays) (progn (mapc ... org-table-coordinate-overlays) (setq org-table-coordinate-overlays nil))) (if (eq org-fold-core-style 'text-properties) (let* (... ... ...) (unwind-protect ... ...)) (let* (... ... ...) (unwind-protect ... ...)))) (message "Local setup has been refreshed"))) ((memq type '(node-property property-drawer)) (let nil (call-interactively #'org-property-action))) ((eq type 'radio-target) (let nil (call-interactively #'org-update-radio-target-regexp))) ((eq type 'statistics-cookie) (let nil (call-interactively #'org-update-statistics-cookies))) ((memq type '(table-row table-cell table)) (let nil (cond ((and (org-match-line "[ \11]*#\\+plot:") (< ... ...)) (org-plot/gnuplot)) ((eq (org-element-property :type context) 'table\.el) (message "%s" (substitute-command-keys "\\<org-mode-map>Use `\\[org-edit-special]' to edit t..."))) ((or (eq type ...) (and ... ...)) (save-excursion (if ... ... ... ... ...))) (t (org-table-maybe-eval-formula) (cond (arg ...) (...) (t ...)))))) ((eq type 'timestamp) (funcall pcase-1)) ((eq type 'planning) (cond ((org-at-timestamp-p 'lax) (funcall pcase-1)) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((null type) (cond ((org-at-heading-p) (let nil (call-interactively #'org-set-tags-command))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) (let* ((context (org-element-lineage (org-element-context) '(babel-call clock dynamic-block footnote-definition footnote-reference inline-babel-call inline-src-block inlinetask item keyword node-property paragraph plain-list planning property-drawer radio-target src-block statistics-cookie table table-cell table-row timestamp) t)) (radio-list-p (org-at-radio-list-p)) (type (org-element-type context))) (if (eq type 'paragraph) (progn (let ((parent (org-element-property :parent context))) (if (and (eq (org-element-type parent) 'item) (= (line-beginning-position) (org-element-property :begin parent))) (progn (setq context parent) (setq type 'item)))))) (let* ((pcase-1 #'(lambda nil (org-timestamp-change 0 'day))) (pcase-0 #'(lambda nil (user-error (substitute-command-keys "`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))) (cond ((memq type '(src-block inline-src-block)) (let nil (if org-babel-no-eval-on-ctrl-c-ctrl-c nil (org-babel-eval-wipe-error-buffer) (org-babel-execute-src-block current-prefix-arg (org-babel-get-src-block-info nil context))))) ((org-match-line "[ \11]*$") (let nil (or (run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) (user-error (substitute-command-keys "`\\[org-ctrl-c-ctrl-c]' can do nothing useful here"))))) ((memq type '(inline-babel-call babel-call)) (let nil (let ((info ...)) (if info (progn ...))))) ((eq type 'clock) (let nil (org-clock-update-time-maybe))) ((eq type 'dynamic-block) (let nil (save-excursion (goto-char (org-element-property :post-affiliated context)) (org-update-dblock)))) ((eq type 'footnote-definition) (let nil (goto-char (org-element-property :post-affiliated context)) (call-interactively 'org-footnote-action))) ((eq type 'footnote-reference) (let nil (call-interactively #'org-footnote-action))) ((memq type '(inlinetask headline)) (let nil (save-excursion (goto-char (org-element-property :begin context)) (call-interactively #'org-set-tags-command)))) ((eq type 'item) (let nil (if (or radio-list-p (and ... org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* (... ... ... ... ... ...) (org-list-set-checkbox ... struct ...) (org-list-struct-fix-ind struct parents 2) (org-list-struct-fix-item-end struct) (org-list-struct-fix-bul struct prevs) (org-list-struct-fix-ind struct parents) (let ... ... ...))))) ((eq type 'plain-list) (let nil (if (or radio-list-p (and ... org-list-checkbox-radio-mode)) (org-toggle-radio-button arg) (let* (... ... ... ... ...) (cond ... ...) (if ... ...) (org-update-checkbox-count-maybe))))) ((eq type 'keyword) (let nil (let ((org-inhibit-startup-visibility-stuff t) (org-startup-align-all-tables nil)) (if (boundp ...) (progn ... ...)) (if (eq org-fold-core-style ...) (let* ... ...) (let* ... ...))) (message "Local setup has been refreshed"))) ((memq type '(node-property property-drawer)) (let nil (call-interactively #'org-property-action))) ((eq type 'radio-target) (let nil (call-interactively #'org-update-radio-target-regexp))) ((eq type 'statistics-cookie) (let nil (call-interactively #'org-update-statistics-cookies))) ((memq type '(table-row table-cell table)) (let nil (cond ((and ... ...) (org-plot/gnuplot)) ((eq ... ...) (message "%s" ...)) ((or ... ...) (save-excursion ...)) (t (org-table-maybe-eval-formula) (cond ... ... ...))))) ((eq type 'timestamp) (funcall pcase-1)) ((eq type 'planning) (cond ((org-at-timestamp-p 'lax) (funcall pcase-1)) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((null type) (cond ((org-at-heading-p) (let nil (call-interactively ...))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0)))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0))))) (cond ((and (boundp 'org-columns-overlays) org-columns-overlays) (org-columns-quit)) ((or (and (boundp 'org-clock-overlays) org-clock-overlays) org-occur-highlights) (if (boundp 'org-clock-overlays) (progn (org-clock-remove-overlays))) (org-remove-occur-highlights) (message "Temporary highlights/overlays removed from current...")) ((and (local-variable-p 'org-finish-function) (fboundp org-finish-function)) (funcall org-finish-function)) ((org-babel-hash-at-point)) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-hook)) (t (let* ((context (org-element-lineage (org-element-context) '(babel-call clock dynamic-block footnote-definition footnote-reference inline-babel-call inline-src-block inlinetask item keyword node-property paragraph plain-list planning property-drawer radio-target src-block statistics-cookie table table-cell table-row timestamp) t)) (radio-list-p (org-at-radio-list-p)) (type (org-element-type context))) (if (eq type 'paragraph) (progn (let ((parent ...)) (if (and ... ...) (progn ... ...))))) (let* ((pcase-1 #'(lambda nil ...)) (pcase-0 #'(lambda nil ...))) (cond ((memq type '...) (let nil (if org-babel-no-eval-on-ctrl-c-ctrl-c nil ... ...))) ((org-match-line "[ \11]*$") (let nil (or ... ...))) ((memq type '...) (let nil (let ... ...))) ((eq type 'clock) (let nil (org-clock-update-time-maybe))) ((eq type 'dynamic-block) (let nil (save-excursion ... ...))) ((eq type 'footnote-definition) (let nil (goto-char ...) (call-interactively ...))) ((eq type 'footnote-reference) (let nil (call-interactively ...))) ((memq type '...) (let nil (save-excursion ... ...))) ((eq type 'item) (let nil (if ... ... ...))) ((eq type 'plain-list) (let nil (if ... ... ...))) ((eq type 'keyword) (let nil (let ... ... ...) (message "Local setup has been refreshed"))) ((memq type '...) (let nil (call-interactively ...))) ((eq type 'radio-target) (let nil (call-interactively ...))) ((eq type 'statistics-cookie) (let nil (call-interactively ...))) ((memq type '...) (let nil (cond ... ... ... ...))) ((eq type 'timestamp) (funcall pcase-1)) ((eq type 'planning) (cond (... ...) (... ...) (t ...))) ((null type) (cond (... ...) (... ...) (t ...))) ((run-hook-with-args-until-success 'org-ctrl-c-ctrl-c-final-hook) 'nil) (t (funcall pcase-0))))))) org-ctrl-c-ctrl-c(nil) funcall-interactively(org-ctrl-c-ctrl-c nil) call-interactively(org-ctrl-c-ctrl-c nil nil) command-execute(org-ctrl-c-ctrl-c) ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-06-10 18:42 [BUG] ob-shell: cmdline and stdin broken when used with TRAMP Felix Freeman via General discussions about Org-mode. @ 2022-06-18 18:54 ` Bruno Barbier 2022-06-23 12:46 ` Ihor Radchenko 0 siblings, 1 reply; 10+ messages in thread From: Bruno Barbier @ 2022-06-18 18:54 UTC (permalink / raw) To: Felix Freeman, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 878 bytes --] "Felix Freeman" via "General discussions about Org-mode." <emacs-orgmode@gnu.org> writes: > When using TRAMP, ob-shell's :cmdline and :stdin header options are > broken on org-babel. > I can reproduce the problem (thanks for your nice MCE). I'm using: Org mode version 9.5.4 (release_9.5.4-32-g82036c) GNU Emacs 29.0.50 From what I understand, the function 'org-babel-sh-evaluate' relies on 'call-process'; and that function ignores file name handlers; as TRAMP relies on those file name handlers, it just cannot do the right thing. Using 'process-file' instead works for me. See the attached patch. I've also included a test, as the problem is reproducible with TRAMP "/mock::" connection. But, that test will only work on GNU/Linux systems. Warning: that's my first attempt to write a patch, and I don't have (yet) signed the copyright papers. Bruno [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: Patch for ob-shell: cmdline and stdin broken when used with TRAMP --] [-- Type: text/x-patch, Size: 5624 bytes --] From 9e8c114b738ddc633b50ca48e828676b92be784f Mon Sep 17 00:00:00 2001 From: Bruno BARBIER <brubar.cs@gmail.com> 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 "<point>" + "#+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.") + \f ;;; Functions for writing tests (put 'missing-test-dependency -- 2.35.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-06-18 18:54 ` Bruno Barbier @ 2022-06-23 12:46 ` Ihor Radchenko 2022-09-03 17:20 ` Bruno Barbier 0 siblings, 1 reply; 10+ messages in thread From: Ihor Radchenko @ 2022-06-23 12:46 UTC (permalink / raw) To: Bruno Barbier; +Cc: Felix Freeman, emacs-orgmode Bruno Barbier <brubar.cs@gmail.com> writes: > From what I understand, the function 'org-babel-sh-evaluate' relies on > 'call-process'; and that function ignores file name handlers; as TRAMP > relies on those file name handlers, it just cannot do the right thing. > > Using 'process-file' instead works for me. > > See the attached patch. Thanks for the patch! I am not very familiar with TRAMP, but since you supplied tests and they are also passing on my side, everything looks good. > I've also included a test, as the problem is reproducible with TRAMP > "/mock::" connection. But, that test will only work on GNU/Linux > systems. Then you also need to guard the tests against system-type variable value. If we cannot tests things on Windows, we should at least make the tests not fail when they should not. > Warning: that's my first attempt to write a patch, and I don't have > (yet) signed the copyright papers. You patch is >15LOC so we do need your copyright assignment before merging. Let me know if you face any difficulties with the copyright process. Note that FSF should reply within 5 working days. > 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. Note that we quote symbols like `symbols'. See https://orgmode.org/worg/org-contribute.html#commit-messages Also, please link to the bug report in the commit message for future reference. > + (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))) > + )) Probably you do not need concat here. AFAIU, (list shell-command-switch (file-local-name script-file) cmdline) should be good enough as ARGS argument of `process-file'. > + (:stdin t :shebang t) > + (:cmdline t :stdin t :shebang t) > + )) Please do not leave closing parenthesis at a separate line. See D.1 Emacs Lisp Coding Conventions section of Elisp manual for details. > +(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.") Since TRAMP sources are not normally available, we can add this variable as defined in tramp-tests.el somewhere into testing/org-test.el, for example. Best, Ihor ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-06-23 12:46 ` Ihor Radchenko @ 2022-09-03 17:20 ` Bruno Barbier 2022-09-04 9:49 ` Ihor Radchenko 0 siblings, 1 reply; 10+ messages in thread From: Bruno Barbier @ 2022-09-03 17:20 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Felix Freeman, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 2335 bytes --] Ihor Radchenko <yantar92@gmail.com> writes: > Thanks for the patch! > Thanks for the review! >> I've also included a test, as the problem is reproducible with TRAMP >> "/mock::" connection. But, that test will only work on GNU/Linux >> systems. > Then you also need to guard the tests against system-type variable > value. If we cannot tests things on Windows, we should at least make the > tests not fail when they should not. Done. I've told ERT to skip this new test for ms-dos and windows-nt systems. Thanks for the variable to use. > You patch is >15LOC so we do need your copyright assignment before > merging. Let me know if you face any difficulties with the copyright > process. Note that FSF should reply within 5 working days. Done. I just learnt a few days ago the process is done. > Note that we quote symbols like `symbols'. > See https://orgmode.org/worg/org-contribute.html#commit-messages > Also, please link to the bug report in the commit message for future > reference. Should be now OK too. > > + (list shell-command-switch > > + (concat (file-local-name script-file) " " cmdline))) > > Probably you do not need concat here. > AFAIU, (list shell-command-switch (file-local-name script-file) cmdline) > should be good enough as ARGS argument of `process-file'. The shell process should receive 2 arguments: the switch and the command to execute. I think the 'concat' is mandatory here. Am I missing something? >> + (:stdin t :shebang t) >> + (:cmdline t :stdin t :shebang t) >> + )) > > Please do not leave closing parenthesis at a separate line. See D.1 > Emacs Lisp Coding Conventions section of Elisp manual for details. Oops. Fixed. >> +(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.") > > Since TRAMP sources are not normally available, we can add this variable > as defined in tramp-tests.el somewhere into testing/org-test.el, for > example. I've copy/pasted the logic used in GNU Emacs Tramp and added a macro. I've added (require 'tramp) in the body; should I move it to the top of the file ? Thanks again for the review, Bruno [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch --] [-- Type: text/x-diff, Size: 6939 bytes --] From d9abfb423bff620dee15d204f4bab48e2ec8dc4e Mon Sep 17 00:00:00 2001 From: Bruno BARBIER <brubar.cs@gmail.com> 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-with-tramp-remote-dir): New macro. Fixes https://list.orgmode.org/CKMOBWBK709F.1RUN69SRWB64U@laptop/. --- lisp/ob-shell.el | 16 +++++++----- testing/lisp/test-ob-shell.el | 49 +++++++++++++++++++++++++++++++++++ testing/org-test.el | 29 +++++++++++++++++++++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el index 44efb4ea1..51071d40a 100644 --- a/lisp/ob-shell.el +++ b/lisp/ob-shell.el @@ -279,12 +279,16 @@ (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..442e70372 100644 --- a/testing/lisp/test-ob-shell.el +++ b/testing/lisp/test-ob-shell.el @@ -106,6 +106,55 @@ (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. + (skip-unless (not (memq system-type '(ms-dos windows-nt)))) + (org-test-with-tramp-remote-dir remote-dir + (dolist (spec `( () + (:dir ,remote-dir) + (:dir ,remote-dir :cmdline t) + (:dir ,remote-dir :stdin t) + (:dir ,remote-dir :cmdline t :shebang t) + (:dir ,remote-dir :stdin t :shebang t) + (:dir ,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 spec :dir) 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 spec :dir))) + (setq params-line (concat params-line " " ":dir " dir))) + (when (plist-get spec :stdin) + (setq who-line " read -r who") + (setq params-line (concat params-line " :stdin input"))) + (when (plist-get spec :cmdline) + (setq args-line " echo \"ARGS: $*\"") + (setq params-line (concat params-line " :cmdline \"--verbose 23 71\""))) + (when (plist-get spec :shebang) + (setq params-line (concat params-line " :shebang \"#!/bin/sh\""))) + (let* ((result (org-test-with-temp-text + (mapconcat #'identity + (list "#+name: input" + "tramp" + "" + (concat "<point>" + "#+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)))) + (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 0520e82f9..7e5d60e63 100644 --- a/testing/org-test.el +++ b/testing/org-test.el @@ -284,6 +284,35 @@ (defun org-test-table-target-expect (target &optional expect laps ;; on multiple lines in the ERT results buffer. (setq pp-escape-newlines back))))) +(defun org-test-with-tramp-remote-dir--worker (body) + "Worker for 'org-test-with-tramp-remote-dir'." + (let ((env-def (getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))) + (cond + (env-def (funcall body env-def)) + ((eq system-type 'windows-nt) (funcall body null-device)) + (t (require 'tramp) + (let ((tramp-methods + (cons '("mock" + (tramp-login-program "sh") + (tramp-login-args (("-i"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) + (tramp-connection-timeout 10)) + tramp-methods)) + (tramp-default-host-alist + `(("\\`mock\\'" nil ,(system-name))))) + (funcall body (format "/mock::%s" temporary-file-directory))))))) + +(defmacro org-test-with-tramp-remote-dir (dir &rest body) + "Bind the symbol DIR to a remote directory and execute BODY. +Return the value of the last form in BODY. The directory DIR +will be something like \"/mock::/tmp/\", which allows to test +Tramp related features. We mostly follow +`tramp-test-temporary-file-directory' from GNU Emacs tests." + (declare (debug (sexp body)) (indent 2)) + `(org-test-with-tramp-remote-dir--worker (lambda (,dir) ,@body))) + + \f ;;; Navigation Functions -- 2.35.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-03 17:20 ` Bruno Barbier @ 2022-09-04 9:49 ` Ihor Radchenko 2022-09-04 17:08 ` Bruno Barbier 2022-09-05 8:16 ` Bastien Guerry 0 siblings, 2 replies; 10+ messages in thread From: Ihor Radchenko @ 2022-09-04 9:49 UTC (permalink / raw) To: Bruno Barbier, Bastien; +Cc: Felix Freeman, emacs-orgmode Bruno Barbier <brubar.cs@gmail.com> writes: >> You patch is >15LOC so we do need your copyright assignment before >> merging. Let me know if you face any difficulties with the copyright >> process. Note that FSF should reply within 5 working days. > > Done. I just learnt a few days ago the process is done. Thanks! Bastien, could you please check the FSF record. >> > + (list shell-command-switch >> > + (concat (file-local-name script-file) " " cmdline))) >> >> Probably you do not need concat here. >> AFAIU, (list shell-command-switch (file-local-name script-file) cmdline) >> should be good enough as ARGS argument of `process-file'. > > The shell process should receive 2 arguments: the switch and the > command to execute. I think the 'concat' is mandatory here. > Am I missing something? You are probably right. `concat' does not heart anyway. >>> +(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.") >> >> Since TRAMP sources are not normally available, we can add this variable >> as defined in tramp-tests.el somewhere into testing/org-test.el, for >> example. > > > I've copy/pasted the logic used in GNU Emacs Tramp and added a macro. > I've added (require 'tramp) in the body; should I move it to the top > of the file ? Should not be a big deal to keep the require inside. > From d9abfb423bff620dee15d204f4bab48e2ec8dc4e Mon Sep 17 00:00:00 2001 > From: Bruno BARBIER <brubar.cs@gmail.com> > Date: Sat, 18 Jun 2022 09:48:01 +0200 > Subject: [PATCH] ob-shell: Use 'process-file' when stdin or cmdline '->` :: `process-file' > lib/ob-shell.el (org-babel-sh-evaluate): Use `process-file' (instead lisp/ob-shell.el > + (with-connection-local-variables I tried to test your patch on various Emacs versions. `with-connection-local-variables' is not yet available in Emacs 26. Emacs 26 has `with-connection-local-profiles' though I am not sure if it is a full equivalent. If not, you may need to create a compatibility wrapper for Emacs 26. -- Ihor Radchenko, Org mode contributor, Learn more about Org mode at https://orgmode.org/. Support Org development at https://liberapay.com/org-mode, or support my work at https://liberapay.com/yantar92 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-04 9:49 ` Ihor Radchenko @ 2022-09-04 17:08 ` Bruno Barbier 2022-09-05 10:33 ` Ihor Radchenko 2022-09-05 8:16 ` Bastien Guerry 1 sibling, 1 reply; 10+ messages in thread From: Bruno Barbier @ 2022-09-04 17:08 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Felix Freeman, emacs-orgmode [-- Attachment #1: Type: text/plain, Size: 1117 bytes --] Ihor Radchenko <yantar92@gmail.com> writes: > > '->` :: `process-file' > Sorry: fixed. > > lib/ob-shell.el (org-babel-sh-evaluate): Use `process-file' (instead > > lisp/ob-shell.el Thanks. > >> + (with-connection-local-variables > > I tried to test your patch on various Emacs versions. > `with-connection-local-variables' is not yet available in Emacs 26. > Emacs 26 has `with-connection-local-profiles' though I am not sure if it > is a full equivalent. If not, you may need to create a compatibility > wrapper for Emacs 26. Indeed. It's been renamed/changed in Emacs 27. https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=21f54feee8c83e2c5fd8eeb6741cbd479a7b19eb I'm now adding a version of `with-connection-local-variables', in org-compat.el: that should work for 26. I didn't test it as I currently don't have an Emacs 26. But I should be able to compile one, if you think it's needed. Thank you for spotting this and pointing me to `with-connection-local-profiles'. Thank you again, Ihor, for the review and the testing. Let me know if you see further improvements, Bruno [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: patch --] [-- Type: text/x-diff, Size: 7867 bytes --] From 9ed2f6d9e2c8bd7dd219e98ff7983fa53fd0686f Mon Sep 17 00:00:00 2001 From: Bruno BARBIER <brubar.cs@gmail.com> Date: Sat, 18 Jun 2022 09:48:01 +0200 Subject: [PATCH] ob-shell: Use `process-file' when stdin or cmdline lisp/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. lisp/org-compat.el (with-connection-local-variables): New compatibility macro. testing/lisp/test-ob-shell.el (ob-shell/remote-with-stdin-or-cmdline): New test. testing/org-test.el (org-test-with-tramp-remote-dir): New macro. Fixes https://list.orgmode.org/CKMOBWBK709F.1RUN69SRWB64U@laptop/. --- lisp/ob-shell.el | 16 +++++++----- lisp/org-compat.el | 10 +++++++ testing/lisp/test-ob-shell.el | 49 +++++++++++++++++++++++++++++++++++ testing/org-test.el | 29 +++++++++++++++++++++ 4 files changed, 98 insertions(+), 6 deletions(-) diff --git a/lisp/ob-shell.el b/lisp/ob-shell.el index 44efb4ea1..51071d40a 100644 --- a/lisp/ob-shell.el +++ b/lisp/ob-shell.el @@ -279,12 +279,16 @@ (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/lisp/org-compat.el b/lisp/org-compat.el index 91972ef9c..501e64bdb 100644 --- a/lisp/org-compat.el +++ b/lisp/org-compat.el @@ -221,6 +221,16 @@ (if (fboundp 'string-distance) (define-obsolete-function-alias 'org-babel-edit-distance 'org-string-distance "9.5") +(unless (fboundp 'with-connection-local-variables) + ;; Added in Emacs 27: commit:21f54feee8, 2019-03-09. + ;; Redefining it using the old function `with-connection-local-profiles'. + (defmacro with-connection-local-variables (&rest body) + "Apply connection-local variables according to `default-directory'. +Execute BODY, and unwind connection-local variables." + (declare (debug t)) + `(with-connection-local-profiles (connection-local-get-profiles) + ,@body))) + \f ;;; Emacs < 26.1 compatibility diff --git a/testing/lisp/test-ob-shell.el b/testing/lisp/test-ob-shell.el index 2f346f699..442e70372 100644 --- a/testing/lisp/test-ob-shell.el +++ b/testing/lisp/test-ob-shell.el @@ -106,6 +106,55 @@ (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. + (skip-unless (not (memq system-type '(ms-dos windows-nt)))) + (org-test-with-tramp-remote-dir remote-dir + (dolist (spec `( () + (:dir ,remote-dir) + (:dir ,remote-dir :cmdline t) + (:dir ,remote-dir :stdin t) + (:dir ,remote-dir :cmdline t :shebang t) + (:dir ,remote-dir :stdin t :shebang t) + (:dir ,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 spec :dir) 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 spec :dir))) + (setq params-line (concat params-line " " ":dir " dir))) + (when (plist-get spec :stdin) + (setq who-line " read -r who") + (setq params-line (concat params-line " :stdin input"))) + (when (plist-get spec :cmdline) + (setq args-line " echo \"ARGS: $*\"") + (setq params-line (concat params-line " :cmdline \"--verbose 23 71\""))) + (when (plist-get spec :shebang) + (setq params-line (concat params-line " :shebang \"#!/bin/sh\""))) + (let* ((result (org-test-with-temp-text + (mapconcat #'identity + (list "#+name: input" + "tramp" + "" + (concat "<point>" + "#+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)))) + (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 0520e82f9..7e5d60e63 100644 --- a/testing/org-test.el +++ b/testing/org-test.el @@ -284,6 +284,35 @@ (defun org-test-table-target-expect (target &optional expect laps ;; on multiple lines in the ERT results buffer. (setq pp-escape-newlines back))))) +(defun org-test-with-tramp-remote-dir--worker (body) + "Worker for 'org-test-with-tramp-remote-dir'." + (let ((env-def (getenv "REMOTE_TEMPORARY_FILE_DIRECTORY"))) + (cond + (env-def (funcall body env-def)) + ((eq system-type 'windows-nt) (funcall body null-device)) + (t (require 'tramp) + (let ((tramp-methods + (cons '("mock" + (tramp-login-program "sh") + (tramp-login-args (("-i"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-c")) + (tramp-connection-timeout 10)) + tramp-methods)) + (tramp-default-host-alist + `(("\\`mock\\'" nil ,(system-name))))) + (funcall body (format "/mock::%s" temporary-file-directory))))))) + +(defmacro org-test-with-tramp-remote-dir (dir &rest body) + "Bind the symbol DIR to a remote directory and execute BODY. +Return the value of the last form in BODY. The directory DIR +will be something like \"/mock::/tmp/\", which allows to test +Tramp related features. We mostly follow +`tramp-test-temporary-file-directory' from GNU Emacs tests." + (declare (debug (sexp body)) (indent 2)) + `(org-test-with-tramp-remote-dir--worker (lambda (,dir) ,@body))) + + \f ;;; Navigation Functions -- 2.35.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-04 17:08 ` Bruno Barbier @ 2022-09-05 10:33 ` Ihor Radchenko 2022-09-06 17:04 ` Bruno Barbier 0 siblings, 1 reply; 10+ messages in thread From: Ihor Radchenko @ 2022-09-05 10:33 UTC (permalink / raw) To: Bruno Barbier; +Cc: Felix Freeman, emacs-orgmode Bruno Barbier <brubar.cs@gmail.com> writes: > I'm now adding a version of `with-connection-local-variables', in > org-compat.el: that should work for 26. I didn't test it as I currently > don't have an Emacs 26. But I should be able to compile one, if you think > it's needed. > > Thank you for spotting this and pointing me to `with-connection-local-profiles'. > > > Thank you again, Ihor, for the review and the testing. > > Let me know if you see further improvements, LGTM now. Thanks! Applied onto main with minor amendments in formatting. https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=8151d52574f525fd922aadc43544688004cb7d14 -- Ihor Radchenko, Org mode contributor, Learn more about Org mode at https://orgmode.org/. Support Org development at https://liberapay.com/org-mode, or support my work at https://liberapay.com/yantar92 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-05 10:33 ` Ihor Radchenko @ 2022-09-06 17:04 ` Bruno Barbier 0 siblings, 0 replies; 10+ messages in thread From: Bruno Barbier @ 2022-09-06 17:04 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Felix Freeman, emacs-orgmode Ihor Radchenko <yantar92@gmail.com> writes: > LGTM now. Thanks! > Applied onto main with minor amendments in formatting. > https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=8151d52574f525fd922aadc43544688004cb7d14 Thanks Ihor! ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-04 9:49 ` Ihor Radchenko 2022-09-04 17:08 ` Bruno Barbier @ 2022-09-05 8:16 ` Bastien Guerry 2022-09-06 17:03 ` Bruno Barbier 1 sibling, 1 reply; 10+ messages in thread From: Bastien Guerry @ 2022-09-05 8:16 UTC (permalink / raw) To: Ihor Radchenko; +Cc: Bruno Barbier, Felix Freeman, emacs-orgmode Hi Ihor and Bruno, Ihor Radchenko <yantar92@gmail.com> writes: > Bastien, could you please check the FSF record. I confirm Bruno is on the list of FSF-signed contributors, I updated the Worg page. Bruno, thanks in advance for your contributions! -- Bastien ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [BUG] ob-shell: cmdline and stdin broken when used with TRAMP 2022-09-05 8:16 ` Bastien Guerry @ 2022-09-06 17:03 ` Bruno Barbier 0 siblings, 0 replies; 10+ messages in thread From: Bruno Barbier @ 2022-09-06 17:03 UTC (permalink / raw) To: Bastien Guerry, Ihor Radchenko; +Cc: emacs-orgmode Bastien Guerry <bzg@gnu.org> writes: > I confirm Bruno is on the list of FSF-signed contributors, > I updated the Worg page. Bruno, thanks in advance for your > contributions! Thanks Bastien. ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-09-06 17:07 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-06-10 18:42 [BUG] ob-shell: cmdline and stdin broken when used with TRAMP Felix Freeman via General discussions about Org-mode. 2022-06-18 18:54 ` Bruno Barbier 2022-06-23 12:46 ` Ihor Radchenko 2022-09-03 17:20 ` Bruno Barbier 2022-09-04 9:49 ` Ihor Radchenko 2022-09-04 17:08 ` Bruno Barbier 2022-09-05 10:33 ` Ihor Radchenko 2022-09-06 17:04 ` Bruno Barbier 2022-09-05 8:16 ` Bastien Guerry 2022-09-06 17:03 ` Bruno Barbier
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.