summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/overlays.xml56
-rw-r--r--pkgs/top-level/impure.nix40
2 files changed, 70 insertions, 26 deletions
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.</para>
 <section xml:id="sec-overlays-install">
 <title>Installing overlays</title>
 
-<para>The list of overlays is determined as follows:
+<para>The list of overlays is determined as follows.</para>
+
+<para>If the <varname>overlays</varname> argument is not provided explicitly, we look for overlays in a path. The path
+is determined as follows:
 
 <orderedlist>
 
   <listitem>
     <para>First, if an <varname>overlays</varname> argument to the nixpkgs function itself is given,
-    then that is used. This can be passed explicitly when importing nipxkgs, for example 
-    <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ] }</literal>.</para>
+    then that is used.</para>
 
-    <para>On a NixOS system the value of the <literal>nixpkgs.overlays</literal> 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. <literal>nix-env</literal>), which are looked up independently.</para>
+    <para>This can be passed explicitly when importing nipxkgs, for example 
+    <literal>import &lt;nixpkgs> { overlays = [ overlay1 overlay2 ]; }</literal>.</para>
   </listitem>
 
   <listitem>
-    <para>Otherwise, if the Nix path entry <literal>&lt;nixpkgs-overlays></literal> exists and is a 
-    directory, then the result is the set of overlays found in that directory, ordered lexicographically.</para> 
+    <para>Otherwise, if the Nix path entry <literal>&lt;nixpkgs-overlays></literal> exists, we look for overlays
+    at that path, as described below.</para>
 
     <para>See the section on <literal>NIX_PATH</literal> in the Nix manual for more details on how to 
     set a value for <literal>&lt;nixpkgs-overlays>.</literal></para>
   </listitem>
 
   <listitem>
-    <para>Otherwise, if <filename>~/.config/nixpkgs/overlays/</filename> exists and is a directory, then
-    the result is the set of overlays found in that directory, ordered lexicographically.</para>
+    <para>If one of <filename>~/.config/nixpkgs/overlays.nix</filename> and
+    <filename>~/.config/nixpkgs/overlays/</filename> exists, then we look for overlays at that path, as
+    described below. It is an error if both exist.</para>
   </listitem>
 
 </orderedlist>
 </para>
 
-<para>For the second and third options, overlays are extracted from the given directory as files, 
-directories containing a <filename>default.nix</filename>, or symlinks to one of those.</para>
+<para>If we are looking for overlays at a path, then there are two cases:
+<itemizedlist>
+  <listitem>
+    <para>If the path is a file, then the file is imported as a Nix expression and used as the list of
+    overlays.</para>
+  </listitem>
+
+  <listitem>
+    <para>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:
+    <itemizedlist>
+      <listitem>
+        <para>Importing the file, if it is a <literal>.nix</literal> file.</para>
+      </listitem>
+      <listitem>
+        <para>Importing a top-level <filename>default.nix</filename> file, if it is a directory.</para>
+      </listitem>
+    </itemizedlist>
+    </para>
+  </listitem>
+</itemizedlist>
+</para>
+
+<para>On a NixOS system the value of the <literal>nixpkgs.overlays</literal> 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. <literal>nix-env</literal>), which are looked up independently.</para>
 
-<para>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 
-<filename>~/.config/nixpkgs/overlays/</filename>.</para>
+<para>The <filename>overlays.nix</filename> 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 <filename>overlays.nix</filename> and imported as the value of <literal>nixpkgs.overlays</literal>.</para>
 
 </section>
 
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 <nixpkgs-overlays> then <nixpkgs-overlays> 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 <nixpkgs-overlays> "";
+      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 []
 
 , ...