From eb9cb0c6e95c2f7ed2426b8238c21fe52ca21cf8 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 8 Aug 2020 05:15:40 -0400 Subject: [PATCH] Fix org version conflicts due to literate config #3649 Tangling would load org libraries. If org hasn't been installed yet, this means the older version is loaded, later interfering with the installation and byte-compilation of the new package, causing down the road. --- bin/doom | 1 - core/core-cli.el | 41 ++++++++--- modules/config/literate/autoload.el | 106 +++++++++++++++------------- 3 files changed, 87 insertions(+), 61 deletions(-) diff --git a/bin/doom b/bin/doom index fee5c1b68..416005e75 100755 --- a/bin/doom +++ b/bin/doom @@ -5,7 +5,6 @@ :; case "$_VERSION" in *\ 2[0-5].[0-9]) echo "Detected Emacs $_VERSION"; echo "Doom only supports Emacs 26.1 and newer"; echo; exit 2 ;; esac :; _DOOMBASE="${EMACSDIR:-$(dirname "$0")/..}" :; _DOOMPOST="$_DOOMBASE/.local/.doom.sh" -:; rm -f "$_DOOMPOST" :; $EMACS --no-site-file --script "$0" -- "$@" :; CODE=$? :; [ -x "$_DOOMPOST" ] && PATH="$_DOOMBASE/bin:$PATH" "$_DOOMPOST" "$0" "$@" diff --git a/core/core-cli.el b/core/core-cli.el index 05ce9b490..2c903b978 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -169,23 +169,42 @@ COMMAND, and passes ARGS to it." (doom--cli-process cli (remq nil args))) (user-error "Couldn't find any %S command" command))) +(defun doom-cli--execute-after (lines) + (let ((post-script (concat doom-local-dir ".doom.sh")) + (coding-system-for-write 'utf-8) + (coding-system-for-read 'utf-8)) + (with-temp-file post-script + (insert "#!/usr/bin/env sh\n" + "[ -x \"$0\" ] && rm -f \"$0\"\n" + (save-match-data + (cl-loop for env in process-environment + if (string-match "^\\([^=]+\\)=\\(.+\\)$" env) + concat (format "%s=%S\n" + (match-string 1 env) + (match-string 2 env)))) + "\n" + (if (stringp lines) + lines + (string-join + (if (listp (car-safe lines)) + (cl-loop for line in (doom-enlist lines) + collect (mapconcat #'shell-quote-argument (remq nil line) " ")) + (list (mapconcat #'shell-quote-argument (remq nil lines) " "))) + "\n")) + "\n")) + (set-file-modes post-script #o700))) + +(defun doom-cli-execute-lines-after (&rest lines) + "TODO" + (doom-cli--execute-after (string-join lines "\n"))) + (defun doom-cli-execute-after (&rest args) "Execute shell command ARGS after this CLI session quits. This is particularly useful when the capabilities of Emacs' batch terminal are insufficient (like opening an instance of Emacs, or reloading Doom after a 'doom upgrade')." - (let ((post-script (concat doom-local-dir ".doom.sh"))) - (with-temp-file post-script - (insert "#!/usr/bin/env sh\n" - "rm -f " (prin1-to-string post-script) "\n" - "exec " (mapconcat #'shell-quote-argument (remq nil args) " ") - "\n")) - (let* ((current-mode (file-modes post-script)) - (add-mode (logand ?\111 (default-file-modes)))) - (or (/= (logand ?\111 current-mode) 0) - (zerop add-mode) - (set-file-modes post-script (logior current-mode add-mode)))))) + (doom-cli--execute-after args)) (defmacro defcli! (name speclist &optional docstring &rest body) "Defines a CLI command. diff --git a/modules/config/literate/autoload.el b/modules/config/literate/autoload.el index 4ebba45ab..696a9eb71 100644 --- a/modules/config/literate/autoload.el +++ b/modules/config/literate/autoload.el @@ -18,55 +18,63 @@ byte-compiled from.") "Tangles `+literate-config-file' if it has changed." (print! (start "Compiling your literate config...")) (print-group! - (let* ((default-directory doom-private-dir) - (org (expand-file-name +literate-config-file)) - (dest (concat (file-name-sans-extension +literate-config-file) ".el"))) - (and (require 'ox) - (require 'ob-tangle) - (letf! (;; Operate on a copy because `org-babel-tangle' has - ;; side-effects we need to undo immediately as not to - ;; overwrite the user's config; it's bad ettiquite. - (backup (make-temp-file (concat (file-name-nondirectory org) "."))) - ;; A hack to prevent ob-tangle from operating relative to the - ;; backup file and thus tangling to the wrong destinations. - (defun org-babel-tangle-single-block (&rest args) - (let* ((spec (apply org-babel-tangle-single-block args)) - (file (nth 1 spec)) - (file (if (file-equal-p file backup) org file)) - (file (if org-babel-tangle-use-relative-file-links - (file-relative-name file) - file))) - (setf (nth 1 spec) file) - spec)) - ;; Ensure output conforms to the formatting of all doom CLIs - (defun message (msg &rest args) - (when msg - (print! (info "%s") (apply #'format msg args))))) - (unwind-protect - (with-temp-file backup - (insert-file-contents org) - (let ((buffer-file-name backup) - ;; Prevent unwanted entries in recentf, or formatters, or - ;; anything that could be on these hooks, really. Nothing - ;; else should be touching these files (particularly in - ;; interactive sessions). - (write-file-functions nil) - (before-save-hook nil) - (after-save-hook nil) - ;; Prevent infinite recursion due to recompile-on-save - ;; hooks later, and speed up `org-mode' init. - (org-mode-hook nil) - (org-inhibit-startup t)) - (org-mode) - (with-silent-modifications - ;; Tangling won't ordinarily expand #+INCLUDE directives, - ;; so I do it myself. - (org-export-expand-include-keyword) - (org-babel-tangle nil dest)))) - (ignore-errors (delete-file backup))) - ;; Write an empty file to serve as our mtime cache - (with-temp-file +literate-config-cache-file) - t))))) + (and (not (getenv "NOTANGLE")) + (require 'ox nil t) + (require 'ob-tangle nil t) + (letf! ((default-directory doom-private-dir) + (target +literate-config-file) + (cache +literate-config-cache-file) + (dest (concat (file-name-sans-extension target) ".el")) + ;; Operate on a copy because `org-babel-tangle' has + ;; side-effects we need to undo immediately as not to + ;; overwrite the user's config; it's bad ettiquite. + (backup (make-temp-file (concat (file-name-nondirectory target) "."))) + + ;; HACK A hack to prevent ob-tangle from operating relative to + ;; the backup file and thus tangling to the wrong + ;; destinations. + (defun org-babel-tangle-single-block (&rest args) + (let* ((spec (apply org-babel-tangle-single-block args)) + (file (nth 1 spec)) + (file (if (file-equal-p file backup) target file)) + (file (if org-babel-tangle-use-relative-file-links + (file-relative-name file) + file))) + (setf (nth 1 spec) file) + spec)) + ;; Ensure output conforms to the formatting of all doom CLIs + (defun message (msg &rest args) + (when msg + (print! (info "%s") (apply #'format msg args))))) + (unwind-protect + (with-temp-file backup + (insert-file-contents file) + (let ((buffer-file-name backup) + ;; Prevent unwanted entries in recentf, or formatters, or + ;; anything that could be on these hooks, really. Nothing + ;; else should be touching these files (particularly in + ;; interactive sessions). + (write-file-functions nil) + (before-save-hook nil) + (after-save-hook nil) + ;; Prevent infinite recursion due to recompile-on-save + ;; hooks later, and speed up `org-mode' init. + (org-mode-hook nil) + (org-inhibit-startup t)) + (org-mode) + (with-silent-modifications + ;; Tangling won't ordinarily expand #+INCLUDE directives, + ;; so I do it myself. + (org-export-expand-include-keyword) + (org-babel-tangle nil dest)))) + (ignore-errors (delete-file backup))) + ;; Write an empty file to serve as our mtime cache + (with-temp-file cache) + (unless doom-interactive-p + (message "Restarting..." ) + (doom-cli-execute-lines-after "NOTANGLE=1 \"$@\"") + (kill-emacs 0)) + t)))) ;;;###autoload (add-hook 'org-mode-hook #'+literate-enable-recompile-h)