Unverified Commit 99fd52da authored by Felix Bühler's avatar Felix Bühler Committed by GitHub
Browse files

formats: add `nixConf` (#440438)

parents aca826d8 c30b9ec9
Loading
Loading
Loading
Loading
+11 −87
Original line number Diff line number Diff line
@@ -16,40 +16,21 @@

let
  inherit (lib)
    concatStringsSep
    boolToString
    escape
    filterAttrs
    floatToString
    getVersion
    hasPrefix
    isBool
    isDerivation
    isFloat
    isInt
    isList
    isString
    literalExpression
    mapAttrsToList
    mkAfter
    mkIf
    mkOption
    mkRenamedOptionModuleWith
    optionalString
    optionals
    strings
    systems
    toPretty
    types
    versionAtLeast
    ;

  cfg = config.nix;

  nixPackage = cfg.package.out;

  isNixAtLeast = versionAtLeast (getVersion nixPackage);

  defaultSystemFeatures = [
    "nixos-test"
    "benchmark"
@@ -98,74 +79,17 @@ let
    attrsOf (either confAtom (listOf confAtom));

  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 strings.isConvertibleWithToString 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);

      isExtra = key: hasPrefix "extra-" key;

    in
    pkgs.writeTextFile {
      name = "nix.conf";
      # workaround for https://github.com/NixOS/nix/issues/9487
      # extra-* settings must come after their non-extra counterpart
      text = ''
        # WARNING: this file is generated from the nix.* options in
        # your NixOS configuration, typically
        # /etc/nixos/configuration.nix.  Do not edit it!
        ${mkKeyValuePairs (filterAttrs (key: value: !(isExtra key)) cfg.settings)}
        ${mkKeyValuePairs (filterAttrs (key: value: isExtra key) cfg.settings)}
        ${cfg.extraOptions}
      '';
      checkPhase = lib.optionalString cfg.checkConfig (
        if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then
          ''
            echo "Ignoring validation for cross-compilation"
          ''
        else
          let
            showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
          in
          ''
            echo "Validating generated nix.conf"
            ln -s $out ./nix.conf
            set -e
            set +o pipefail
            NIX_CONF_DIR=$PWD \
              ${cfg.package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
                ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
              |& sed -e 's/^warning:/error:/' \
              | (! grep '${if cfg.checkAllErrors then "^error:" else "^error: unknown setting"}')
            set -o pipefail
          ''
      );
    };
    (pkgs.formats.nixConf {
      inherit (cfg)
        package
        checkAllErrors
        checkConfig
        extraOptions
        ;
      inherit (nixPackage) version;
    }).generate
      "nix.conf"
      cfg.settings;

in
{
+104 −1
Original line number Diff line number Diff line
{ lib, pkgs }:
let
  inherit (lib)
    boolToString
    concatStringsSep
    escape
    filterAttrs
    flatten
    hasPrefix
    id
    isAttrs
    isBool
    isDerivation
    isFloat
    isInt
    isList
@@ -16,8 +21,11 @@ let
    optionalAttrs
    optionalString
    pipe
    types
    singleton
    strings
    toPretty
    types
    versionAtLeast
    warn
    ;

@@ -863,6 +871,101 @@ optionalAttrs allowAliases aliases
      lib.mkRaw = lib.mkLuaInline;
    };

  nixConf =
    {
      package,
      version,
      extraOptions ? "",
      checkAllErrors ? true,
      checkConfig ? true,
    }:
    let
      isNixAtLeast = versionAtLeast version;
    in
    assert isNixAtLeast "2.2";
    {
      type =
        let
          atomType = nullOr (oneOf [
            bool
            int
            float
            str
            path
            package
          ]);
        in
        attrsOf atomType;
      generate =
        name: value:
        let

          # note that list type has been omitted here as the separator varies, see `nix.settings.*`
          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
              strings.floatToString v
            else if isDerivation v then
              toString v
            else if builtins.isPath v then
              toString v
            else if isString v then
              v
            else if strings.isConvertibleWithToString 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);

          isExtra = key: hasPrefix "extra-" key;

        in
        pkgs.writeTextFile {
          inherit name;
          # workaround for https://github.com/NixOS/nix/issues/9487
          # extra-* settings must come after their non-extra counterpart
          text = ''
            # WARNING: this file is generated from the nix.* options in
            # your NixOS configuration, typically
            # /etc/nixos/configuration.nix.  Do not edit it!
            ${mkKeyValuePairs (filterAttrs (key: _: !(isExtra key)) value)}
            ${mkKeyValuePairs (filterAttrs (key: _: isExtra key) value)}
            ${extraOptions}
          '';
          checkPhase = lib.optionalString checkConfig (
            if pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform then
              ''
                echo "Ignoring validation for cross-compilation"
              ''
            else
              let
                showCommand = if isNixAtLeast "2.20pre" then "config show" else "show-config";
              in
              ''
                echo "Validating generated nix.conf"
                ln -s $out ./nix.conf
                set -e
                set +o pipefail
                NIX_CONF_DIR=$PWD \
                  ${package}/bin/nix ${showCommand} ${optionalString (isNixAtLeast "2.3pre") "--no-net"} \
                    ${optionalString (isNixAtLeast "2.4pre") "--option experimental-features nix-command"} \
                  |& sed -e 's/^warning:/error:/' \
                  | (! grep '${if checkAllErrors then "^error:" else "^error: unknown setting"}')
                set -o pipefail
              ''
          );
        };
    };

  # Outputs a succession of Python variable assignments
  # Useful for many Django-based services
  pythonVars =
+25 −0
Original line number Diff line number Diff line
@@ -850,6 +850,31 @@ runBuildTests {
    '';
  };

  nixConfAtoms = shouldPass {
    format = formats.nixConf {
      package = pkgs.nix;
      version = pkgs.nix.version;
      extraOptions = ''ignore-try = false'';
    };
    input = {
      auto-optimise-store = true;
      cores = 0;
      store = "auto";
    };
    # note that null type is hard to test here,
    # as it involves a trailing space our formatter will remove here
    expected = ''
      # WARNING: this file is generated from the nix.* options in
      # your NixOS configuration, typically
      # /etc/nixos/configuration.nix.  Do not edit it!
      auto-optimise-store = true
      cores = 0
      store = auto

      ignore-try = false
    '';
  };

  phpAtoms = shouldPass rec {
    format = formats.php { finalVariable = "config"; };
    input = {