diff --git a/core/core-configuration-layer.el b/core/core-configuration-layer.el index 872af2a0f..43fcfdeb9 100644 --- a/core/core-configuration-layer.el +++ b/core/core-configuration-layer.el @@ -76,7 +76,11 @@ (variables :initarg :variables :initform nil :type list - :documentation "A list of variable-value pairs.")) + :documentation "A list of variable-value pairs.") + (disabled :initarg :disabled-for + :initform nil + :type list + :documentation "A list of layer where this layer is disabled.")) "A configuration layer.") (defclass cfgl-package () @@ -108,7 +112,8 @@ (excluded :initarg :excluded :initform nil :type boolean - :documentation "If non-nil this package is ignored."))) + :documentation + "If non-nil this package is excluded from all layers."))) (defvar configuration-layer--layers '() "A non-sorted list of `cfgl-layer' objects.") @@ -738,39 +743,47 @@ path." (defun configuration-layer//configure-package (pkg) "Configure PKG." - (let ((pkg-name (oref pkg :name))) + (let* ((pkg-name (oref pkg :name)) + (owner (oref pkg :owner)) + (owner-layer (object-assoc owner :name configuration-layer--layers)) + (disabled-for-layers (oref owner-layer :disabled-for))) (spacemacs-buffer/message (format "Configuring %S..." pkg-name)) ;; pre-init (mapc (lambda (layer) - (spacemacs-buffer/message - (format " -> pre-init (%S)..." layer)) - (condition-case err - (funcall (intern (format "%S/pre-init-%S" layer pkg-name))) - ('error - (configuration-layer//set-error) - (spacemacs-buffer/append - (format - (concat "An error occurred while pre-configuring %S " - "in layer %S (error: %s)\n") - pkg-name layer err))))) + (if (memq layer disabled-for-layers) + (spacemacs-buffer/message + (format " -> ignore pre-init (disabled for %S)..." layer)) + (spacemacs-buffer/message + (format " -> pre-init (%S)..." layer)) + (condition-case err + (funcall (intern (format "%S/pre-init-%S" layer pkg-name))) + ('error + (configuration-layer//set-error) + (spacemacs-buffer/append + (format + (concat "An error occurred while pre-configuring %S " + "in layer %S (error: %s)\n") + pkg-name layer err)))))) (oref pkg :pre-layers)) ;; init - (let ((owner (oref pkg :owner))) - (spacemacs-buffer/message (format " -> init (%S)..." owner)) - (funcall (intern (format "%S/init-%S" owner pkg-name)))) + (spacemacs-buffer/message (format " -> init (%S)..." owner)) + (funcall (intern (format "%S/init-%S" owner pkg-name))) ;; post-init (mapc (lambda (layer) - (spacemacs-buffer/message - (format " -> post-init (%S)..." layer)) - (condition-case err - (funcall (intern (format "%S/post-init-%S" layer pkg-name))) - ('error - (configuration-layer//set-error) - (spacemacs-buffer/append - (format - (concat "An error occurred while post-configuring %S " - "in layer %S (error: %s)\n") - pkg-name layer err))))) + (if (memq layer disabled-for-layers) + (spacemacs-buffer/message + (format " -> ignore post-init (disabled for %S)..." layer)) + (spacemacs-buffer/message + (format " -> post-init (%S)..." layer)) + (condition-case err + (funcall (intern (format "%S/post-init-%S" layer pkg-name))) + ('error + (configuration-layer//set-error) + (spacemacs-buffer/append + (format + (concat "An error occurred while post-configuring %S " + "in layer %S (error: %s)\n") + pkg-name layer err)))))) (oref pkg :post-layers)))) (defun configuration-layer/update-packages (&optional always-update) diff --git a/tests/core/core-configuration-layer-utest.el b/tests/core/core-configuration-layer-utest.el index 0328de955..60a36ae03 100644 --- a/tests/core/core-configuration-layer-utest.el +++ b/tests/core/core-configuration-layer-utest.el @@ -492,6 +492,94 @@ (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1)) (configuration-layer/get-packages layers)))))) +;; --------------------------------------------------------------------------- +;; configuration-layer//configure-package +;; --------------------------------------------------------------------------- + + +(ert-deftest test-configure-package--init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1)) + (configuration-layer--layers `(,(cfgl-layer "layer1" :name 'layer1))) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer1/init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-packages--pre-init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1 :pre-layers '(layer2))) + (configuration-layer--layers + `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2))) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg nil) + (defun layer2/pre-init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer2/pre-init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-package--post-init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1 :post-layers '(layer2))) + (configuration-layer--layers + `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2))) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg nil) + (defun layer2/post-init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer2/post-init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-package--pre-init-is-evaluated-before-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1 :pre-layers '(layer2))) + (configuration-layer--layers + `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2))) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init pre-init) witness))))) + +(ert-deftest test-configure-package--post-init-is-evaluated-after-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1 :post-layers '(layer2))) + (configuration-layer--layers + `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2))) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(post-init init) witness))))) + +(ert-deftest test-configure-package--disabled-for-does-not-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owner 'layer1 + :pre-layers '(layer2) + :post-layers '(layer3))) + (configuration-layer--layers + `(,(cfgl-layer "layer1" :name 'layer1 :disabled-for '(layer2 layer3)) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3))) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init) witness)))) + ) + ;; --------------------------------------------------------------------------- ;; configuration-layer//sort-packages ;; --------------------------------------------------------------------------- @@ -543,7 +631,7 @@ (should (not (configuration-layer//get-package-recipe 'pkg2))))) ;; --------------------------------------------------------------------------- -;; configuration-layer/filter-packages +;; configuration-layer/filter-objects ;; --------------------------------------------------------------------------- (ert-deftest test-filter-packages--example-filter-excluded-packages () @@ -564,7 +652,7 @@ (cfgl-package "pkg4" :name 'pkg4) (cfgl-package "pkg7" :name 'pkg7) (cfgl-package "pkg8" :name 'pkg8)) - (configuration-layer/filter-packages + (configuration-layer/filter-objects pkgs (lambda (x) (not (oref x :excluded)))))))) @@ -586,7 +674,7 @@ (cfgl-package "pkg4" :name 'pkg4) (cfgl-package "pkg7" :name 'pkg7) (cfgl-package "pkg8" :name 'pkg8)) - (configuration-layer/filter-packages + (configuration-layer/filter-objects pkgs (lambda (x) (not (eq 'local (oref x :location))))))))) @@ -611,7 +699,7 @@ (should (equal (list (cfgl-package "pkg2" :name 'pkg2) (cfgl-package "pkg4" :name 'pkg4) (cfgl-package "pkg8" :name 'pkg8)) - (configuration-layer/filter-packages + (configuration-layer/filter-objects pkgs (lambda (x) (and (not (eq 'local (oref x :location))) (not (oref x :excluded))))))))) @@ -638,7 +726,7 @@ (cfgl-package "pkg5" :name 'pkg5 :excluded t) (cfgl-package "pkg7" :name 'pkg7) (cfgl-package "pkg8" :name 'pkg8)) - (configuration-layer/filter-packages + (configuration-layer/filter-objects pkgs (lambda (x) (or (not (eq 'local (oref x :location))) (not (oref x :excluded)))))))))