From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:403:478a::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms9.migadu.com with LMTPS id UJNzA8r+v2TW5wAASxT56A (envelope-from ) for ; Tue, 25 Jul 2023 18:56:42 +0200 Received: from aspmx1.migadu.com ([2001:41d0:403:478a::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id 0KWkA8r+v2QGkAAAauVa8A (envelope-from ) for ; Tue, 25 Jul 2023 18:56:42 +0200 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 4255E481FB for ; Tue, 25 Jul 2023 18:56:41 +0200 (CEST) Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=lipklim.org header.s=key1 header.b="XwyC/7z0"; 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"; dmarc=pass (policy=quarantine) header.from=lipklim.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1690304201; 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=KzImab8iYOKud+0DZeplUCxRpJiRIY2Pcqa6W0vnets=; b=HyOryVt1sLIKLpcON1bX3c3atPvww6ZZNWDX4s1RoAN3NK//AIhDsZ7aIjOdqz4AJFM6aP gFtx7UYrNSpbLBlU/zGrsmwy2LCBe6ii2eRO6e3oF0NnMjdNBTTffWuY696OOCm6IebRep Xf6enH2og1r7l2naFEA1uJXKfKXVgRf9jnL3alAQKqwHRbGEx27OcDeMkT+VG5Uqt8QWTE pcQEfPbDNJ1Sri9DNRc68W2F1TBO41sIydTZlmiKovnAp7f2dy0zHPsxXpVpYkZXqhO9G+ d04rgHxhEsMegpqexONxFnD8YNABtVmduvJ0EDj2gUTxNxvS3+2egL0lXvRUwg== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=lipklim.org header.s=key1 header.b="XwyC/7z0"; 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"; dmarc=pass (policy=quarantine) header.from=lipklim.org ARC-Seal: i=1; s=key1; d=yhetil.org; t=1690304201; a=rsa-sha256; cv=none; b=mziZZwovtI71mEfmMpFkh8EEnShy2xqrM1Gy/ctWYruxaIywzeDQd4E4tK4WCupi7tIS1N BlT5uj++ZIv0i0YRQJCtksesbM1+fYRZ3EHYW/KcbKkbEIhSTcVmzON8DwxJG6IsMqgeI6 2+cr+wtwKlPOcd4BwfP20pmO8QPpN9az8rhk6Vr0k28O2OYJKUxOcD1GEhPIT2CKa5peJK QMZ0Mf147h54FE5CcVq922XXJVMDFSeatk4N7Eer6oQEq3nTqO+aljVcBaoNXVhPrILYXe U10xawcI0ojg44UkE8v9FEPJw81FTob7L463p59tD/k5Dag+Vn9WLmbM4W1dEw== Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qOLKD-0003Wf-RH; Tue, 25 Jul 2023 12:55:53 -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 1qOLK5-0003WA-Vh for emacs-orgmode@gnu.org; Tue, 25 Jul 2023 12:55:46 -0400 Received: from out-51.mta1.migadu.com ([2001:41d0:203:375::33]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qOLK1-0002Er-18 for emacs-orgmode@gnu.org; Tue, 25 Jul 2023 12:55:45 -0400 References: <87lefkd9tb.fsf@lipklim.org> <87h6q8d9lz.fsf@lipklim.org> <87cz0wcbtt.fsf@lipklim.org> <87ttu6j2zr.fsf@localhost> <87bkg1h4q3.fsf@lipklim.org> <87fs5c79ss.fsf@localhost> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=lipklim.org; s=key1; t=1690304135; h=from:from: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; bh=KzImab8iYOKud+0DZeplUCxRpJiRIY2Pcqa6W0vnets=; b=XwyC/7z02ZHLZ+cAtdOzpO8VkvKCjIHs2pYOczdPLtA43ritF/gSyg0UOfMc7c/0pLQTVx FZ+u9lCGpg1P4O2zOJ4JCD57Q8NirDVNdtskBhYxWAft1EelwHKTaS54dQuAwJdKGrEYir f+rb4CyJQXZAOf2ifBm11c6S+3Ye828= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Evgenii Klimov To: Ihor Radchenko Cc: emacs-orgmode@gnu.org Subject: [PATCH v4] ob-tangle.el: Blocks overwrite each other when grouping before tangling Date: Tue, 25 Jul 2023 17:12:46 +0100 In-reply-to: <87fs5c79ss.fsf@localhost> Message-ID: <871qgwgcc9.fsf@lipklim.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Received-SPF: pass client-ip=2001:41d0:203:375::33; envelope-from=eugene.dev@lipklim.org; helo=out-51.mta1.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 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: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: emacs-orgmode-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Spam-Score: -6.60 X-Migadu-Queue-Id: 4255E481FB X-Migadu-Spam-Score: -6.60 X-Migadu-Scanner: mx0.migadu.com X-TUID: JBWwp1WDE6Md --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Ihor Radchenko writes: [...] > Thanks! > The second patch is malformed. May you please resend? Sorry, resend with rewritten test. [...] > If you can, please avoid using `org-test-at-id'. This is much less > readable compared to explicit org-test-with-temp-text because one needs > to reach out to another file in order to understand what the test is > about. Now it's less verbose, handles both cases (with and without TARGET-FILE) and prints detailed ert explanation. > Evgenii Klimov writes: [...] >> It wasn't clear for me: will ":tangle yes" or explicit ":tangle no" be >> affected by TARGET-FILE. Maybe if we rephrase as follows it will be >> clear for both of us: >> >> Optional argument TARGET-FILE can be used to overwrite a default >> export file in `org-babel-default-header-args' for all source >> blocks. > > In `org-babel-tangle', TARGET-FILE is set as fallback value for the > blocks that have no :tangle value at all, including inherited; including > :tangle yes. This exactly idea I wanted to add to the docstring. > The manual asserts > > =E2=80=98yes=E2=80=99 > Export the code block to source file. The file name for the sou= rce > file is derived from the name of the Org file, and the file > extension is derived from the source code language identifier. > Example: =E2=80=98:tangle yes=E2=80=99. > > So, "yes" should imply :tangle > > `org-babel-tangle-collect-blocks' handles this by > > (unless (or (string=3D src-tfile "no") > (and tangle-file (not (equal tangle-file src-tfile))) > (and lang-re (not (string-match-p lang-re src-lang)))) > > So, :tangle no is always excluded. > When TANGLE-FILE is set and not equal to :tangle value (including > "yes"), block is also excluded. Indeed, but later =E2=80=98no=E2=80=99 The *default*. Do not extract the code in a source code file. Example: =E2=80=98:tangle no=E2=80=99. in conjunction with TARGET-FILE's description in ~org-babel-tangle~ docstring: Optional argument TARGET-FILE can be used to specify a *default* export file for all source blocks. made me feel doubt about TARGET-FILE's effect. Anyway, probably it was my incorrect interpretation, so let's leave it as it is. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=v4-0001-testing-lisp-test-ob-tangle.el-Test-block-collect.patch >From a5b4faec9b58b8e56512c03e4f1a1fe295900d3f Mon Sep 17 00:00:00 2001 From: Evgenii Klimov Date: Fri, 21 Jul 2023 22:40:06 +0100 Subject: [PATCH v4 1/2] testing/lisp/test-ob-tangle.el: Test block collection into groups for tangling * testing/lisp/test-ob-tangle.el (ob-tangle/collect-blocks): Test block collection into groups for tangling. --- testing/lisp/test-ob-tangle.el | 111 +++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/testing/lisp/test-ob-tangle.el b/testing/lisp/test-ob-tangle.el index 07e75f4d3..55e1f7aa3 100644 --- a/testing/lisp/test-ob-tangle.el +++ b/testing/lisp/test-ob-tangle.el @@ -569,6 +569,117 @@ another block (set-buffer-modified-p nil)) (kill-buffer buffer)))) +(ert-deftest ob-tangle/collect-blocks () + "Test block collection into groups for tangling." + (org-test-with-temp-text-in-file + "* H1 with :tangle in properties +:PROPERTIES: +:header-args: :tangle relative.el +:END: + +#+begin_src emacs-lisp +\"H1: inherited :tangle relative.el in properties\" +#+end_src + +#+begin_src emacs-lisp :tangle yes +\"H1: :tangle yes\" +#+end_src + +#+begin_src emacs-lisp :tangle no +\"H1: should be ignored\" +#+end_src + + + +#+begin_src emacs-lisp :tangle relative.el +\"H1: :tangle relative.el\" +#+end_src + +#+begin_src emacs-lisp :tangle ./relative.el +\"H1: :tangle ./relative.el\" +#+end_src + +#+begin_src emacs-lisp :tangle /tmp/absolute.el +\"H1: :tangle /tmp/absolute.el\" +#+end_src + +#+begin_src emacs-lisp :tangle ~/../../tmp/absolute.el +\"H1: :tangle ~/../../tmp/absolute.el\" +#+end_src + +* H2 without :tangle in properties + +#+begin_src emacs-lisp +\"H2: without :tangle\" +#+end_src + +#+begin_src emacs-lisp :tangle yes +\"H2: :tangle yes\" +#+end_src + +#+begin_src emacs-lisp :tangle no +\"H2: should be ignored\" +#+end_src + +#+begin_src emacs-lisp :tangle relative.el +\"H2: :tangle relative.el\" +#+end_src + +#+begin_src emacs-lisp :tangle ./relative.el +\"H2: :tangle ./relative.el\" +#+end_src + +#+begin_src emacs-lisp :tangle /tmp/absolute.el +\"H2: :tangle /tmp/absolute.el\" +#+end_src + +#+begin_src emacs-lisp :tangle ~/../../tmp/absolute.el +\"H2: :tangle ~/../../tmp/absolute.el\" +#+end_src +" + (letrec ((org-file (buffer-file-name)) + (test-dir (file-name-directory org-file)) + (el-file-abs (concat (file-name-sans-extension org-file) ".el")) + (el-file-rel (file-name-nondirectory el-file-abs)) + (sort-fn (lambda (lst) (seq-sort-by #'car #'string-lessp lst))) + (expected-targets-fn + (lambda (nblocks-el-file) + "Convert to absolute file names and sort expected targets" + (funcall sort-fn + (map-apply (lambda (file nblocks) + (cons (expand-file-name file test-dir) nblocks)) + `(("/tmp/absolute.el" . 4) + ("relative.el" . 5) + ;; single file that differs between tests + (,el-file-abs . ,nblocks-el-file)))))) + (collected-targets-fn + (lambda (collected-blocks) + (funcall sort-fn (map-apply (lambda (file blocks) + (cons file (length blocks))) + collected-blocks))))) + ;; to the first header + (insert (format "#+begin_src emacs-lisp :tangle %s +\"H1: absolute org-file.lang-ext :tangle %s\" +#+end_src" el-file-abs el-file-abs)) + (goto-char (point-max)) + ;; to the second header + (insert (format " +#+begin_src emacs-lisp :tangle %s +\"H2: relative org-file.lang-ext :tangle %s\" +#+end_src" el-file-rel el-file-rel)) + (should (equal (funcall expected-targets-fn 4) + (funcall collected-targets-fn (org-babel-tangle-collect-blocks)))) + ;; simulate TARGET-FILE to test as `org-babel-tangle' and + ;; `org-babel-load-file' would call + ;; `org-babel-tangle-collect-blocks'. + (let ((org-babel-default-header-args + (org-babel-merge-params + org-babel-default-header-args + (list (cons :tangle el-file-abs))))) + (should (equal (funcall expected-targets-fn 5) + (funcall collected-targets-fn + (org-babel-tangle-collect-blocks)))))))) + (provide 'test-ob-tangle) ;;; test-ob-tangle.el ends here -- 2.34.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=v4-0002-ob-tangle.el-Avoid-relative-file-names-when-group.patch >From 4ca26a21612df18d8ff7f71726a858501e317e00 Mon Sep 17 00:00:00 2001 From: Evgenii Klimov Date: Wed, 12 Jul 2023 19:24:48 +0100 Subject: [PATCH v4 2/2] ob-tangle.el: Avoid relative file names when grouping blocks to tangle * lisp/ob-tangle.el (org-babel-tangle-single-block, org-babel-tangle-collect-blocks): Make target file name attribute, used internally to group blocks with identical language, to be absolute. (org-babel-effective-tangled-filename): Avoid using relative file names that could cause one block to overwrite the others in `org-babel-tangle-collect-blocks' if they have the same target file but in different formats. --- lisp/ob-tangle.el | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index b6ae4b55a..670a3dfa7 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -427,17 +427,19 @@ that the appropriate major-mode is set. SPEC has the form: org-babel-tangle-comment-format-end link-data))))) (defun org-babel-effective-tangled-filename (buffer-fn src-lang src-tfile) - "Return effective tangled filename of a source-code block. -BUFFER-FN is the name of the buffer, SRC-LANG the language of the -block and SRC-TFILE is the value of the :tangle header argument, -as computed by `org-babel-tangle-single-block'." - (let ((base-name (cond - ((string= "yes" src-tfile) - ;; Use the buffer name - (file-name-sans-extension buffer-fn)) - ((string= "no" src-tfile) nil) - ((> (length src-tfile) 0) src-tfile))) - (ext (or (cdr (assoc src-lang org-babel-tangle-lang-exts)) src-lang))) + "Return effective tangled absolute filename of a source-code block. +BUFFER-FN is the absolute file name of the buffer, SRC-LANG the +language of the block and SRC-TFILE is the value of the :tangle +header argument, as computed by `org-babel-tangle-single-block'." + (let* ((fnd (file-name-directory buffer-fn)) + (base-name (cond + ((string= "yes" src-tfile) + ;; Use the buffer name + (file-name-sans-extension buffer-fn)) + ((string= "no" src-tfile) nil) + ((> (length src-tfile) 0) + (expand-file-name src-tfile fnd)))) + (ext (or (cdr (assoc src-lang org-babel-tangle-lang-exts)) src-lang))) (when base-name ;; decide if we want to add ext to base-name (if (and ext (string= "yes" src-tfile)) @@ -454,7 +456,9 @@ source code blocks by languages matching a regular expression. Optional argument TANGLE-FILE can be used to limit the collected code blocks by target file." - (let ((counter 0) last-heading-pos blocks) + (let ((counter 0) + (buffer-fn (buffer-file-name (buffer-base-buffer))) + last-heading-pos blocks) (org-babel-map-src-blocks (buffer-file-name) (let ((current-heading-pos (or (org-element-begin @@ -478,7 +482,7 @@ code blocks by target file." (let* ((block (org-babel-tangle-single-block counter)) (src-tfile (cdr (assq :tangle (nth 4 block)))) (file-name (org-babel-effective-tangled-filename - (nth 1 block) src-lang src-tfile)) + buffer-fn src-lang src-tfile)) (by-fn (assoc file-name blocks))) (if by-fn (setcdr by-fn (cons (cons src-lang block) (cdr by-fn))) (push (cons file-name (list (cons src-lang block))) blocks))))))) @@ -595,7 +599,7 @@ non-nil, return the full association list to be used by comment))) (if only-this-block (let* ((file-name (org-babel-effective-tangled-filename - (nth 1 result) src-lang src-tfile))) + file src-lang src-tfile))) (list (cons file-name (list (cons src-lang result))))) result))) -- 2.34.1 --=-=-=--