home-manager/modules/misc/nix.nix

240 lines
6.8 KiB
Nix
Raw Normal View History

2022-01-27 18:58:25 +01:00
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.nix;
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
nixPackage = cfg.package;
isNixAtLeast = versionAtLeast (getVersion nixPackage);
nixConf = assert isNixAtLeast "2.2";
let
mkValueString = v:
if v == null then
""
else if isInt v then
toString v
else if isBool v then
boolToString v
else if isFloat v then
floatToString v
else if isList v then
toString v
else if isDerivation v then
toString v
else if builtins.isPath v then
toString v
else if isString v then
v
else if isCoercibleToString v then
toString v
else
abort "The nix conf value: ${toPretty { } v} can not be encoded";
mkKeyValue = k: v: "${escape [ "=" ] k} = ${mkValueString v}";
mkKeyValuePairs = attrs:
concatStringsSep "\n" (mapAttrsToList mkKeyValue attrs);
in pkgs.writeTextFile {
name = "nix.conf";
text = ''
# WARNING: this file is generated from the nix.settings option in
# your Home Manager configuration at $XDG_CONFIG_HOME/nix/nix.conf.
# Do not edit it!
${mkKeyValuePairs cfg.settings}
${cfg.extraOptions}
'';
checkPhase =
if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then ''
echo "Ignoring validation for cross-compilation"
'' else ''
echo "Validating generated nix.conf"
ln -s $out ./nix.conf
set -e
set +o pipefail
NIX_CONF_DIR=$PWD \
${cfg.package}/bin/nix show-config ${
optionalString (isNixAtLeast "2.3pre")
"--no-net --option experimental-features nix-command"
} \
|& sed -e 's/^warning:/error:/' \
| (! grep '${
if cfg.checkConfig then "^error:" else "^error: unknown setting"
}')
set -o pipefail
'';
};
semanticConfType = with types;
let
confAtom = nullOr (oneOf [ bool int float str path package ]) // {
description =
"Nix config atom (null, bool, int, float, str, path or package)";
};
in attrsOf (either confAtom (listOf confAtom));
jsonFormat = pkgs.formats.json { };
2022-01-27 18:58:25 +01:00
in {
options.nix = {
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
enable = mkEnableOption ''
the Nix configuration module
'' // {
default = true;
visible = false;
};
package = mkOption {
type = types.nullOr types.package;
default = null;
example = literalExpression "pkgs.nix";
description = ''
The Nix package that the configuration should be generated for.
'';
};
2022-01-27 18:58:25 +01:00
registry = mkOption {
type = types.attrsOf (types.submodule (let
inputAttrs = types.attrsOf
(types.oneOf [ types.str types.int types.bool types.package ]);
in { config, name, ... }: {
options = {
from = mkOption {
type = inputAttrs;
example = {
type = "indirect";
id = "nixpkgs";
};
description = "The flake reference to be rewritten.";
};
to = mkOption {
type = inputAttrs;
example = {
type = "github";
owner = "my-org";
repo = "my-nixpkgs";
};
description =
"The flake reference to which <option>from></option> is to be rewritten.";
};
flake = mkOption {
type = types.nullOr types.attrs;
default = null;
example = literalExpression "nixpkgs";
description = ''
The flake input to which <option>from></option> is to be rewritten.
'';
};
exact = mkOption {
type = types.bool;
default = true;
description = ''
Whether the <option>from</option> reference needs to match exactly. If set,
a <option>from</option> reference like <literal>nixpkgs</literal> does not
match with a reference like <literal>nixpkgs/nixos-20.03</literal>.
'';
};
};
config = {
from = mkDefault {
type = "indirect";
id = name;
};
to = mkIf (config.flake != null) ({
type = "path";
path = config.flake.outPath;
} // lib.filterAttrs (n: v:
n == "lastModified" || n == "rev" || n == "revCount" || n
== "narHash") config.flake);
};
}));
default = { };
description = ''
User level flake registry.
'';
};
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
2022-01-27 18:58:25 +01:00
registryVersion = mkOption {
type = types.int;
default = 2;
internal = true;
description = "The flake registry format version.";
};
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
checkConfig = mkOption {
type = types.bool;
default = true;
description = ''
If enabled (the default), checks for data type mismatches and that Nix
can parse the generated nix.conf.
'';
};
extraOptions = mkOption {
type = types.lines;
default = "";
example = ''
keep-outputs = true
keep-derivations = true
'';
description =
"Additional text appended to <filename>nix.conf</filename>.";
};
settings = mkOption {
type = types.submodule { freeformType = semanticConfType; };
default = { };
example = literalExpression ''
{
use-sandbox = true;
show-trace = true;
system-features = [ "big-parallel" "kvm" "recursive-nix" ];
}
'';
description = ''
Configuration for Nix, see
<link xlink:href="https://nixos.org/manual/nix/stable/#sec-conf-file"/> or
<citerefentry>
<refentrytitle>nix.conf</refentrytitle>
<manvolnum>5</manvolnum>
2022-12-03 05:20:00 +01:00
</citerefentry> for available options.
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
The value declared here will be translated directly to the key-value pairs Nix expects.
</para>
<para>
Configuration specified in <option>nix.extraOptions</option> which will be appended
verbatim to the resulting config file.
'';
};
2022-01-27 18:58:25 +01:00
};
config = mkIf cfg.enable (mkMerge [
(mkIf (cfg.registry != { }) {
xdg.configFile."nix/registry.json".source =
jsonFormat.generate "registry.json" {
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
version = cfg.registryVersion;
flakes =
mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
};
})
(mkIf (cfg.settings != { } || cfg.extraOptions != "") {
assertions = [{
assertion = cfg.package != null;
message = ''
A corresponding Nix package must be specified via `nix.package` for generating
nix.conf.
'';
}];
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
xdg.configFile."nix/nix.conf".source = nixConf;
})
]);
nix: add structural settings (#2718) Nix permits user level configurations through ~/.config/nix/nix.conf that allow customization of system-wide settings and behavior. This is beneficial in chroot environments and for per-user configurations. System level Nix configurations in the form of /etc/nix/nix.conf can be specified declaratively via the NixOS nix module but as of currently no counter part exists in home-manager. This PR is a port of the RFC42 implementation for the NixOS nix module[1] to home-manager. Non-applicable options have been excluded and the config generation backends have been tweaked to the backends offered by home-manager. A notable change from the NixOS module is a mandatory option to specify the Nix binary corresponding to the version "nix.conf" should be generated against. This is necessary because the validation phase is dependent on the `nix show-config` subcommand on the host platform. While it is possible to avoid validation entirely, the lack of type checking was deemed too significant. In NixOs, the version information can be retrieved from the `package` option itself which declares the Nix binary system-wide. However in home-manager, there is no pure way to detect the system Nix version and what state version the "nix.conf" should be generated against. Thus an option is used to overcome this limitation by forcing the user to specify the Nix package. Note this interaction can still be automated by forwarding the system-wide Nix package to the home-manager module if needed. Three unit tests were added to test the module behavior for the empty settings, the example settings and the example registry configurations respectively. [1] - NixOS/nixpkgs#139075
2022-03-18 03:47:32 +01:00
meta.maintainers = [ maintainers.polykernel ];
2022-01-27 18:58:25 +01:00
}