aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--nix/pkglst/packages_ruby_3_1.nix17
-rwxr-xr-xorg/org-tangle159
-rw-r--r--org/sisu_build.org25
-rwxr-xr-xshell.nix8
4 files changed, 203 insertions, 6 deletions
diff --git a/nix/pkglst/packages_ruby_3_1.nix b/nix/pkglst/packages_ruby_3_1.nix
new file mode 100644
index 00000000..ca9ced14
--- /dev/null
+++ b/nix/pkglst/packages_ruby_3_1.nix
@@ -0,0 +1,17 @@
+{ pkgs ? import <nixpkgs> {} }:
+with pkgs; [
+ ruby_3_1
+ rubyPackages_3_1.rake
+ rubyPackages_3_1.sqlite3
+ rubyPackages_3_1.thor
+ sqlite
+ unzip
+ xz
+ zip
+ openssl
+ #texlive-combined-full
+ nixFlakes
+ validatePkgConfig
+ jq
+ git
+]
diff --git a/org/org-tangle b/org/org-tangle
new file mode 100755
index 00000000..b662ecbd
--- /dev/null
+++ b/org/org-tangle
@@ -0,0 +1,159 @@
+#!/usr/bin/env sh
+":"; exec emacs --quick --script "$0" -- "$@" # -*- mode: emacs-lisp; lexical-binding: t; -*-
+;;; bin/org-tangle
+
+;; Tangles source blocks from org files. Also expands #+INCLUDE directives,
+;; unlike vanilla `ob-tangle'. Debug/info messages are directed to stderr and
+;; can be ignored.
+;;
+;; -l/--lang LANG
+;; Only include blocks in the specified language (e.g. emacs-lisp).
+;; -a/--all
+;; Tangle all blocks by default (unless it has :tangle nil set or a
+;; :notangle: tag)
+;; -t/--tag TAG
+;; --and TAG
+;; --or TAG
+;; Only include blocks in trees that have these tags. Combine multiple --and
+;; and --or's, or just use --tag (implicit --and).
+;; -p/--print
+;; Prints tangled code to stdout instead of to files
+;;
+;; Usage: org-tangle [[-l|--lang] LANG] some-file.org another.org
+;; Examples:
+;; org-tangle -l sh modules/some/module/README.org > install_module.sh
+;; org-tangle -l sh modules/lang/go/README.org | sh
+;; org-tangle --and tagA --and tagB my/literate/config.org
+
+(require 'cl-lib)
+(require 'ox)
+(require 'ob-tangle)
+
+(defun usage ()
+ (with-temp-buffer
+ (insert (format "%s %s [OPTIONS] [TARGETS...]\n"
+ "Usage:"
+ (file-name-nondirectory load-file-name))
+ "\n"
+ "A command line interface for tangling org-mode files. TARGETS can be\n"
+ "files or folders (which are searched for org files recursively).\n"
+ "\n"
+ "This is useful for literate configs that rely on command line\n"
+ "workflows to build it.\n"
+ "\n"
+ "Example:\n"
+ " org-tangle some-file.org\n"
+ " org-tangle literate/config/\n"
+ " org-tangle -p -l sh scripts.org > do_something.sh\n"
+ " org-tangle -p -l python -t tagA -t tagB file.org | python\n"
+ "\n"
+ "Options:\n"
+ " -a --all\t\tTangle all blocks by default\n"
+ " -l --lang LANG\tOnly tangle blocks written in LANG\n"
+ " -p --print\t\tPrint tangled output to stdout than to files\n"
+ " -t --tag TAG\n"
+ " --and TAG\n"
+ " --or TAG\n"
+ " Lets you tangle org blocks by tag. You may have more than one\n"
+ " of these options.\n")
+ (princ (buffer-string))))
+
+(defun *org-babel-tangle (fn &rest args)
+ "Don't write tangled blocks to files, print them to stdout."
+ (cl-letf (((symbol-function 'write-region)
+ (lambda (start end filename &optional append visit lockname mustbenew)
+ (princ (buffer-string)))))
+ (apply fn args)))
+
+(defun *org-babel-tangle-collect-blocks (&optional language tangle-file)
+ "Like `org-babel-tangle-collect-blocks', but will ignore blocks that are in
+trees with the :notangle: tag."
+ (let ((counter 0) last-heading-pos blocks)
+ (org-babel-map-src-blocks (buffer-file-name)
+ (let ((current-heading-pos
+ (org-with-wide-buffer
+ (org-with-limited-levels (outline-previous-heading)))))
+ (if (eq last-heading-pos current-heading-pos) (cl-incf counter)
+ (setq counter 1)
+ (setq last-heading-pos current-heading-pos)))
+ (unless (org-in-commented-heading-p)
+ (require 'org)
+ (let* ((tags (org-get-tags-at))
+ (info (org-babel-get-src-block-info 'light))
+ (src-lang (nth 0 info))
+ (src-tfile (cdr (assq :tangle (nth 2 info)))))
+ (cond ((member "notangle" tags))
+
+ ((and (or or-tags and-tags)
+ (or (not and-tags)
+ (let ((a (cl-intersection and-tags tags :test #'string=))
+ (b and-tags))
+ (not (or (cl-set-difference a b :test #'equal)
+ (cl-set-difference b a :test #'equal)))))
+ (or (not or-tags)
+ (cl-intersection or-tags tags :test #'string=))
+ t))
+
+ ((or (not (or all-blocks src-tfile))
+ (string= src-tfile "no") ; tangle blocks by default
+ (and tangle-file (not (equal tangle-file src-tfile)))
+ (and language (not (string= language src-lang)))))
+
+ ;; Add the spec for this block to blocks under its language.
+ ((let ((by-lang (assoc src-lang blocks))
+ (block (org-babel-tangle-single-block counter)))
+ (if by-lang
+ (setcdr by-lang (cons block (cdr by-lang)))
+ (push (cons src-lang (list block)) blocks))))))))
+ ;; Ensure blocks are in the correct order.
+ (mapcar (lambda (b) (cons (car b) (nreverse (cdr b)))) blocks)))
+(advice-add #'org-babel-tangle-collect-blocks
+ :override #'*org-babel-tangle-collect-blocks)
+
+(defvar all-blocks nil)
+(defvar and-tags nil)
+(defvar or-tags nil)
+(let (lang srcs and-tags or-tags)
+ (pop argv)
+ (while argv
+ (let ((arg (pop argv)))
+ (pcase arg
+ ((or "-h" "--help")
+ (usage)
+ (error ""))
+ ((or "-a" "--all")
+ (setq all-blocks t))
+ ((or "-l" "--lang")
+ (setq lang (pop argv)))
+ ((or "-p" "--print")
+ (advice-add #'org-babel-tangle :around #'*org-babel-tangle))
+ ((or "-t" "--tag" "--and")
+ (push (pop argv) and-tags))
+ ("--or"
+ (push (pop argv) or-tags))
+ ((guard (string-match-p "^--lang=" arg))
+ (setq lang (cadr (split-string arg "=" t t))))
+ ((guard (file-directory-p arg))
+ (setq srcs
+ (append (directory-files-recursively arg "\\.org$")
+ srcs)))
+ ((guard (file-exists-p arg))
+ (push arg srcs))
+ (_ (error "Unknown option or file: %s" arg)))))
+
+ (dolist (file srcs)
+ (let ((backup (make-temp-file (file-name-base file) nil ".backup.org")))
+ (unwind-protect
+ ;; Prevent slow hooks from interfering
+ (let (org-mode-hook org-confirm-babel-evaluate)
+ ;; We do the ol' switcheroo because `org-babel-tangle' writes
+ ;; changes to the current file, which would be imposing on the user.
+ (copy-file file backup t)
+ (with-current-buffer (find-file-noselect file)
+ ;; Tangling doesn't expand #+INCLUDE directives, so we do it
+ ;; ourselves, since includes are so useful for literate configs!
+ (org-export-expand-include-keyword)
+ (org-babel-tangle nil nil lang)))
+ (ignore-errors (copy-file backup file t))
+ (ignore-errors (delete-file backup)))))
+ (kill-emacs 0))
diff --git a/org/sisu_build.org b/org/sisu_build.org
index 8b56c1d2..da7ce0b1 100644
--- a/org/sisu_build.org
+++ b/org/sisu_build.org
@@ -2585,6 +2585,17 @@ with pkgs; [
]
#+END_SRC
+**** ruby 3.1
+
+#+BEGIN_SRC nix :tangle ../nix/pkglst/packages_ruby_3_1.nix
+{ pkgs ? import <nixpkgs> {} }:
+with pkgs; [
+ <<ruby_version_3_1>>
+ <<packages_project_relevant>>
+ <<packages_build>>
+]
+#+END_SRC
+
**** ruby 3.0
#+BEGIN_SRC nix :tangle ../nix/pkglst/packages_ruby_3_0.nix
@@ -2617,14 +2628,14 @@ with pkgs; [
#+NAME: ruby_current
#+BEGIN_SRC nix
-<<ruby_version_3_0>>
+<<ruby_version_3_1>>
#+END_SRC
*** ruby next
#+NAME: ruby_next
#+BEGIN_SRC nix
-<<ruby_version_3_0>>
+<<ruby_version_3_1>>
#+END_SRC
*** ruby 2.6 - ruby_version_2_6
@@ -2647,6 +2658,16 @@ rubyPackages_3_0.sqlite3
rubyPackages_3_0.thor
#+END_SRC
+*** ruby 3.1 - ruby_version_3_1
+
+#+NAME: ruby_version_3_1
+#+BEGIN_SRC nix
+ruby_3_1
+rubyPackages_3_1.rake
+rubyPackages_3_1.sqlite3
+rubyPackages_3_1.thor
+#+END_SRC
+
*** nix related packages
#+NAME: nix_packages
diff --git a/shell.nix b/shell.nix
index 5c0baa18..704a2da1 100755
--- a/shell.nix
+++ b/shell.nix
@@ -3,10 +3,10 @@
pkgs.mkShell {
buildInputs = [(
with pkgs; [
- ruby_3_0
- rubyPackages_3_0.rake
- rubyPackages_3_0.sqlite3
- rubyPackages_3_0.thor
+ ruby_3_1
+ rubyPackages_3_1.rake
+ rubyPackages_3_1.sqlite3
+ rubyPackages_3_1.thor
sqlite
unzip
xz