241 lines
6.9 KiB
Nix
241 lines
6.9 KiB
Nix
|
{ config, lib, pkgs, ... }:
|
||
|
|
||
|
with lib;
|
||
|
|
||
|
let
|
||
|
|
||
|
cfg = config.nix;
|
||
|
|
||
|
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 { };
|
||
|
|
||
|
in {
|
||
|
options.nix = {
|
||
|
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.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
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.
|
||
|
'';
|
||
|
};
|
||
|
|
||
|
registryVersion = mkOption {
|
||
|
type = types.int;
|
||
|
default = 2;
|
||
|
internal = true;
|
||
|
description = "The flake registry format version.";
|
||
|
};
|
||
|
|
||
|
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>
|
||
|
</citerefentry> for available options.
|
||
|
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.
|
||
|
'';
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = mkIf cfg.enable {
|
||
|
assertions = [{
|
||
|
assertion = cfg.settings == { } || cfg.package != null;
|
||
|
message = ''
|
||
|
A corresponding Nix package must be specified via `nix.package` for generating
|
||
|
nix.conf.
|
||
|
'';
|
||
|
}];
|
||
|
|
||
|
xdg.configFile = {
|
||
|
"nix/registry.json" = mkIf (cfg.registry != { }) {
|
||
|
source = jsonFormat.generate "registry.json" {
|
||
|
version = cfg.registryVersion;
|
||
|
flakes =
|
||
|
mapAttrsToList (n: v: { inherit (v) from to exact; }) cfg.registry;
|
||
|
};
|
||
|
};
|
||
|
|
||
|
"nix/nix.conf" = mkIf (cfg.settings != { } || cfg.extraOptions != "") {
|
||
|
source = nixConf;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
meta.maintainers = [ maintainers.polykernel ];
|
||
|
}
|