emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Phil <pe@7d.nz>
To: emacs-orgmode@gnu.org
Subject: [FR] org-babel-n-tangle
Date: Fri, 12 Jul 2024 09:11:40 +0200	[thread overview]
Message-ID: <6a7129e2-9d26-4292-b8d1-1a3e3db90f4b@7d.nz> (raw)

Hi,

The ability to tangle to multiple destinations is a very convenient way
to manage cluster configurations. No, it's more than that: it's an
*awesome* way to deploy and keep clusters configs and repros well
organized.

The following *org-babel-n-tangle*, is just a small derivation
of *org-babel-tangle*.  It's displayed here as a diff not
with the intent to be applied as a patch, but to show the very
little differences required in order to get this working.

#+begin_src diff
diff -u ~/.emacs.d/repos/org/lisp/ob-tangle.el ~/tmp/ob-ntangle.el
--- ~/.emacs.d/repos/org/lisp/ob-tangle.el
+++ ~/tmp/ob-ntangle.el
@@ -238,8 +238,12 @@
(org-babel-tangle-file filename)))

;;;###autoload
-(defun org-babel-tangle (&optional arg target-file lang-re)
-  "Write code blocks to source-specific files.
+(defun org-babel-n-tangle (&optional arg target-file lang-re)
+  "Write code blocks to source-specific files
+located into the directories designated by the :n-tangle parameter
+then onto subsequent directory and file of the :tangle parameter.
+Performs like `org-babel-tangle' adding an extra iteration over
+a list of directories, potentially different hosts and protocols
Extract the bodies of all source code blocks from the current
file into their own source-specific files.  Return the list of files.
With one universal prefix argument, only tangle the block at point.
@@ -268,12 +272,19 @@
(tangle-file
(when (equal arg '(16))
(or (cdr (assq :tangle (nth 2 (org-babel-get-src-block-info 'no-eval))))
-      (user-error "Point is not in a source code block"))))
+      (user-error "Point is not in a source code block"))))
+     (targets (or (cadr (assoc (cdr
+         (assoc :n-tangle (nth 2 (org-babel-get-src-block-info))))
+                               org-babel-ntangle-destinations))
+      '(nil))) ; iterate on one local target
path-collector
(source-file buffer-file-name))
+
+ (dolist (target targets) ;; iterate the n-tangle group
+  (progn
(mapc ;; map over file-names
(lambda (by-fn)
-    (let ((file-name (car by-fn)))
+    (let ((file-name (concat target (car by-fn))))
(when file-name
(let ((lspecs (cdr by-fn))
(fnd (file-name-directory file-name))
@@ -354,6 +365,7 @@
(if (equal arg '(4))
(org-babel-tangle-single-block 1 t)
(org-babel-tangle-collect-blocks lang-re tangle-file)))
+ ))
(message "Tangled %d code block%s from %s" block-counter
(if (= block-counter 1) "" "s")
(file-name-nondirectory

#+end_src


In order to use this *:n-tangle* parameter, the destinations are
declared in groups of host and/or root folders.
    #+begin_src elisp
      (setq org-babel-ntangle-destinations
            '(("test-1"
               ("/tmp/test/host-A"
                "/tmp/test/host-B" ))
              ("hosts-A&B/tmp"
               ("/-:hostA:/tmp/"
                "/-:hostB:/tmp/"))))

    #+end_src


Calling *org-babel-n-tangle* with the universal argument
runs the tangle processor, not on the entire file, but
for the current block. The tangled output goes into the
designated group.

#+begin_example
#+begin_src elisp :n-tangle "hosts-A&B/tmp" :tangle /x/y :mkdirp t
   (org-babel-n-tangle '(4))
#+end_src
#+end_example

In the above example the tangled outputs goes to
*hostA:/tmp/x/y* and *hostB:/tmp/x/y* using a default protocol.

In the absence of *:n-tangle* or when
*org-babel-ntangle-destinations* is nil.
*org-babel-n-tangle* behaves like *org-babel-tangle*

What do you think ?

Phil

/"Oh what a tangled web we weave..."/


             reply	other threads:[~2024-07-12  7:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-12  7:11 Phil [this message]
2024-07-12 11:23 ` [FR] org-babel-n-tangle Ihor Radchenko
2024-07-15  5:12   ` Phil
2024-07-15 14:28     ` 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=6a7129e2-9d26-4292-b8d1-1a3e3db90f4b@7d.nz \
    --to=pe@7d.nz \
    --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).