[emacs] Fixing magit key loading
This commit is contained in:
@ -8,6 +8,12 @@
|
||||
(after! envrc
|
||||
(envrc-global-mode))
|
||||
|
||||
;; Force systemd user ssh-agent socket for all Emacs subprocesses.
|
||||
(let* ((xdg (format "/run/user/%d" (user-uid)))
|
||||
(sock (expand-file-name "ssh-agent.socket" xdg)))
|
||||
(setenv "XDG_RUNTIME_DIR" xdg)
|
||||
(setenv "SSH_AUTH_SOCK" sock))
|
||||
|
||||
;; load pinentry
|
||||
(when (require 'pinentry nil t)
|
||||
(pinentry-start))
|
||||
@ -444,35 +450,55 @@ Always open the result in `eww`."
|
||||
(global-set-key (kbd "C-c l") #'life-scrobble-url)
|
||||
|
||||
(after! magit
|
||||
(defvar my/ssh-key-injector-script
|
||||
(expand-file-name "~/.local/bin/load_keys"))
|
||||
(defvar my/ssh-key-injector-script (expand-file-name "~/.local/bin/load_keys"))
|
||||
|
||||
(defun my/ssh-agent-has-keys-p (&rest _ignore)
|
||||
"Non-nil if ssh-agent currently has at least one identity loaded."
|
||||
(eq 0 (call-process "ssh-add" nil nil nil "-l")))
|
||||
(defun my/systemd-ssh-auth-sock ()
|
||||
(format "/run/user/%d/ssh-agent.socket" (user-uid)))
|
||||
|
||||
(defun my/ssh-add-status ()
|
||||
"ssh-add -l exit code: 0=has keys, 1=no keys, 2=no agent."
|
||||
(call-process "ssh-add" nil nil nil "-l"))
|
||||
|
||||
(defun my/run-ssh-key-injector ()
|
||||
(let* ((buf (get-buffer-create "*ssh-key-injector*"))
|
||||
(sock (my/systemd-ssh-auth-sock))
|
||||
(process-connection-type t) ;; PTY for pinentry-curses
|
||||
(process-environment (copy-sequence process-environment)))
|
||||
(setenv "SSH_AUTH_SOCK" sock)
|
||||
(setenv "XDG_RUNTIME_DIR" (format "/run/user/%d" (user-uid)))
|
||||
|
||||
(defun my/ensure-ssh-keys-loaded (&rest _ignore)
|
||||
"Ensure ssh-agent has keys loaded; if not, run injector script."
|
||||
(unless (file-executable-p my/ssh-key-injector-script)
|
||||
(user-error "SSH injector script not executable: %s" my/ssh-key-injector-script))
|
||||
(let ((buf (get-buffer-create "*ssh-key-injector*")))
|
||||
(with-current-buffer buf (erase-buffer))
|
||||
(let ((exit (call-process-shell-command my/ssh-key-injector-script nil buf t)))
|
||||
|
||||
(with-current-buffer buf
|
||||
(erase-buffer)
|
||||
(insert (format "Emacs SSH_AUTH_SOCK=%s\n" (getenv "SSH_AUTH_SOCK")))
|
||||
(insert (format "Emacs XDG_RUNTIME_DIR=%s\n\n" (getenv "XDG_RUNTIME_DIR"))))
|
||||
|
||||
(let ((proc (make-process
|
||||
:name "ssh-key-injector"
|
||||
:buffer buf
|
||||
:stderr buf
|
||||
:command (list my/ssh-key-injector-script)
|
||||
:noquery t)))
|
||||
(while (process-live-p proc)
|
||||
(accept-process-output proc 0.05))
|
||||
(let ((exit (process-exit-status proc)))
|
||||
(unless (eq exit 0)
|
||||
(display-buffer buf)
|
||||
(user-error "SSH key injection failed (see *ssh-key-injector*)")))))
|
||||
(user-error "SSH key injection failed (exit %d). See *ssh-key-injector*." exit))))))
|
||||
|
||||
;; IMPORTANT: remove then re-add, so we don't keep an old advised function object around
|
||||
(advice-remove 'magit-status #'my/ensure-ssh-keys-loaded)
|
||||
(advice-add 'magit-status :before #'my/ensure-ssh-keys-loaded)
|
||||
(defun my/ensure-ssh-keys-loaded (&rest _ignore)
|
||||
(pcase (my/ssh-add-status)
|
||||
(0 nil) ;; already has identities
|
||||
(1 (my/run-ssh-key-injector)) ;; agent reachable but empty
|
||||
(2 (user-error "No reachable ssh-agent. SSH_AUTH_SOCK=%s"
|
||||
(or (getenv "SSH_AUTH_SOCK") "<unset>")))
|
||||
(_ (my/run-ssh-key-injector))))
|
||||
|
||||
;; optional:
|
||||
(advice-remove 'magit-fetch #'my/ensure-ssh-keys-loaded)
|
||||
(advice-add 'magit-fetch :before #'my/ensure-ssh-keys-loaded)
|
||||
(advice-remove 'magit-push #'my/ensure-ssh-keys-loaded)
|
||||
(advice-add 'magit-push :before #'my/ensure-ssh-keys-loaded)
|
||||
(advice-remove 'magit-pull #'my/ensure-ssh-keys-loaded)
|
||||
(advice-add 'magit-pull :before #'my/ensure-ssh-keys-loaded))
|
||||
(dolist (fn '(magit-status magit-fetch magit-push magit-pull))
|
||||
(advice-remove fn #'my/ensure-ssh-keys-loaded)
|
||||
(advice-add fn :before #'my/ensure-ssh-keys-loaded)))
|
||||
|
||||
(defun my/disable-apheleia-in-certain-projects ()
|
||||
(when-let ((root (and (fboundp 'project-root)
|
||||
|
||||
Reference in New Issue
Block a user