This post announces autodocodec-nix
, a new companion library for autodocodec
that lets you generate a NixOS module options from any Codec
.
Every one of my products comes with some sort of Configuration
type that has a HasCodec
instance. The autodocodec
library lets me easily generate documentation for this type. However, I then write a nix/nixos-module.nix
that a NixOS option and type that contains mostly the same information. As of today, the autodocodec-nix
library lets you generate these options, and the opt-env-conf
library lets you output the options for your settings parser as well.
The new autodocodec-nix
library
I often use Nix to produce a configuration file that will be parsed by Haskell code with autodocodec
. This means that the Nix code has to produce values with the right shape. There is a nice mechanism in nixpkgs
' NixOS modules for this: lib.types
.
The new autodocodec-nix
library lets you generate those options from a Codec
. Here is an example codec:
-- | A complex example type
data Example = Example
exampleText :: !Text,
{ exampleBool :: !Bool
}deriving (Show, Eq, Generic)
instance HasCodec Example where
= object "Example" objectCodec $
codec Example
<$> requiredField "text" "a text" .= exampleText
<*> requiredField "bool" "a bool" .= exampleBool
And here are the options that autodocodec-nix
generates:
{ lib }:
{
bool = lib.mkOption {
default = null;
description = "a bool";
type = lib.types.nullOr lib.types.bool;
};
text = lib.mkOption {
default = null;
description = "a text";
type = lib.types.nullOr lib.types.str;
};
}
New opt-env-conf
integration
The opt-env-conf
library also just got an upgrade. It now integrates with autodocodec-nix
to produce Nix options for the configuration file that it parses.
The example code in the opt-env-conf
announcement blogpost now lets you output the following with the hidden --render-nix-options
command:
{ lib }:
{
log-level = lib.mkOption {
default = null;
description = "minimal severity of log messages";
type = lib.types.nullOr lib.types.str;
};
payment = lib.mkOption {
default = {};
type = lib.types.submodule {
options = {
currency = lib.mkOption {
default = null;
description = "Currency";
type = lib.types.nullOr lib.types.str;
};
public-key = lib.mkOption {
default = null;
description = "Public key";
type = lib.types.nullOr lib.types.str;
};
secret-key = lib.mkOption {
default = null;
description = "Secret key";
type = lib.types.nullOr lib.types.str;
};
};
};
};
}