diff --git a/doc/overlays.xml b/doc/overlays.xml
index ad31b90299e7..cc0aef447d2d 100644
--- a/doc/overlays.xml
+++ b/doc/overlays.xml
@@ -17,42 +17,68 @@ if multiple layers override the same package.
Installing overlays
-The list of overlays is determined as follows:
+The list of overlays is determined as follows.
+
+If the overlays argument is not provided explicitly, we look for overlays in a path. The path
+is determined as follows:
First, if an overlays argument to the nixpkgs function itself is given,
- then that is used. This can be passed explicitly when importing nipxkgs, for example
- import <nixpkgs> { overlays = [ overlay1 overlay2 ] }.
+ then that is used.
- On a NixOS system the value of the nixpkgs.overlays option, if present,
- is passed to the system Nixpkgs in this way. Note that this does not affect the overlays for
- non-NixOS operations (e.g. nix-env), which are looked up independently.
+ This can be passed explicitly when importing nipxkgs, for example
+ import <nixpkgs> { overlays = [ overlay1 overlay2 ]; }.
- Otherwise, if the Nix path entry <nixpkgs-overlays> exists and is a
- directory, then the result is the set of overlays found in that directory, ordered lexicographically.
+ Otherwise, if the Nix path entry <nixpkgs-overlays> exists, we look for overlays
+ at that path, as described below.
See the section on NIX_PATH in the Nix manual for more details on how to
set a value for <nixpkgs-overlays>.
- Otherwise, if ~/.config/nixpkgs/overlays/ exists and is a directory, then
- the result is the set of overlays found in that directory, ordered lexicographically.
+ If one of ~/.config/nixpkgs/overlays.nix and
+ ~/.config/nixpkgs/overlays/ exists, then we look for overlays at that path, as
+ described below. It is an error if both exist.
-For the second and third options, overlays are extracted from the given directory as files,
-directories containing a default.nix, or symlinks to one of those.
+If we are looking for overlays at a path, then there are two cases:
+
+
+ If the path is a file, then the file is imported as a Nix expression and used as the list of
+ overlays.
+
-The last option provides a convenient way to install an overlay from a repository,
-by cloning the overlay's repository and adding a symbolic link to it in
-~/.config/nixpkgs/overlays/.
+
+ If the path is a directory, then we take the content of the directory, order it
+ lexicographically, and attempt to interpret each as an overlay by:
+
+
+ Importing the file, if it is a .nix file.
+
+
+ Importing a top-level default.nix file, if it is a directory.
+
+
+
+
+
+
+
+On a NixOS system the value of the nixpkgs.overlays option, if present,
+is passed to the system Nixpkgs directly as an argument. Note that this does not affect the overlays for
+non-NixOS operations (e.g. nix-env), which are looked up independently.
+
+The overlays.nix option therefore provides a convenient way to use the same
+overlays for a NixOS system configuration and user configuration: the same file can be used
+as overlays.nix and imported as the value of nixpkgs.overlays.
diff --git a/pkgs/top-level/impure.nix b/pkgs/top-level/impure.nix
index c0cf8fb09113..a4d313a1b991 100644
--- a/pkgs/top-level/impure.nix
+++ b/pkgs/top-level/impure.nix
@@ -40,18 +40,36 @@ in
# collections of packages. These collection of packages are part of the
# fix-point made by Nixpkgs.
overlays ? let
- dirPath = try (if pathExists then else "") "";
- dirHome = homeDir + "/.config/nixpkgs/overlays";
- dirCheck = dir: dir != "" && pathExists (dir + "/.");
- overlays = dir:
- let content = readDir dir; in
- map (n: import (dir + ("/" + n)))
- (builtins.filter (n: builtins.match ".*\.nix" n != null || pathExists (dir + ("/" + n + "/default.nix")))
- (attrNames content));
+ isDir = path: pathExists (path + "/.");
+ pathOverlays = try "";
+ homeOverlaysFile = homeDir + "/.config/nixpkgs/overlays.nix";
+ homeOverlaysDir = homeDir + "/.config/nixpkgs/overlays";
+ overlays = path:
+ # check if the path is a directory or a file
+ if isDir path then
+ # it's a directory, so the set of overlays from the directory, ordered lexicographically
+ let content = readDir path; in
+ map (n: import (path + ("/" + n)))
+ (builtins.filter (n: builtins.match ".*\.nix" n != null || pathExists (path + ("/" + n + "/default.nix")))
+ (attrNames content))
+ else
+ # it's a file, so the result is the contents of the file itself
+ import path;
in
- if dirPath != "" then
- overlays dirPath
- else if dirCheck dirHome then overlays dirHome
+ if pathOverlays != "" && pathExists pathOverlays then overlays pathOverlays
+ else if pathExists homeOverlaysFile && pathExists homeOverlaysDir then
+ throw ''
+ Nixpkgs overlays can be specified with ${homeOverlaysFile} or ${homeOverlaysDir}, but not both.
+ Please remove one of them and try again.
+ ''
+ else if pathExists homeOverlaysFile then
+ if isDir homeOverlaysFile then
+ throw (homeOverlaysFile + " should be a file")
+ else overlays homeOverlaysFile
+ else if pathExists homeOverlaysDir then
+ if !(isDir homeOverlaysDir) then
+ throw (homeOverlaysDir + " should be a directory")
+ else overlays homeOverlaysDir
else []
, ...