;; -*- lexical-binding: t; -*- ;; Helper packages (use-package deferred :commands (deferred:next deferred:nextc deferred:error deferred:cancel deferred:watch deferred:wait deferred:$ deferred:loop deferred:parallel deferred:earlier deferred:call deferred:apply deferred:process deferred:process-buffer deferred:wait-idle deferred:url-retrieve deferred:url-get deferred:url-post deferred:new deferred:succeed deferred:fail deferred:callback deferred:callback-post deferred:errorback deferred:errorback-post deferred:try deferred:timeout deferred:process)) (use-package s :defer t) (use-package dash :defer t) (use-package dash-functional :defer t) (use-package f :defer t) (use-package request :commands request) (use-package ht :defer t) ;; Elisp utilities (defun make-process-sentinel (success err) "Makes a process sentinel that calls `success` on success and `err` on error" (lambda (proc event) (cond ((string-match-p "finished" event) (funcall success)) (t (funcall err))))) (defun make-success-err-msg-sentinel (buf success-msg err-msg &optional kill-on-err) (make-process-sentinel (lambda () (message success-msg) (kill-buffer buf)) (lambda () (message err-msg) (when kill-on-err (kill-buffer buf))))) (cl-defun extract-vars-from-env-file (file &key dir) "Extracts an alist of variable name to value from a bash script that exports environment variables." (let ((file (expand-file-name file)) (var-re "\\(.+?\\)=\\(.+\\)$") (env '())) (with-temp-buffer (cd (expand-file-name (or dir (file-name-directory file)))) (insert (shell-command-to-string (concat "source " (shell-quote-argument file) " > /dev/null && env"))) (goto-char (point-min)) (save-match-data (while (re-search-forward var-re nil t) (push (cons (match-string 1) (match-string 2)) env)))) env)) (defun source-env-file (file) (interactive "fFile: \n") (let ((env (extract-vars-from-env-file file))) (dolist (binding env) (setenv (car binding) (cdr binding))))) (cl-defmacro with-env-from-file (file &rest body) (declare (indent 1)) (let ((env-var (make-symbol "the-env")) (path-var (make-symbol "the-path"))) `(let* ((,env-var (extract-vars-from-env-file ,file)) (,path-var (assoc "PATH" ,env-var)) (exec-path (if ,path-var (append (split-string (cdr ,path-var) ":") exec-path) exec-path)) (process-environment (append (mapcar (lambda (elt) (format "%s=%s" (car elt) (cdr elt))) ,env-var) process-environment))) ,@body))) (cl-defun call-with-env-from-file (file callback &key dir) (let* ((env (extract-vars-from-env-file file :dir dir)) (path (assoc "PATH" env)) (exec-path (if path (append (split-string (cdr path) ":") exec-path) exec-path)) (process-environment (append (mapcar (lambda (elt) (format "%s=%s" (car elt) (cdr elt))) env) process-environment))) (funcall callback))) (defmacro with-env (env &rest body) (declare (indent 1)) `(let* ((process-environment (append (mapcar (lambda (elt) (format "%s=%s" (car elt) (cdr elt))) ,env) process-environment))) ,@body)) (provide 'init-lib)