@@ -407,7 +407,7 @@ When INTERACTIVE is non-nil, `yank' the recipe to the clipboard."
407407(cl-defstruct (elpaca (:constructor elpaca<--create) (:type list ) (:named )
408408 (:conc-name elpaca<-))
409409 " Order for queued processing."
410- id package props order statuses
410+ id package declaration order statuses
411411 build-dir source-dir main
412412 files build-steps recipe blocking blockers
413413 dependencies dependents
@@ -582,21 +582,27 @@ The first function, if any, which returns non-nil is used." :type 'hook)
582582 " Return E's source directory."
583583 (expand-file-name (elpaca<-package e) elpaca-sources-directory))
584584
585- (defun elpaca<-create (order )
586- " Create a new elpaca struct from ORDER."
587- (let* ((id (elpaca--first order))
588- (recipe (elpaca-recipe order))
589- (build-dir (elpaca-build-dir recipe))
590- (e (elpaca<--create
591- :id id :package (symbol-name id)
592- :order order :build-dir build-dir
593- :recipe recipe :builtp (and build-dir (file-exists-p build-dir)))))
594- (when-let* ((recipe)
595- (registered (elpaca-alist-get (plist-get recipe :type ) elpaca-types)))
596- (require registered)) ; ;@TODO: optimize lookup by tracking separate from `features' ?
597- (setf (elpaca<-source-dir e) (elpaca-source-dir e)
598- (elpaca<-build-steps e) (elpaca-build-steps e))
599- e))
585+ (defun elpaca<-create (declaration )
586+ " Create a new elpaca struct from DECLARATION."
587+ (let* ((id (elpaca--first declaration))
588+ (e (elpaca<--create :id id :package (symbol-name id) :declaration declaration)))
589+ (condition-case err
590+ (progn
591+ (setf (elpaca<-order e) (elpaca--normalize-order declaration)
592+ (elpaca<-recipe e) (elpaca--normalize-recipe (elpaca<-order e))
593+ (elpaca<-build-dir e) (elpaca-build-dir (elpaca<-recipe e))
594+ (elpaca<-builtp e) (when-let* ((build-dir (elpaca<-build-dir e)))
595+ (file-exists-p build-dir)))
596+ (when-let* ((recipe (elpaca<-recipe e))
597+ (registered (elpaca-alist-get (plist-get recipe :type ) elpaca-types)))
598+ (require registered)) ; ;@TODO: optimize lookup by tracking separate from `features' ?
599+ (setf (elpaca<-source-dir e) (elpaca-source-dir e)
600+ (elpaca<-build-steps e) (elpaca-build-steps e))
601+ e)
602+ (elpaca-error
603+ (if (run-hook-with-args-until-success 'elpaca-error-functions e err)
604+ (throw 'elpaca-abort nil )
605+ (signal (car err) (cdr err)))))))
600606
601607(declare-function elpaca-ui--update-search-query " elpaca-ui" )
602608(defun elpaca--update-log-buffer ()
@@ -1466,13 +1472,19 @@ When quit with \\[keyboard-quit], running sub-processes are not stopped."
14661472 (setq elpaca--interactive-timer
14671473 (run-at-time elpaca-interactive-interval nil #'elpaca-process-queues ))))))
14681474
1475+ (defcustom elpaca-error-functions nil
1476+ " Abnormal hook to catch top-level `elpaca-error' signals.
1477+ Each element is a function accepting an E struct and error object.
1478+ The first to return non-nil suppresses the error."
1479+ :type 'hook )
1480+
14691481;;;### autoload
14701482(defmacro elpaca (order &rest body )
14711483 " Queue ORDER for asynchronous installation/activation.
14721484Evaluate BODY forms synchronously once ORDER's queue is processed.
14731485See Info node `(elpaca) Basic Concepts'."
14741486 (declare (indent 1 ) (debug form))
1475- `(elpaca-- expand-declaration ', order ', body ))
1487+ `(catch ' elpaca-abort (elpaca-- expand-declaration ', order ', body) ))
14761488
14771489(defvar elpaca--try-package-history nil " History for `elpaca-try' ." )
14781490;;;### autoload
0 commit comments