Implement bootstrap functionality + make bootstrap (WIP)

This commit is contained in:
Henrik Lissner 2017-03-20 02:45:31 -04:00
parent de08d0a2db
commit 804aba93f5
7 changed files with 131 additions and 24 deletions

View file

@ -27,6 +27,18 @@ clean:
clean-cache: clean-cache:
@$(EMACS) -f 'doom/clean-cache' @$(EMACS) -f 'doom/clean-cache'
# Syntactic sugar for bootstrapping modules. Allows: make bootstrap javascript
# See doom/bootstrap for more information.
ifeq (bootstrap,$(firstword $(MAKECMDGOALS)))
ARGV := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
$(eval $(ARGV):;@:)
endif
bootstrap: init.el
@$(EMACS) -f 'doom-initialize-autoloads' --eval "(doom/bootstrap '($(ARGV)))"
# This is only useful if your emacs.d is somewhere other than ~/.emacs.d (for # This is only useful if your emacs.d is somewhere other than ~/.emacs.d (for
# development purposes for instance). # development purposes for instance).
run: run:
@ -35,4 +47,5 @@ run:
init.el: init.el:
@[ -e init.el ] || $(error No init.el file; create one or copy init.example.el) @[ -e init.el ] || $(error No init.el file; create one or copy init.example.el)
.PHONY: all test
.PHONY: all test bootstrap

View file

