core: new layer file -> layers.el / Fix regressions of previous commits

The new layer file `layers.el` is used to declared additional layers.
It is like the sibling of packages.el except that for now it does not
take a list (can do this in a futur commit).

The new order for file loading is the following:

layers.el > packages.el > funcs.el > config.el > keybindings.el

Since packages.el relies on some undefined stuff encapsulated
in init functions, it is not meant to be byte compiled. OTOH funcs.el
(where lies most of the computation added by a package config) should
be compilable.

Since we load packages.el very early it is not possible to use
`configuration-layer/package-usedp` in funcs.el.

This commit also fixes the tests.
This commit is contained in:
syl20bnr 2016-05-28 21:20:23 -04:00
parent ee59df2ab0
commit d98be63dfa
5 changed files with 348 additions and 303 deletions

View File

@ -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."

View File

@ -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

View File

@ -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 =<layer>/local/<package>/= 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 =<layer>-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

View File

@ -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)))))))

View File

@ -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)