From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id cIb8B/vsY2OsuAAAbAwnHQ (envelope-from ) for ; Thu, 03 Nov 2022 17:31:55 +0100 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id kD8ACPvsY2OscQAA9RJhRA (envelope-from ) for ; Thu, 03 Nov 2022 17:31:55 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 9BC9CB339 for ; Thu, 3 Nov 2022 17:31:54 +0100 (CET) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oqd7B-0000cO-O3; Thu, 03 Nov 2022 12:30:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oqd70-0000Yk-9o for emacs-orgmode@gnu.org; Thu, 03 Nov 2022 12:30:48 -0400 Received: from mr85p00im-ztdg06021201.me.com ([17.58.23.189]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oqd6y-000281-4v for emacs-orgmode@gnu.org; Thu, 03 Nov 2022 12:30:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=me.com; s=1a1hai; t=1667493034; bh=RVdQutm6Og7GP82pmUtmxo0La++83xuXWTYubwIrEVw=; h=From:To:Subject:Date:Message-ID:MIME-Version:Content-Type; b=zvS/CiQUf0EpvhJid+0suhvfvgL23qfbe8Ixg3t5GudV8DnAUCBrD4lWAX3kzzDUN 8++D3Jc0ySiRWr/i5fr3/U7ZDmTtrymzzvNam+v0N7MSV9zRcrzFDa7eP+qNUBhRpM JoVyC1eKXIXMVajXQ3wwAkQSpeR9NDAv92GYgV4Sto/qzgmPaGLn9FKhwdZpEQFs5G eNCM3yiYMspGynhIAr5SIO7y7lyqM84js8v9h4uFieee5VaT8P2U3+U+QZI4mLTwZN konI3wS9KccXbsL3tByaTzRrs/8IXlNcowWeEWtPd9ALdY001dJi9rrSlRPLHhmb8m aV9QFdQrqQzZA== Received: from Rudolfs-MacBook-Air.local (mr38p00im-dlb-asmtp-mailmevip.me.com [17.57.152.18]) by mr85p00im-ztdg06021201.me.com (Postfix) with ESMTPSA id 5FCAE320666; Thu, 3 Nov 2022 16:30:33 +0000 (UTC) From: Rudolf =?utf-8?Q?Adamkovi=C4=8D?= To: Ihor Radchenko Cc: Ihor Radchenko , emacs-orgmode@gnu.org Subject: Re: Org 9.6-pre and Bash sessions In-Reply-To: <87r0yrjmue.fsf@localhost> References: <87edvbysqc.fsf@localhost> <87r0z6j1b1.fsf@localhost> <87pmel68y6.fsf@localhost> <87o7u432tl.fsf@localhost> <87a65o15ut.fsf@localhost> <87fsffqi49.fsf@localhost> <87wn8lorc1.fsf@localhost> <87v8o4krel.fsf@localhost> <87r0yrjmue.fsf@localhost> Date: Thu, 03 Nov 2022 17:30:29 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Proofpoint-ORIG-GUID: 5T6wWjdQAddQi171g78tjP2S2aZd4-3a X-Proofpoint-GUID: 5T6wWjdQAddQi171g78tjP2S2aZd4-3a X-Proofpoint-Virus-Version: =?UTF-8?Q?vendor=3Dfsecure_engine=3D1.1.170-22c6f66c430a71ce266a39bfe25bc?= =?UTF-8?Q?2903e8d5c8f:6.0.425,18.0.816,17.0.605.474.0000000_definitions?= =?UTF-8?Q?=3D2022-01-18=5F01:2022-01-14=5F01,2022-01-18=5F01,2020-01-23?= =?UTF-8?Q?=5F02_signatures=3D0?= X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 mlxlogscore=994 phishscore=0 adultscore=0 bulkscore=0 spamscore=0 suspectscore=0 malwarescore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2209130000 definitions=main-2211030110 Received-SPF: pass client-ip=17.58.23.189; envelope-from=salutis@me.com; helo=mr85p00im-ztdg06021201.me.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Emacs-orgmode" Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1667493114; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references:list-id:list-help:list-unsubscribe: list-subscribe:list-post:dkim-signature; bh=RVdQutm6Og7GP82pmUtmxo0La++83xuXWTYubwIrEVw=; b=ndgJU+TYTNXwTRQHMhw0oNNnBnnN253XnMTJoX63CYksYE7A72jagxmardgq9FbWQC7LWW NvQnsGjnEa+Sf70V4cGFGW29yOAcp6dCtdra3WNjgMTc4tlQy7uL3ug+h1cEj39R/7rQr1 usL392t+BYjX3S1P1muOUsrz5k04IuuhEOi/8XvMKJdJeiI3sxvQwkfS/PADTS5YoE/SQ/ GGiXSIGnPb/U0sRpMJh17cpttHAAkP/ShKAzaNTKK0/IdsYdCRHERS4kXzsQYGdvJ2Ov6w NCTtnDGEXTxEt2d/YA4rCBpuIBIWctEPBSxDf1/RIO634a4t/ZkTLKE0Olc7EA== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1667493114; a=rsa-sha256; cv=none; b=TAApikaUvLmzIMDlalFRG/VHakZq5z823qSuLeGhNvAkL/tKoniP7IdvlUtRf4Rgwk53TZ 0vWSpvHkTtDIjQPRKRwbkZCZRLcrUhrn88c7XasSNLvRLsu4q8eUj+tvoCtlMguI0C56v8 uxHDcE43g4opKX0JcpqyjLpPP/4gR/81eJ0GxjHmckEWsoT7ZJVrol5FmfHweX4UDzfIgm e/yRfV/o5L7/hJ8VympkIlcT1x4XLw1pjSAsACdaHv0OW97lbq6vGAIjn2q53py/WBBtJe ID+USuIJcHsJ9tFXP5VLj3I/z8gjby/mx++F6LQWD5t70GC1QSXZn2vWjlbokA== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=me.com header.s=1a1hai header.b="zvS/CiQU"; dmarc=pass (policy=quarantine) header.from=me.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -2.59 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=me.com header.s=1a1hai header.b="zvS/CiQU"; dmarc=pass (policy=quarantine) header.from=me.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 9BC9CB339 X-Spam-Score: -2.59 X-Migadu-Scanner: scn1.migadu.com X-TUID: 9DHmfUdlK5jK --=-=-= Content-Type: text/plain Ihor Radchenko writes: > Feel free to change it in the patch together with tests. Thank you for driving the discussion and for giving me the opportunity to solve the problem (and not just temporarily, but with tests). What do you think about the attached patch? Rudy --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-ob-shell-Never-throw-away-standard-error.patch >From 7001ed80e5fd146f6acf586b3cf3ef20bbba04e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rudolf=20Adamkovi=C4=8D?= Date: Wed, 26 Oct 2022 13:35:26 +0200 Subject: [PATCH] ob-shell: Never throw away standard error * lisp/ob-eval.el (org-babel-eval-error-notify): Do not insert superfluous whitespace. * lisp/ob-eval.el (org-babel-eval): Show standard error even if the command exits with a zero code. * testing/lisp/test-ob-shell.el( ob-shell/standard-output-after-success, ob-shell/standard-output-after-failure, ob-shell/error-output-after-success, ob-shell/error-output-after-failure, ob-shell/error-output-after-failure-multiple, ob-shell/exit-code, ob-shell/exit-code-multiple ): Add tests to avoid regressions. --- lisp/ob-eval.el | 47 +++++++++++--------- testing/lisp/test-ob-shell.el | 82 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 21 deletions(-) diff --git a/lisp/ob-eval.el b/lisp/ob-eval.el index e1278bbad..af9283c0a 100644 --- a/lisp/ob-eval.el +++ b/lisp/ob-eval.el @@ -40,39 +40,44 @@ (with-current-buffer buf (goto-char (point-max)) (save-excursion - (insert stderr) (unless (bolp) (insert "\n")) - (insert (format "[ Babel evaluation exited with code %S ]\n" exit-code)))) + (insert stderr) + (insert (format "[ Babel evaluation exited with code %S ]" exit-code)))) (display-buffer buf)) (message "Babel evaluation exited with code %S" exit-code)) (defun org-babel-eval (command query) "Run COMMAND on QUERY. +Return standard output produced by COMMAND. If COMMAND exits +with a non-zero code or produces error output, show it with +`org-babel-eval-error-notify'. + Writes QUERY into a temp-buffer that is processed with -`org-babel--shell-command-on-region'. If COMMAND succeeds then return -its results, otherwise display STDERR with -`org-babel-eval-error-notify'." +`org-babel--shell-command-on-region'." (let ((error-buffer (get-buffer-create " *Org-Babel Error*")) exit-code) (with-current-buffer error-buffer (erase-buffer)) (with-temp-buffer (insert query) (setq exit-code - (org-babel--shell-command-on-region - command error-buffer)) - (if (or (not (numberp exit-code)) (> exit-code 0)) - (progn - (with-current-buffer error-buffer - (org-babel-eval-error-notify exit-code (buffer-string))) - (save-excursion - (when (get-buffer org-babel-error-buffer-name) - (with-current-buffer org-babel-error-buffer-name - (unless (derived-mode-p 'compilation-mode) - (compilation-mode)) - ;; Compilation-mode enforces read-only, but Babel expects the buffer modifiable. - (setq buffer-read-only nil)))) - ;; Return output, if any. - (buffer-string)) - (buffer-string))))) + (org-babel--shell-command-on-region + command error-buffer)) + (let ((stderr (with-current-buffer error-buffer (buffer-string)))) + (if (or (not (numberp exit-code)) + (> exit-code 0) + (not (string-empty-p stderr))) + (progn + (org-babel-eval-error-notify exit-code stderr) + (save-excursion + (when (get-buffer org-babel-error-buffer-name) + (with-current-buffer org-babel-error-buffer-name + (unless (derived-mode-p 'compilation-mode) + (compilation-mode)) + ;; Compilation-mode enforces read-only, but + ;; Babel expects the buffer modifiable. + (setq buffer-read-only nil)))) + ;; Return output, if any. + (buffer-string)) + (buffer-string)))))) (defun org-babel-eval-read-file (file) "Return the contents of FILE as a string." diff --git a/testing/lisp/test-ob-shell.el b/testing/lisp/test-ob-shell.el index 4c00faa49..7aa45cc8a 100644 --- a/testing/lisp/test-ob-shell.el +++ b/testing/lisp/test-ob-shell.el @@ -170,6 +170,88 @@ ob-comint.el, which was not previously tested." "#+BEGIN_SRC sh :results table\necho 'I \"want\" it all'\n#+END_SRC" (org-babel-execute-src-block))))) +;;; Standard output + +(ert-deftest ob-shell/standard-output-after-success () + "Test standard output after exiting with a zero code." + (should (= 1 + (org-babel-execute:sh + "echo 1" nil)))) + +(ert-deftest ob-shell/standard-output-after-failure () + "Test standard output after exiting with a non-zero code." + (should (= 1 + (org-babel-execute:sh + "echo 1; exit 2" nil)))) + +;;; Standard error + +(ert-deftest ob-shell/error-output-after-success () + "Test that standard error shows in the error buffer, alongside the +exit code, after exiting with a zero code." + (should + (string= "1 +[ Babel evaluation exited with code 0 ]" + (progn (org-babel-eval-wipe-error-buffer) + (org-babel-execute:sh + "echo 1 >&2" nil) + (with-current-buffer org-babel-error-buffer-name + (buffer-string)))))) + +(ert-deftest ob-shell/error-output-after-failure () + "Test that standard error shows in the error buffer, alongside the +exit code, after exiting with a non-zero code." + (should + (string= "1 +[ Babel evaluation exited with code 2 ]" + (progn (org-babel-eval-wipe-error-buffer) + (org-babel-execute:sh + "echo 1 >&2; exit 2" nil) + (with-current-buffer org-babel-error-buffer-name + (buffer-string)))))) + +(ert-deftest ob-shell/error-output-after-failure-multiple () + "Test that multiple standard error strings show in the error +buffer, alongside multiple exit codes." + (should + (string= "1 +[ Babel evaluation exited with code 2 ] +3 +[ Babel evaluation exited with code 4 ]" + (progn (org-babel-eval-wipe-error-buffer) + (org-babel-execute:sh + "echo 1 >&2; exit 2" nil) + (org-babel-execute:sh + "echo 3 >&2; exit 4" nil) + (with-current-buffer org-babel-error-buffer-name + (buffer-string)))))) + +;;; Exit codes + +(ert-deftest ob-shell/exit-code () + "Test that the exit code shows in the error buffer after exiting +with a non-zero return code." + (should + (string= "[ Babel evaluation exited with code 1 ]" + (progn (org-babel-eval-wipe-error-buffer) + (org-babel-execute:sh + "exit 1" nil) + (with-current-buffer org-babel-error-buffer-name + (buffer-string)))))) + +(ert-deftest ob-shell/exit-code-multiple () + "Test that multiple exit codes show in the error buffer after +exiting with a non-zero return code multiple times." + (should + (string= "[ Babel evaluation exited with code 1 ] +[ Babel evaluation exited with code 2 ]" + (progn (org-babel-eval-wipe-error-buffer) + (org-babel-execute:sh + "exit 1" nil) + (org-babel-execute:sh + "exit 2" nil) + (with-current-buffer org-babel-error-buffer-name + (buffer-string)))))) (provide 'test-ob-shell) -- 2.38.1 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable --=20 "One can begin to reason only when a clear picture has been formed in the imagination." -- Walter Warwick Sawyer, Mathematician's Delight, 1943 Rudolf Adamkovi=C4=8D [he/him] Studenohorsk=C3=A1 25 84103 Bratislava Slovakia --=-=-=--