@ -0,0 +1,46 @@
;;; ../core/autoload/bootstrap.el
(defvar doom-bootstraps nil
"TODO")
;;;###autoload
(defmacro def-bootstrap! (name &rest forms)
(declare (indent defun))
`(push (cons ',name
(lambda ()
(cl-flet ((sh (lambda (&rest args) (apply 'doom-sh args)))
(sh& (lambda (&rest args) (apply 'doom-async-sh args)))
(sudo (lambda (&rest args) (apply 'doom-sudo args)))
(fetch (lambda (&rest args) (apply 'doom-fetch args)))
(message (lambda (&rest args)
(apply 'message (format "[%s] %s" ,(symbol-name name) (car args))
(cdr args)))))
(with-demoted-errors "BOOTSTRAP ERROR: %s"
,@forms))))
doom-bootstraps))
;;;###autoload
(defun doom/bootstrap (ids)
"Bootstraps a module, if it has a bootstrapper. Bootstraps are expected to be
recipes for setting up the external dependencies of a module by, for instance,
using the OS package manager to install them, or retrieving them from a repo
using `doom-fetch'."
(interactive
(list (list (completing-read "Bootstrap: " (mapcar 'car doom-bootstraps) nil t))))
(doom-initialize-packages t)
;; Error out if any of the bootstraps don't exist or aren't valid functions.
;; If something goes wrong, it's likely we don't want to continue.
(let ((err-not-found (cl-remove-if (lambda (id) (assq id doom-bootstraps)) ids))
(err-not-func (cl-remove-if (lambda (id) (functionp (cdr (assq id doom-bootstraps)))) ids)))
(when (or (and err-not-found
(message "ERROR: These bootstraps don't exist: %s" err-not-found))
(and err-not-func
(message "ERROR: These bootstraps were invalid: %s" err-not-func)))
(error "There were errors. Aborting.")))
(dolist (id ids)
(let ((bootstrap (assq id doom-bootstraps)))
(message "[%s] BOOTSTRAP START" id)
(with-demoted-errors (format "[%s] ERROR: %%s" id)
(unless (funcall (cdr bootstrap))
(message "[%s] DONE (already bootstrapped)" id))))))

View file

@ -18,19 +18,21 @@
(t (error "Unknown OS: %s" system-type))))) (t (error "Unknown OS: %s" system-type)))))
;;;###autoload ;;;###autoload
(defun doom-sh (&rest args) (defun doom-sh (command &rest args)
"Runs a shell command and prints any output to the DOOM buffer." "Runs a shell command and prints any output to the DOOM buffer."
(error "doom-sh not implemented yet")) (if (equal (car (split-string command " ")) "sudo")
(apply 'doom-sudo command args)
(princ (shell-command-to-string (apply 'format command args)))))
;;;###autoload ;;;###autoload
(defun doom-async-sh (&rest args) (defun doom-sudo (command &rest args)
"Like `doom-sh', but runs command asynchronously."
(error "doom-async-sh not implemented yet"))
;;;###autoload
(defun doom-sudo (&rest args)
"Like `doom-sh', but runs as root (prompts for password)." "Like `doom-sh', but runs as root (prompts for password)."
(error "doom-sudo not implemented yet")) (let ((tramp-verbose 2)
(buf (get-buffer-create "*sudo*")))
(with-current-buffer buf
(unless (string-prefix-p "/sudo::/" default-directory)
(cd "/sudo::/"))
(apply 'doom-sh command args))))
;;;###autoload ;;;###autoload
(defun doom-fetch (fetcher location dest) (defun doom-fetch (fetcher location dest)
@ -59,3 +61,4 @@ etc."
(when (featurep 'evil) (when (featurep 'evil)
(evil-change-state 'normal)) (evil-change-state 'normal))
(set-buffer-modified-p nil)))))) (set-buffer-modified-p nil))))))

View file

@ -8,3 +8,29 @@
(when (featurep! :completion company) (when (featurep! :completion company)
(package! company-go)) (package! company-go))
;;
(def-bootstrap! go
(let ((gobin (executable-find "go"))
(gopath (getenv "GOPATH"))
changed)
(unless gobin
(pcase (doom-system-os)
('arch
(sudo "pacman --noconfirm -S go"))
('debian) ;; TODO
('macos
(sh "brew install go")))
(unless (executable-find "go")
(error "Go isn't installed (%s)" gobin)))
(unless (file-directory-p gopath)
(error "GOPATH isn't set up (%s)" gopath))
(mapc (lambda (url)
(unless (file-directory-p (expand-file-name (concat "src/" url) gopath))
(sh "%s get -u '%s'" gobin url)
(setq changed t)))
'("github.com/nsf/gocode"
"github.com/motemen/gore"
"golang.org/x/tools/cmd/guru"
"golang.org/x/tools/cmd/gorename"))
(or changed (not gobin))))

View file

@ -14,3 +14,23 @@
(when (featurep! :feature jump) (when (featurep! :feature jump)
(package! xref-js2)) (package! xref-js2))
;;
(def-bootstrap! javascript
(unless (cl-every 'executable-find '("node" "npm" "tern"))
(pcase (doom-system-os)
('arch
(let (progs)
(unless (executable-find "node") (push "nodejs" progs))
(unless (executable-find "npm") (push "npm" progs))
(when progs
(sudo "pacman --noconfirm -S %s" progs))))
('debian) ;; TODO
('macos
(unless (executable-find "node")
(sh "brew install node"))))
(unless (executable-find "node")
(error "Failed to install NodeJS"))
(unless (executable-find "tern")
(funcall (if (file-writable-p (executable-find "npm")) 'sh 'sudo)
"npm -g install tern"))
t))

View file

@ -1,14 +0,0 @@
;;; lang/sh/boostrap.el
(bootstrap!
:title "{z,ba}sh"
:desc "Sets up the zshdb and bashdb debuggers, and shell-check"
:if-debian
(sudo "apt-get update && apt-get install zshdb bashdb spellcheck")
:if-arch
(sudo "pacman --noconfirm --needed -S zshdb bashdb shellcheck")
:if-macos
(sh "brew install zshdb bashdb"))

View file

@ -3,3 +3,16 @@
(when (featurep! :completion company) (when (featurep! :completion company)
(package! company-shell)) (package! company-shell))
;;
(def-bootstrap! sh
(when-let (progs (cl-remove-if 'executable-find '("zshdb" "bashdb" "shellcheck")))
(let ((prog-str (string-join progs " ")))
(pcase (doom-system-os)
('arch
(sudo "pacman --noconfirm -S %s" prog-str))
('debian
(sudo "apt-get install -y %s" prog-str))
('macos
(sh "brew install %s" prog-str))))
t))