bin/doom: inhibit POSIX errors during postscript

Some doom commands will generate a temporary script at
~/.emacs.d/.local/.doom.sh so that it can run an arbitrary shell command
after the current invocation of bin/doom ends. Very useful for, say,
restarting the currently running doom command after a destructive
operation, like updating Doom's source code, tangling your literate
config, or for launching arbitrary programs, like a new instance of
Emacs. This is necessary because elisp lacks an execv implementation.

However, for some folks, .doom.sh wasn't executing at all. This meant:

1. Some `doom upgrade`s would upgrade Doom itself but never move on to
   the second step of the process: updating its packages.
2. Literate config users could tangle their configs on `doom sync`, but
   the actual syncing process would never happen (#3746).
3. `doom run` would do nothing.

I hadn't realized /bin/sh runs bash in POSIX mode (at least, on systems
where /bin/sh = bash, like nixOS or macOS). In POSIX mode the script
will abort the if a builtin command (like export) returns a non-zero
exit code. Since .doom.sh is basically a bunch of exports followed by an
arbitrary command, and there are some environment variables
that can trigger validation errors (like UID triggering a "read-only
variable" error), we have a problem.

Hopefully addresses #3746
This commit is contained in:
Henrik Lissner 2020-08-18 18:45:37 -04:00
parent f3740d4766
commit 9f45561825
No known key found for this signature in database
GPG Key ID: 5F6C0EA160557395

View File

@ -172,17 +172,18 @@ COMMAND, and passes ARGS to it."
(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))
(coding-system-for-read 'utf-8)
(delimiter "--%EOF%--"))
(with-temp-file post-script
(insert "#!/usr/bin/env sh\n"
(save-match-data
(insert (save-match-data
(cl-loop for env in process-environment
if (string-match "^\\([a-zA-Z0-9_]+\\)=\\(.+\\)$" env)
concat (format "export %s=%s;\n"
concat (format "%s=%s \\\n"
(match-string 1 env)
(shell-quote-argument (match-string 2 env)))))
(format "\nexport PATH=\"%s:$PATH\"\n" (concat doom-emacs-dir "bin/"))
"\n[ -x \"$0\" ] && rm -f \"$0\"\n"
(format "PATH=\"%s:$PATH\" \\\n" (concat doom-emacs-dir "bin/"))
"/usr/bin/env sh <<" delimiter "\n"
"rm -f " (shell-quote-argument post-script) "\n"
(if (stringp lines)
lines
(string-join
@ -191,7 +192,7 @@ COMMAND, and passes ARGS to it."
collect (mapconcat #'shell-quote-argument (remq nil line) " "))
(list (mapconcat #'shell-quote-argument (remq nil lines) " ")))
"\n"))
"\n"))
"\n" delimiter "\n"))
(set-file-modes post-script #o700)))
(defun doom-cli-execute-lines-after (&rest lines)