emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Evgenii Klimov <eugene.dev@lipklim.org>
To: emacs-orgmode <emacs-orgmode@gnu.org>
Subject: [BUG] ob-tangle.el: Blocks overwrite each other when grouping before tangling
Date: Wed, 12 Jul 2023 21:59:01 +0100	[thread overview]
Message-ID: <87lefkd9tb.fsf@lipklim.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 2512 bytes --]

Hi, I noticed that during grouping of blocks to tangle some of them can
overwrite each other if they have the same target file, but in different
format (relative vs absolute).

Consider this example (part of example.org file in the attachment):

  * 1st explicit :tangle yes
  #+begin_src emacs-lisp :tangle yes
    "1st explicit :tangle yes"
  #+end_src
  * 1st implicit default
  #+begin_src emacs-lisp
    "1st implicit :tangle no"
  #+end_src

If we call `org-babel-tangle-file' with target-file arg equal to
"/path/to/example.el" (e.g. `org-babel-load-file' does that), then
target file name for the first block will be "example.el" and
"/path/to/example.el" for the second block. It appears to be crucial in
`org-babel-tangle-collect-blocks' [1]:

  ;; `org-babel-map-src-blocks' runs this part on each source block
  (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))
         (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)))

Current implementation of `org-babel-effective-tangled-filename' returns
relative file name if :tangle is "yes" or relative FILENAME. But if
:tangle happened to be absolute (as `org-babel-load-file' does), then
blocks with the same file name but one name is relative while the other is
absolute, will be treated as different and won't be group (see last tree
lines of code above).

As a result when blocks are returned to `org-babel-tangle' [2] one group
will overwrite the previous one, since their absolute file names are
equal.

I noticed two scenarious where such things happen (e.g. if running
`org-babel-tangle-file'):
- if target-file arg is equal to one of :tangle FILENAMEs and some
  blocks don't have :tangle argument, while other have :tangle
  FILENAME. As a result one of these groups will be lost.
- if target-file arg is equal to tangled original Org file and some
  blocks don't have :tangle argument, while other have :tangle
  "yes". As a result one of these groups will also be lost.

I attach example Org file and scratch code to reproduce both scenarious.

[1] [[file:lisp/ob-tangle.el::(file-name (org-babel-effective-tangled-filename][target file-name]]

[2] [[file:lisp/ob-tangle.el::org-babel-tangle-collect-blocks lang-re tangle-file))][blocks return]]


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: example Org file --]
[-- Type: text/x-org, Size: 710 bytes --]

* 1st explicit :tangle yes
#+begin_src emacs-lisp :tangle yes
  "1st explicit :tangle yes"
#+end_src
* 1st explicit :tangle filename.el
#+begin_src emacs-lisp :tangle filename.el
  "1st explicit :tangle filename.el"
#+end_src
* 1st implicit default
#+begin_src emacs-lisp
  "1st implicit :tangle no"
#+end_src
* 2nd explicit :tangle yes
#+begin_src emacs-lisp :tangle yes
  "2nd explicit :tangle yes"
#+end_src
* explicit :tangle no
#+begin_src emacs-lisp :tangle no
  "explicit :tangle no"
#+end_src
* 2nd explicit :tangle filename.el
#+begin_src emacs-lisp :tangle filename.el
  "2nd explicit :tangle filename.el"
#+end_src
* 2nd implicit default
#+begin_src emacs-lisp
  "2nd implicit :tangle no"
#+end_src

[-- Attachment #3: scratch code to reproduce the bug --]
[-- Type: application/emacs-lisp, Size: 706 bytes --]

             reply	other threads:[~2023-07-12 22:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-12 20:59 Evgenii Klimov [this message]
2023-07-12 22:51 ` [PATCH] ob-tangle.el: Blocks overwrite each other when grouping before tangling Evgenii Klimov
2023-07-13 10:52   ` [PATCH v2] " Evgenii Klimov
2023-07-14  8:45     ` Ihor Radchenko
2023-07-24 12:28       ` [PATCH v3] " Evgenii Klimov
2023-07-25  7:02         ` Ihor Radchenko
2023-07-25 16:12           ` [PATCH v4] " Evgenii Klimov
2023-07-26  7:20             ` Ihor Radchenko
2023-07-26 15:07               ` [PATCH v5] " Evgenii Klimov
2023-07-28  7:29                 ` Ihor Radchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87lefkd9tb.fsf@lipklim.org \
    --to=eugene.dev@lipklim.org \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).