From 9235ff1259bb9425c58ac3b3322ddf83e74a4255 Mon Sep 17 00:00:00 2001 From: Michael Peyton Jones Date: Wed, 9 Aug 2017 19:47:27 +0100 Subject: [PATCH] Overlays: allow overlays to be specified in a file --- doc/overlays.xml | 56 ++++++++++++++++++++++++++++----------- pkgs/top-level/impure.nix | 40 ++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/doc/overlays.xml b/doc/overlays.xml index ad31b90299e..cc0aef447d2 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 c0cf8fb0911..a4d313a1b99 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 [] , ...