diff --git a/core/core-configuration-layer.el b/core/core-configuration-layer.el index a755ecaf4..7e511b844 100644 --- a/core/core-configuration-layer.el +++ b/core/core-configuration-layer.el @@ -309,17 +309,20 @@ If NO-INSTALL is non nil then install steps are skipped." (dotspacemacs|call-func dotspacemacs/layers "Calling dotfile layers...") (when (spacemacs-buffer//choose-banner) (spacemacs-buffer//inject-version t)) - ;; layers - (setq configuration-layer--layers (configuration-layer//declare-layers)) - (configuration-layer//configure-layers configuration-layer--layers) - ;; packages - (setq configuration-layer--packages (configuration-layer//declare-packages - configuration-layer--layers)) + ;; first, declare layer then package as soon as possible to + ;; resolve usage and ownership (in other words, get the list of used + ;; layers and packages as soon as possible) + (configuration-layer//declare-layers) + (configuration-layer//declare-packages configuration-layer--layers) + ;; then load the functions and finally configure the layers (configuration-layer//load-layers-files configuration-layer--layers '("funcs.el")) + (configuration-layer//configure-layers configuration-layer--layers) + ;; pre-filter some packages to save some time later in the loading process (setq configuration-layer--used-distant-packages (configuration-layer//get-distant-used-packages configuration-layer--packages)) + ;; install/uninstall packages (configuration-layer/load-auto-layer-file) (unless no-install (configuration-layer//install-packages @@ -620,82 +623,81 @@ If TOGGLEP is non nil then `:toggle' parameter is ignored." (re-search-backward "\\(\\[.+\\]\\)" nil t) (help-xref-button 1 'help-package pkg-symbol)))))) -(defun configuration-layer/get-packages (layers &optional dotfile packages) +(defun configuration-layer/get-packages (layers &optional dotfile) "Read the package lists of LAYERS and dotfile and return a list of packages." - (let ((result packages)) - (dolist (layer layers) - (let* ((layer-name (oref layer :name)) - (layer-dir (oref layer :dir)) - (packages-file (concat layer-dir "packages.el"))) - ;; packages - (when (file-exists-p packages-file) - ;; required for lazy-loading of unused layers - ;; for instance for helm-spacemacs-help - (eval `(defvar ,(intern (format "%S-packages" layer-name)) nil)) - (load packages-file) - (dolist (pkg (symbol-value (intern (format "%S-packages" - layer-name)))) - (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) - (init-func (intern (format "%S/init-%S" - layer-name pkg-name))) - (pre-init-func (intern (format "%S/pre-init-%S" - layer-name pkg-name))) - (post-init-func (intern (format "%S/post-init-%S" - layer-name pkg-name))) - (ownerp (fboundp init-func)) - (obj (object-assoc pkg-name :name result))) - (cl-pushnew pkg-name (oref layer :packages)) - (if obj - (setq obj (configuration-layer/make-package pkg obj ownerp)) - (setq obj (configuration-layer/make-package pkg nil ownerp)) - (push obj result)) - (when ownerp - ;; last owner wins over the previous one, - ;; still warn about mutliple owners - (when (and (oref obj :owner) - (not (eq layer-name (oref obj :owner)))) - (spacemacs-buffer/warning - (format (concat "More than one init function found for " - "package %S. Previous owner was %S, " - "replacing it with layer %S.") - pkg-name (oref obj :owner) layer-name))) - (oset obj :owner layer-name)) - ;; if no function at all is found for the package, then check - ;; again this layer later to resolve `package-usedp' usage in - ;; `packages.el' files - (unless (or ownerp - (fboundp pre-init-func) - (fboundp post-init-func)) - (add-to-list 'configuration-layer--delayed-layers layer)) - ;; check if toggle can be applied - (when (and (not ownerp) - (listp pkg) - (spacemacs/mplist-get pkg :toggle)) + (dolist (layer layers) + (let* ((layer-name (oref layer :name)) + (layer-dir (oref layer :dir)) + (packages-file (concat layer-dir "packages.el"))) + ;; packages + (when (file-exists-p packages-file) + ;; required for lazy-loading of unused layers + ;; for instance for helm-spacemacs-help + (eval `(defvar ,(intern (format "%S-packages" layer-name)) nil)) + (load packages-file) + (dolist (pkg (symbol-value (intern (format "%S-packages" + layer-name)))) + (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) + (init-func (intern (format "%S/init-%S" + layer-name pkg-name))) + (pre-init-func (intern (format "%S/pre-init-%S" + layer-name pkg-name))) + (post-init-func (intern (format "%S/post-init-%S" + layer-name pkg-name))) + (ownerp (fboundp init-func)) + (obj (object-assoc pkg-name + :name configuration-layer--packages))) + (cl-pushnew pkg-name (oref layer :packages)) + (if obj + (setq obj (configuration-layer/make-package pkg obj ownerp)) + (setq obj (configuration-layer/make-package pkg nil ownerp)) + (push obj configuration-layer--packages)) + (when ownerp + ;; last owner wins over the previous one, + ;; still warn about mutliple owners + (when (and (oref obj :owner) + (not (eq layer-name (oref obj :owner)))) (spacemacs-buffer/warning - (format (concat "Ignoring :toggle for package %s because " - "layer %S does not own it.") - pkg-name layer-name))) - (when (fboundp pre-init-func) - (push layer-name (oref obj :pre-layers))) - (when (fboundp post-init-func) - (push layer-name (oref obj :post-layers)))))))) - ;; additional and excluded packages from dotfile - (when dotfile - (dolist (pkg dotspacemacs-additional-packages) - (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) - (obj (object-assoc pkg-name :name result))) - (if obj - (setq obj (configuration-layer/make-package pkg obj t)) - (setq obj (configuration-layer/make-package pkg nil t)) - (push obj result) - (oset obj :owner 'dotfile)))) - (dolist (xpkg dotspacemacs-excluded-packages) - (let ((obj (object-assoc xpkg :name result))) - (unless obj - (setq obj (configuration-layer/make-package xpkg)) - (push obj result)) - (oset obj :excluded t)))) - result)) + (format (concat "More than one init function found for " + "package %S. Previous owner was %S, " + "replacing it with layer %S.") + pkg-name (oref obj :owner) layer-name))) + (oset obj :owner layer-name)) + ;; if no function at all is found for the package, then check + ;; again this layer later to resolve `package-usedp' usage in + ;; `packages.el' files + (unless (or ownerp + (fboundp pre-init-func) + (fboundp post-init-func)) + (add-to-list 'configuration-layer--delayed-layers layer)) + ;; check if toggle can be applied + (when (and (not ownerp) + (listp pkg) + (spacemacs/mplist-get pkg :toggle)) + (spacemacs-buffer/warning + (format (concat "Ignoring :toggle for package %s because " + "layer %S does not own it.") + pkg-name layer-name))) + (when (fboundp pre-init-func) + (push layer-name (oref obj :pre-layers))) + (when (fboundp post-init-func) + (push layer-name (oref obj :post-layers)))))))) + ;; additional and excluded packages from dotfile + (when dotfile + (dolist (pkg dotspacemacs-additional-packages) + (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) + (obj (object-assoc pkg-name :name configuration-layer--packages))) + (if obj + (setq obj (configuration-layer/make-package pkg obj t)) + (setq obj (configuration-layer/make-package pkg nil t)) + (push obj configuration-layer--packages) + (oset obj :owner 'dotfile)))) + (dolist (xpkg dotspacemacs-excluded-packages) + (let ((obj (object-assoc xpkg :name configuration-layer--packages))) + (unless obj + (setq obj (configuration-layer/make-package xpkg)) + (push obj configuration-layer--packages)) + (oset obj :excluded t))))) (defun configuration-layer//sort-packages (packages) "Return a sorted list of PACKAGES objects." @@ -806,6 +808,7 @@ Possible return values: (let ((files (directory-files path))) ;; most frequent files encoutered in a layer are tested first (when (or (member "packages.el" files) + (member "layers.el" files) (member "config.el" files) (member "keybindings.el" files) (member "funcs.el" files)) @@ -887,34 +890,33 @@ path." (ht-keys configuration-layer-paths))) (dolist (layer dotspacemacs-configuration-layers) (let ((layer-name (if (listp layer) (car layer) layer))) - (if (ht-contains? configuration-layer-paths layer-name) - (unless (string-match-p "+distribution" - (ht-get configuration-layer-paths layer-name)) - (push (configuration-layer/make-layer layer) - configuration-layer--layers)) - (spacemacs-buffer/warning "Unknown layer %s declared in dotfile." - layer-name)))) + (unless (string-match-p "+distribution" + (ht-get configuration-layer-paths layer-name)) + (configuration-layer/declare-layer layer)))) (setq configuration-layer--layers (reverse configuration-layer--layers))) ;; distribution and bootstrap layers are always first (let ((distribution (if configuration-layer-distribution configuration-layer-distribution dotspacemacs-distribution))) (unless (eq 'spacemacs-bootstrap distribution) - (push (configuration-layer/make-layer distribution) - configuration-layer--layers))) - (push (configuration-layer/make-layer 'spacemacs-bootstrap) - configuration-layer--layers)) + (configuration-layer/declare-layer distribution))) + (configuration-layer/declare-layer 'spacemacs-bootstrap)) (defun configuration-layer/declare-layers (layer-names) "Add layers with LAYER-NAMES to used layers." (mapc 'configuration-layer/declare-layer layer-names)) -(defun configuration-layer/declare-layer (layer-name) - "Declare a single layer" - (unless (object-assoc layer-name :name configuration-layer--layers) - (let ((new-layer (configuration-layer/make-layer layer-name))) - (push new-layer configuration-layer--layers) - (configuration-layer//configure-layer new-layer)))) +(defun configuration-layer/declare-layer (layer) + "Declare a single layer." + (let ((layer-name (if (listp layer) (car layer) layer))) + (unless (object-assoc layer-name :name configuration-layer--layers) + (if (ht-contains? configuration-layer-paths layer-name) + (let ((new-layer (configuration-layer/make-layer layer))) + (push new-layer configuration-layer--layers) + (configuration-layer//set-layer-variables new-layer) + (configuration-layer//load-layer-files new-layer '("layers.el"))) + (spacemacs-buffer/warning "Unknown layer %s declared in dotfile." + layer-name))))) (defun configuration-layer/remove-layers (layer-names) "Remove layers with LAYER-NAMES from used layers." @@ -970,27 +972,20 @@ path." (defun configuration-layer//configure-layers (layers) "Configure LAYERS." - ;; FIFO loading of layers, this allow the user to put her layers at the - ;; end of the list to override previous layers. (let ((warning-minimum-level :error)) (dolist (l layers) - (configuration-layer//configure-layer l)))) - -(defun configuration-layer//configure-layer (layer) - "Configure LAYER." - (configuration-layer//set-layer-variables layer) - (configuration-layer//load-layer-files layer '("config.el"))) + (configuration-layer//load-layer-files l '("config.el"))))) (defun configuration-layer//declare-packages (layers) - "Declare all packages contained in LAYERS." - (let* ((warning-minimum-level :error) - ;; first pass - (configuration-layer--packages - (configuration-layer/get-packages layers t))) - (configuration-layer//sort-packages - ;; second pass - (configuration-layer/get-packages - configuration-layer--delayed-layers nil configuration-layer--packages)))) + "Declare packages contained in LAYERS in `configuration-layer--packages'." + (setq configuration-layer--packages nil) + (let* ((warning-minimum-level :error)) + ;; first pass + (configuration-layer/get-packages layers t) + ;; second pass to resolve package-usedp calls + (configuration-layer/get-packages configuration-layer--delayed-layers) + (setq configuration-layer--packages + (configuration-layer//sort-packages configuration-layer--packages)))) (defun configuration-layer//load-layers-files (layers files) "Load the files of list FILES for all passed LAYERS." diff --git a/doc/DOCUMENTATION.org b/doc/DOCUMENTATION.org index b10c23b8a..9bed98ee1 100644 --- a/doc/DOCUMENTATION.org +++ b/doc/DOCUMENTATION.org @@ -340,9 +340,10 @@ Configuration is organized in layers. Each layer has the following structure: | |__ [package 1] | | ... | |__ [package n] - |__ config.el + |-- layers.el |__ packages.el |__ funcs.el + |__ config.el |__ keybindings.el [] = directory @@ -350,12 +351,13 @@ Configuration is organized in layers. Each layer has the following structure: Where: -| File | Usage | -|----------------+-----------------------------------------------------------------------------------| -| config.el | Layer configuration (defines the layer variables and setup some config variables) | -| packages.el | The list of packages and their configuration functions (init, post-init, etc...) | -| funcs.el | All functions defined in the layer (used in package configuration for instance) | -| keybindings.el | General key bindings no tied to a specific package configuration | +| File | Usage | +|----------------+--------------------------------------------------------------------------------------------------| +| layers.el | The place to declare additional layers | +| packages.el | The list of packages and their configuration functions (init, post-init, etc...) | +| funcs.el | All functions defined in the layer (used in package configuration for instance) | +| config.el | Layer configuration (defines the layer variables default values and setup some config variables) | +| keybindings.el | General key bindings no tied to a specific package configuration | =Packages= can be: - =ELPA= packages installed from an =ELPA= compliant repository diff --git a/doc/LAYERS.org b/doc/LAYERS.org index f7d14f7e8..6f0ad58f9 100644 --- a/doc/LAYERS.org +++ b/doc/LAYERS.org @@ -12,9 +12,10 @@ - [[#eval-after-load][Eval after load]] - [[#use-package][Use-package]] - [[#anatomy-of-a-layer][Anatomy of a layer]] - - [[#configel][config.el]] + - [[#layersel][layers.el]] - [[#packagesel][packages.el]] - [[#funcsel][funcs.el]] + - [[#configel][config.el]] - [[#keybindingsel][keybindings.el]] - [[#the-spacemacs-loading-process][The Spacemacs loading process]] - [[#case-study-auto-completion][Case study: auto-completion]] @@ -277,11 +278,12 @@ more. * Anatomy of a layer A layer is simply a folder somewhere in Spacemacs' layer search path that -usually contains these files. +usually contains these files (listed in loading order). -- =config.el= :: layer specific configuration +- =layers.el= :: declare additional layers - =packages.el= :: the packages list and configuration - =funcs.el= :: all functions used in the layer should be declared here +- =config.el= :: layer specific configuration - =keybindings.el= :: general key bindings Additionally, for each local package (see the next section), there should be a @@ -289,16 +291,26 @@ folder =/local//= containing the source code for that package. Before initializing that package, Spacemacs will add this folder to the load path for you. -** config.el -This file configure the layer like declaring layer variables and setup some -other variables related to the layer. +** layers.el +This file is the first file to be loaded and this is the place where addtional +layers can be declared. -This is the first file loaded when loading a layer. +For instance is layer A depends on some functionality of layer B then in the +file =layers.el= of layer A we can add: + +#+begin_src emacs-lisp +(configuration-layer/declare-layer 'B) +#+end_src + +The effect is that B is considered a used layer and will be loaded as if it +was added to =dotspacemacs-configuration-layers= variables. ** packages.el It contains this list of packages of the layer and the actual configuration for the packages included in the layer. +This file is loaded after =layers.el=. + It must define a variable called =-packages=, which should be a list of all the packages that this layer needs. Some valid package specifications are as follows: @@ -352,7 +364,7 @@ discuss later. ** funcs.el It contains all the defined functions used in the layer. -This file is loaded _after_ =config.el= and =packages.el=. +This file is loaded after =packages.el= and before =config.el=. It is good practice to guard the definition of functions to make sure a package is actually used. For instance: @@ -366,9 +378,17 @@ is actually used. For instance: By guarding these functions we avoid to define them in case the package `my-package` is not used. +** config.el +This file configure the layer like declaring layer variables default values +and setup some other variables related to the layer. + +This file is loaded after =funcs.el=. + ** keybindings.el It contains general key bindings. +This is the last file loaded. + The word /general/ here means /independent of any package/. Since the end user can exclude an arbitrary set of packages, you cannot be sure that, just because your layer includes a package, that package will necessarily be loaded. For this diff --git a/tests/core/core-configuration-layer-ftest.el b/tests/core/core-configuration-layer-ftest.el index 4af627bdd..0eb5b32c0 100644 --- a/tests/core/core-configuration-layer-ftest.el +++ b/tests/core/core-configuration-layer-ftest.el @@ -17,27 +17,42 @@ (ert-deftest test-declare-layers--bootstrap-layer-always-first () (let ((dotspacemacs-distribution 'spacemacs) (dotspacemacs-configuration-layers '(emacs-lisp - (git :variables foo 'bar)))) - (configuration-layer//declare-layers) - (should (eq 'spacemacs-bootstrap - (oref (first configuration-layer--layers) :name))))) + (git :variables foo 'bar))) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((load (f) ((:output nil)))) + (let (configuration-layer--layers) + (configuration-layer//declare-layers) + (should (eq 'spacemacs-bootstrap + (oref (first configuration-layer--layers) :name))))))) (ert-deftest test-declare-layers--bootstrap-layer-always-first-all () (let ((dotspacemacs-distribution 'spacemacs) - (dotspacemacs-configuration-layers 'all)) - (configuration-layer//declare-layers) - (should (eq 'spacemacs-bootstrap - (oref (first configuration-layer--layers) :name))))) + (dotspacemacs-configuration-layers 'all) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((load (f) ((:output nil)))) + (let (configuration-layer--layers) + (configuration-layer//declare-layers) + (should (eq 'spacemacs-bootstrap + (oref (first configuration-layer--layers) :name))))))) -(ert-deftest test-declare-layers--distribution-layer-always-second () - (let ((dotspacemacs-distribution 'spacemacs) +(ert-deftest test-declare-layers--distribution-layer-is-second () + (let ((dotspacemacs-distribution 'spacemacs-base) (dotspacemacs-configuration-layers '(emacs-lisp (git :variables foo 'bar)))) - (configuration-layer//declare-layers) - (should (eq 'spacemacs (oref (second configuration-layer--layers) :name))))) + (let (configuration-layer--layers) + (configuration-layer//declare-layers) + (should (eq 'spacemacs-base + (oref (second configuration-layer--layers) :name)))))) -(ert-deftest test-declare-layers--distribution-layer-always-second-all () - (let ((dotspacemacs-distribution 'spacemacs) - (dotspacemacs-configuration-layers 'all)) - (configuration-layer//declare-layers) - (should (eq 'spacemacs (oref (second configuration-layer--layers) :name))))) +(ert-deftest test-declare-layers--distribution-layer-position-with-all-layers () + (let ((dotspacemacs-distribution 'spacemacs-base) + (dotspacemacs-configuration-layers 'all) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((load (f) ((:output nil)))) + (let (configuration-layer--layers) + (configuration-layer//declare-layers) + (should (eq 'spacemacs-base + (oref (second configuration-layer--layers) :name))))))) diff --git a/tests/core/core-configuration-layer-utest.el b/tests/core/core-configuration-layer-utest.el index 33c5af23a..19c4dd356 100644 --- a/tests/core/core-configuration-layer-utest.el +++ b/tests/core/core-configuration-layer-utest.el @@ -286,7 +286,7 @@ ;; --------------------------------------------------------------------------- (ert-deftest test-get-packages--symbols-only () - (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path")) + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) (layers (list layer1)) (layer1-packages '(pkg1 pkg2 pkg3)) (mocker-mock-default-record-cls 'mocker-stub-record)) @@ -295,14 +295,16 @@ (defun layer1/init-pkg3 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1)) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--lists-only () - (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path")) + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) (layers (list layer1)) (layer1-packages '((pkg1 :location elpa :excluded t) (pkg2 :location (recipe blahblah)) @@ -313,14 +315,16 @@ (defun layer1/init-pkg3 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1 :location 'local :step 'pre) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1 :location '(recipe blahblah)) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1 :excluded t)) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1 :location 'local :step 'pre) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1 :location '(recipe blahblah)) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1 :excluded t)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--symbols-and-lists () - (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path")) + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) (layers (list layer1)) (layer1-packages '(pkg1 (pkg2 :location (recipe blahblah)) @@ -333,15 +337,17 @@ (defun layer1/init-pkg4 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg4" :name 'pkg4 :owner 'layer1) - (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1 :location 'local :step 'pre) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1 :location '(recipe blahblah)) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1)) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg4" :name 'pkg4 :owner 'layer1) + (cfgl-package "pkg3" :name 'pkg3 :owner 'layer1 :location 'local :step 'pre) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer1 :location '(recipe blahblah)) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer1)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--pkg2-has-no-owner-because-no-init-function () - (let* ((layer2 (cfgl-layer "layer2" :name 'layer2 :dir "/path")) + (let* ((layer2 (cfgl-layer "layer2" :name 'layer2 :dir "/path/")) (layers (list layer2)) (layer2-packages '(pkg1 pkg2 pkg3)) (mocker-mock-default-record-cls 'mocker-stub-record)) @@ -349,15 +355,17 @@ (defun layer2/init-pkg3 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer2) - (cfgl-package "pkg2" :name 'pkg2) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer2)) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer2) + (cfgl-package "pkg2" :name 'pkg2) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer2)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--pre-init-function () - (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path")) - (layer4 (cfgl-layer "layer4" :name 'layer4 :dir "/path")) + (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path/")) + (layer4 (cfgl-layer "layer4" :name 'layer4 :dir "/path/")) (layers (list layer3 layer4)) (layer3-packages '(pkg1)) (layer4-packages '(pkg1)) @@ -365,15 +373,16 @@ (defun layer3/init-pkg1 nil) (defun layer4/pre-init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :pre-layers '(layer4))) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :pre-layers '(layer4))) + configuration-layer--packages)))))) (ert-deftest test-get-packages--post-init-function () - (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path")) - (layer5 (cfgl-layer "layer5" :name 'layer5 :dir "/path")) + (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path/")) + (layer5 (cfgl-layer "layer5" :name 'layer5 :dir "/path/")) (layers (list layer3 layer5)) (layer3-packages '(pkg1)) (layer5-packages '(pkg1)) @@ -381,15 +390,16 @@ (defun layer3/init-pkg1 nil) (defun layer5/post-init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :post-layers '(layer5))) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :post-layers '(layer5))) + configuration-layer--packages)))))) (ert-deftest test-get-packages--pre-and-post-init-functions () - (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path")) - (layer6 (cfgl-layer "layer6" :name 'layer6 :dir "/path")) + (let* ((layer3 (cfgl-layer "layer3" :name 'layer3 :dir "/path/")) + (layer6 (cfgl-layer "layer6" :name 'layer6 :dir "/path/")) (layers (list layer3 layer6)) (layer3-packages '(pkg1)) (layer6-packages '(pkg1)) @@ -398,15 +408,16 @@ (defun layer6/pre-init-pkg1 nil) (defun layer6/post-init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :pre-layers '(layer6) :post-layers '(layer6))) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer3 :pre-layers '(layer6) :post-layers '(layer6))) + configuration-layer--packages)))))) (ert-deftest test-get-packages--several-init-functions-last-one-is-the-owner () - (let* ((layer7 (cfgl-layer "layer7" :name 'layer7 :dir "/path")) - (layer8 (cfgl-layer "layer8" :name 'layer8 :dir "/path")) + (let* ((layer7 (cfgl-layer "layer7" :name 'layer7 :dir "/path/")) + (layer8 (cfgl-layer "layer8" :name 'layer8 :dir "/path/")) (layers (list layer7 layer8)) (layer7-packages '(pkg1)) (layer8-packages '(pkg1)) @@ -414,16 +425,17 @@ (defun layer7/init-pkg1 nil) (defun layer8/init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer8)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer8)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--layer-10-excludes-pkg2-in-layer-9 () - (let* ((layer9 (cfgl-layer "layer9" :name 'layer9 :dir "/path")) - (layer10 (cfgl-layer "layer10" :name 'layer10 :dir "/path")) + (let* ((layer9 (cfgl-layer "layer9" :name 'layer9 :dir "/path/")) + (layer10 (cfgl-layer "layer10" :name 'layer10 :dir "/path/")) (layers (list layer9 layer10)) (layer9-packages '(pkg1 pkg2)) (layer10-packages '(pkg3 (pkg2 :excluded t))) @@ -432,16 +444,17 @@ (defun layer9/init-pkg2 nil) (defun layer10/init-pkg3 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer10) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer9 :excluded t) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer9)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer10) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer9 :excluded t) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer9)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--dotfile-excludes-pkg2-in-layer-11 () - (let* ((layer11 (cfgl-layer "layer11" :name 'layer11 :dir "/path")) + (let* ((layer11 (cfgl-layer "layer11" :name 'layer11 :dir "/path/")) (layers (list layer11)) (layer11-packages '(pkg1 pkg2 pkg3)) (dotspacemacs-excluded-packages '(pkg2)) @@ -451,14 +464,16 @@ (defun layer11/init-pkg3 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer11) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer11 :excluded t) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer11)) - (configuration-layer/get-packages layers t)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers t) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'layer11) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer11 :excluded t) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer11)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--dotfile-declares-and-owns-one-additional-package () - (let* ((layer12 (cfgl-layer "layer12" :name 'layer12 :dir "/path")) + (let* ((layer12 (cfgl-layer "layer12" :name 'layer12 :dir "/path/")) (layers (list layer12)) (layer12-packages '(pkg1 pkg2)) (dotspacemacs-additional-packages '(pkg3)) @@ -467,15 +482,17 @@ (defun layer12/init-pkg2 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'dotfile) - (cfgl-package "pkg2" :name 'pkg2 :owner 'layer12) - (cfgl-package "pkg1" :name 'pkg1 :owner 'layer12)) - (configuration-layer/get-packages layers t)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers t) + (should (equal (list (cfgl-package "pkg3" :name 'pkg3 :owner 'dotfile) + (cfgl-package "pkg2" :name 'pkg2 :owner 'layer12) + (cfgl-package "pkg1" :name 'pkg1 :owner 'layer12)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--last-owner-can-overwrite-location () - (let* ((layer13 (cfgl-layer "layer13" :name 'layer13 :dir "/path")) - (layer14 (cfgl-layer "layer14" :name 'layer14 :dir "/path")) + (let* ((layer13 (cfgl-layer "layer13" :name 'layer13 :dir "/path/")) + (layer14 (cfgl-layer "layer14" :name 'layer14 :dir "/path/")) (layers (list layer13 layer14)) (layer13-packages '((pkg1 :location elpa))) (layer14-packages '((pkg1 :location local))) @@ -483,16 +500,17 @@ (defun layer13/init-pkg1 nil) (defun layer14/init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer14 :location 'local)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer14 :location 'local)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--last-owner-can-overwrite-step-nil-to-pre () - (let* ((layer15 (cfgl-layer "layer15" :name 'layer15 :dir "/path")) - (layer16 (cfgl-layer "layer16" :name 'layer16 :dir "/path")) + (let* ((layer15 (cfgl-layer "layer15" :name 'layer15 :dir "/path/")) + (layer16 (cfgl-layer "layer16" :name 'layer16 :dir "/path/")) (layers (list layer15 layer16)) (layer15-packages '((pkg1 :step nil))) (layer16-packages '((pkg1 :step pre))) @@ -500,16 +518,17 @@ (defun layer15/init-pkg1 nil) (defun layer16/init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer16 :step 'pre)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer16 :step 'pre)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--last-owner-cannot-overwrite-step-pre-to-nil () - (let* ((layer15 (cfgl-layer "layer15" :name 'layer15 :dir "/path")) - (layer16 (cfgl-layer "layer16" :name 'layer16 :dir "/path")) + (let* ((layer15 (cfgl-layer "layer15" :name 'layer15 :dir "/path/")) + (layer16 (cfgl-layer "layer16" :name 'layer16 :dir "/path/")) (layers (list layer15 layer16)) (layer15-packages '((pkg1 :step pre))) (layer16-packages '((pkg1 :step nil))) @@ -517,16 +536,17 @@ (defun layer15/init-pkg1 nil) (defun layer16/init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer16 :step 'pre)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer16 :step 'pre)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--last-owner-can-overwrite-exclude () - (let* ((layer17 (cfgl-layer "layer17" :name 'layer17 :dir "/path")) - (layer18 (cfgl-layer "layer18" :name 'layer18 :dir "/path")) + (let* ((layer17 (cfgl-layer "layer17" :name 'layer17 :dir "/path/")) + (layer18 (cfgl-layer "layer18" :name 'layer18 :dir "/path/")) (layers (list layer17 layer18)) (layer17-packages '(pkg1)) (layer18-packages '((pkg1 :excluded t))) @@ -534,31 +554,34 @@ (defun layer17/init-pkg1 nil) (defun layer18/init-pkg1 nil) (mocker-let - ((file-exists-p (f) ((:output t :occur 1) - (:output t :occur 1))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer18 :excluded t)) - (configuration-layer/get-packages layers)))))) + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer18 :excluded t)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--owner-layer-can-define-toggle () - (let* ((layer19 (cfgl-layer "layer19" :name 'layer19 :dir "/path")) + (let* ((layer19 (cfgl-layer "layer19" :name 'layer19 :dir "/path/")) (layers (list layer19)) (layer19-packages '((pkg1 :toggle (foo-toggle)))) (mocker-mock-default-record-cls 'mocker-stub-record)) (defun layer19/init-pkg1 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg1" - :name 'pkg1 - :owner 'layer19 - :toggle '(foo-toggle))) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" + :name 'pkg1 + :owner 'layer19 + :toggle '(foo-toggle))) + configuration-layer--packages)))))) (ert-deftest test-get-packages--not-owner-layer-cannot-define-toggle () - (let* ((layer20 (cfgl-layer "layer20" :name 'layer20 :dir "/path")) - (layer21 (cfgl-layer "layer21" :name 'layer21 :dir "/path")) + (let* ((layer20 (cfgl-layer "layer20" :name 'layer20 :dir "/path/")) + (layer21 (cfgl-layer "layer21" :name 'layer21 :dir "/path/")) (layers (list layer20 layer21)) (layer20-packages '((pkg1))) (layer21-packages '((pkg1 :toggle (foo-toggle)))) @@ -567,18 +590,20 @@ (defun layer21/post-init-pkg1 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 2))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" - :name 'pkg1 - :owner 'layer20 - :post-layers '(layer21) - :toggle t)) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" + :name 'pkg1 + :owner 'layer20 + :post-layers '(layer21) + :toggle t)) + configuration-layer--packages)))))) (ert-deftest test-get-packages--new-owner-layer-can-override-toggle () - (let* ((layer22 (cfgl-layer "layer22" :name 'layer22 :dir "/path")) - (layer23 (cfgl-layer "layer23" :name 'layer23 :dir "/path")) + (let* ((layer22 (cfgl-layer "layer22" :name 'layer22 :dir "/path/")) + (layer23 (cfgl-layer "layer23" :name 'layer23 :dir "/path/")) (layers (list layer22 layer23)) (layer22-packages '((pkg1 :toggle (foo-toggle)))) (layer23-packages '((pkg1 :toggle (bar-toggle)))) @@ -587,17 +612,19 @@ (defun layer23/init-pkg1 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 2))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" - :name 'pkg1 - :owner 'layer23 - :toggle '(bar-toggle))) - (configuration-layer/get-packages layers)))))) + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" + :name 'pkg1 + :owner 'layer23 + :toggle '(bar-toggle))) + configuration-layer--packages)))))) (ert-deftest test-get-packages--dotfile-additional-pkg-can-override-toggle () - (let* ((layer22 (cfgl-layer "layer22" :name 'layer22 :dir "/path")) - (layer23 (cfgl-layer "layer23" :name 'layer23 :dir "/path")) + (let* ((layer22 (cfgl-layer "layer22" :name 'layer22 :dir "/path/")) + (layer23 (cfgl-layer "layer23" :name 'layer23 :dir "/path/")) (layers (list layer22 layer23)) (layer22-packages '((pkg1 :toggle (foo-toggle)))) (layer23-packages '((pkg1 :toggle (bar-toggle)))) @@ -606,29 +633,15 @@ (defun layer23/init-pkg1 nil) (mocker-let ((file-exists-p (f) ((:output t :occur 2))) - (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 2)))) - (should (equal (list (cfgl-package "pkg1" + (load (f) ((:output nil :occur 2))) + (spacemacs-buffer/warning (msg &rest args) ((:output nil :occur 1)))) + (let (configuration-layer--packages) + (configuration-layer/get-packages layers) + (should (equal (list (cfgl-package "pkg1" :name 'pkg1 :owner 'layer23 :toggle '(bar-toggle))) - (configuration-layer/get-packages layers)))))) - -(ert-deftest test-get-packages--dotfile-additional-pkg-can-override-toggle () - (let* ((layer24 (cfgl-layer "layer24" :name 'layer24 :dir "/path")) - (layers (list layer24)) - (layer24-packages '((pkg1 :toggle (foo-toggle)))) - (dotspacemacs-additional-packages '((pkg1 :toggle (bar-toggle)))) - (mocker-mock-default-record-cls 'mocker-stub-record)) - (defun layer24/init-pkg1 nil) - (mocker-let - ((file-exists-p (f) ((:output t :occur 1))) - (configuration-layer/layer-usedp (l) ((:output t :occur 1)))) - (should (equal (list (cfgl-package "pkg1" - :name 'pkg1 - :owner 'layer24 - :toggle '(bar-toggle))) - (configuration-layer/get-packages layers t)))))) + configuration-layer--packages)))))) ;; --------------------------------------------------------------------------- ;; configuration-layer//configure-package @@ -1029,7 +1042,7 @@ ;; --------------------------------------------------------------------------- (ert-deftest test-package-usedp--package-with-owner-can-be-used () - (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path")) + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) (layers (list layer1)) (layer1-packages '(pkg1 pkg2 pkg3)) (mocker-mock-default-record-cls 'mocker-stub-record) @@ -1041,7 +1054,7 @@ layer1-packages))))) (ert-deftest test-package-usedp--package-with-no-owner-cannot-be-used () - (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path")) + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) (layers (list layer1)) (layer1-packages '(pkg1 pkg2 pkg3)) (mocker-mock-default-record-cls 'mocker-stub-record)