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
codec = object "Example" objectCodec $
Example
<$> requiredField "text" "a text" .= exampleText
<*> requiredField "bool" "a bool" .= exampleBoolAnd 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;
};
};
};
};
}