nix: add a declarative alternative to Nix channels (#4031)
* nix: add options 'nixPath' and 'keepOldNixPath' By default, the system value for $NIX_PATH is kept as a fallback. To completely override the system value for $NIX_PATH: nix.keepOldNixPath = false; * nix: add more tests * nix: add a declarative alternative to Nix channels This adds a new option, 'nix.channels'. It's the Nix channels equivalent of the 'nix.registry' option, and compatible with pre-Flake Nix tooling including nix-env and nix-shell. Like 'nix.registry', this option is useful for pinning Nix channels. Channels defined in the new option can coexist with channels introduced through the nix-channel command. If the same channel exists in both, the one from Home Manager will be prioritized. * nix: add news entry * nix: make channels respect use-xdg-base-directories * nix: remove 'with lib;' --------- Co-authored-by: Michael Hoang <enzime@users.noreply.github.com>
This commit is contained in:
parent
892f76bd0a
commit
8d5e27b480
|
@ -1656,6 +1656,17 @@ in {
|
||||||
See https://codeberg.org/dnkl/yambar for more.
|
See https://codeberg.org/dnkl/yambar for more.
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
time = "2024-05-25T14:36:03+00:00";
|
||||||
|
message = ''
|
||||||
|
Multiple new options are available:
|
||||||
|
|
||||||
|
- 'nix.nixPath'
|
||||||
|
- 'nix.keepOldNixPath'
|
||||||
|
- 'nix.channels'
|
||||||
|
'';
|
||||||
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,40 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
inherit (lib)
|
||||||
|
boolToString concatStringsSep escape floatToString getVersion isBool
|
||||||
|
isConvertibleWithToString isDerivation isFloat isInt isList isString
|
||||||
|
literalExpression maintainers mapAttrsToList mkDefault mkEnableOption mkIf
|
||||||
|
mkMerge mkOption optionalString toPretty types versionAtLeast;
|
||||||
|
|
||||||
cfg = config.nix;
|
cfg = config.nix;
|
||||||
|
|
||||||
nixPackage = cfg.package;
|
nixPackage = cfg.package;
|
||||||
|
|
||||||
isNixAtLeast = versionAtLeast (getVersion nixPackage);
|
isNixAtLeast = versionAtLeast (getVersion nixPackage);
|
||||||
|
|
||||||
|
nixPath = concatStringsSep ":" cfg.nixPath;
|
||||||
|
|
||||||
|
useXdg = config.nix.enable
|
||||||
|
&& (config.nix.settings.use-xdg-base-directories or false);
|
||||||
|
defexprDir = if useXdg then
|
||||||
|
"${config.xdg.stateHome}/nix/defexpr"
|
||||||
|
else
|
||||||
|
"${config.home.homeDirectory}/.nix-defexpr";
|
||||||
|
|
||||||
|
# The deploy path for declarative channels. The directory name is prefixed
|
||||||
|
# with a number to make it easier for files in defexprDir to control the order
|
||||||
|
# they'll be read relative to each other.
|
||||||
|
channelPath = "${defexprDir}/50-home-manager";
|
||||||
|
|
||||||
|
channelsDrv = let
|
||||||
|
mkEntry = name: drv: {
|
||||||
|
inherit name;
|
||||||
|
path = toString drv;
|
||||||
|
};
|
||||||
|
in pkgs.linkFarm "channels" (lib.mapAttrsToList mkEntry cfg.channels);
|
||||||
|
|
||||||
nixConf = assert isNixAtLeast "2.2";
|
nixConf = assert isNixAtLeast "2.2";
|
||||||
let
|
let
|
||||||
|
|
||||||
|
@ -102,6 +127,47 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nixPath = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
example = [
|
||||||
|
"$HOME/.nix-defexpr/channels"
|
||||||
|
"darwin-config=$HOME/.config/nixpkgs/darwin-configuration.nix"
|
||||||
|
];
|
||||||
|
description = ''
|
||||||
|
Adds new directories to the Nix expression search path.
|
||||||
|
|
||||||
|
Used by Nix when looking up paths in angular brackets
|
||||||
|
(e.g. `<nixpkgs>`).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
keepOldNixPath = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
description = ''
|
||||||
|
Whether {option}`nix.nixPath` should keep the previously set values in
|
||||||
|
{env}`NIX_PATH`.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
channels = lib.mkOption {
|
||||||
|
type = with lib.types; attrsOf package;
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression "{ inherit nixpkgs; }";
|
||||||
|
description = ''
|
||||||
|
A declarative alternative to Nix channels. Whereas with stock channels,
|
||||||
|
you would register URLs and fetch them into the Nix store with
|
||||||
|
{manpage}`nix-channel(1)`, this option allows you to register the store
|
||||||
|
path directly. One particularly useful example is registering flake
|
||||||
|
inputs as channels.
|
||||||
|
|
||||||
|
This option can coexist with stock Nix channels. If the same channel is
|
||||||
|
defined in both, this option takes precedence.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
registry = mkOption {
|
registry = mkOption {
|
||||||
type = types.attrsOf (types.submodule (let
|
type = types.attrsOf (types.submodule (let
|
||||||
inputAttrs = types.attrsOf
|
inputAttrs = types.attrsOf
|
||||||
|
@ -210,6 +276,19 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (mkMerge [
|
config = mkIf cfg.enable (mkMerge [
|
||||||
|
(mkIf (cfg.nixPath != [ ] && !cfg.keepOldNixPath) {
|
||||||
|
home.sessionVariables.NIX_PATH = "${nixPath}";
|
||||||
|
})
|
||||||
|
|
||||||
|
(mkIf (cfg.nixPath != [ ] && cfg.keepOldNixPath) {
|
||||||
|
home.sessionVariables.NIX_PATH = "${nixPath}\${NIX_PATH:+:$NIX_PATH}";
|
||||||
|
})
|
||||||
|
|
||||||
|
(lib.mkIf (cfg.channels != { }) {
|
||||||
|
nix.nixPath = [ channelPath ];
|
||||||
|
home.file."${channelPath}".source = channelsDrv;
|
||||||
|
})
|
||||||
|
|
||||||
(mkIf (cfg.registry != { }) {
|
(mkIf (cfg.registry != { }) {
|
||||||
xdg.configFile."nix/registry.json".source =
|
xdg.configFile."nix/registry.json".source =
|
||||||
jsonFormat.generate "registry.json" {
|
jsonFormat.generate "registry.json" {
|
||||||
|
|
|
@ -2,4 +2,7 @@
|
||||||
nix-empty-settings = ./empty-settings.nix;
|
nix-empty-settings = ./empty-settings.nix;
|
||||||
nix-example-settings = ./example-settings.nix;
|
nix-example-settings = ./example-settings.nix;
|
||||||
nix-example-registry = ./example-registry.nix;
|
nix-example-registry = ./example-registry.nix;
|
||||||
|
nix-keep-old-nix-path = ./keep-old-nix-path.nix;
|
||||||
|
nix-example-channels = ./example-channels.nix;
|
||||||
|
nix-example-channels-xdg = ./example-channels-xdg.nix;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ with lib;
|
||||||
|
|
||||||
nmt.script = ''
|
nmt.script = ''
|
||||||
assertPathNotExists home-files/.config/nix
|
assertPathNotExists home-files/.config/nix
|
||||||
|
assertPathNotExists home-files/.nix-defexpr/50-home-manager
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
29
tests/modules/misc/nix/example-channels-xdg.nix
Normal file
29
tests/modules/misc/nix/example-channels-xdg.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{ lib, config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
exampleChannel = pkgs.writeTextDir "default.nix" ''
|
||||||
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
{
|
||||||
|
example = pkgs.emptyDirectory;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
nix = {
|
||||||
|
package = config.lib.test.mkStubPackage {
|
||||||
|
version = lib.getVersion pkgs.nixVersions.stable;
|
||||||
|
};
|
||||||
|
channels.example = exampleChannel;
|
||||||
|
settings.use-xdg-base-directories = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
|
'export NIX_PATH="/home/hm-user/.local/state/nix/defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||||
|
assertFileContent \
|
||||||
|
home-files/.local/state/nix/defexpr/50-home-manager/example/default.nix \
|
||||||
|
${exampleChannel}/default.nix
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
26
tests/modules/misc/nix/example-channels.nix
Normal file
26
tests/modules/misc/nix/example-channels.nix
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{ config, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
exampleChannel = pkgs.writeTextDir "default.nix" ''
|
||||||
|
{ pkgs ? import <nixpkgs> { } }:
|
||||||
|
|
||||||
|
{
|
||||||
|
example = pkgs.emptyDirectory;
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
config = {
|
||||||
|
nix = {
|
||||||
|
package = config.lib.test.mkStubPackage { };
|
||||||
|
channels.example = exampleChannel;
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
|
'export NIX_PATH="/home/hm-user/.nix-defexpr/50-home-manager''${NIX_PATH:+:$NIX_PATH}"'
|
||||||
|
assertFileContent \
|
||||||
|
home-files/.nix-defexpr/50-home-manager/example/default.nix \
|
||||||
|
${exampleChannel}/default.nix
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
nixPath = [ "/a" "/b/c" ];
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
use-sandbox = true;
|
use-sandbox = true;
|
||||||
show-trace = true;
|
show-trace = true;
|
||||||
|
@ -28,6 +30,9 @@ with lib;
|
||||||
assertFileContent \
|
assertFileContent \
|
||||||
home-files/.config/nix/nix.conf \
|
home-files/.config/nix/nix.conf \
|
||||||
${./example-settings-expected.conf}
|
${./example-settings-expected.conf}
|
||||||
|
|
||||||
|
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
|
'export NIX_PATH="/a:/b/c''${NIX_PATH:+:$NIX_PATH}"'
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
16
tests/modules/misc/nix/keep-old-nix-path.nix
Normal file
16
tests/modules/misc/nix/keep-old-nix-path.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
config = {
|
||||||
|
nix = {
|
||||||
|
package = config.lib.test.mkStubPackage { };
|
||||||
|
nixPath = [ "/a" "/b/c" ];
|
||||||
|
keepOldNixPath = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileContains home-path/etc/profile.d/hm-session-vars.sh \
|
||||||
|
'export NIX_PATH="/a:/b/c"'
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue