98336c223b
Paths get automatically added to the store. The INI generator currently chokes on paths, so it is not supported for now.
133 lines
3.2 KiB
Nix
133 lines
3.2 KiB
Nix
{ lib, pkgs }:
|
|
rec {
|
|
|
|
/*
|
|
|
|
Every following entry represents a format for program configuration files
|
|
used for `settings`-style options (see https://github.com/NixOS/rfcs/pull/42).
|
|
Each entry should look as follows:
|
|
|
|
<format> = <parameters>: {
|
|
# ^^ Parameters for controlling the format
|
|
|
|
# The module system type most suitable for representing such a format
|
|
# The description needs to be overwritten for recursive types
|
|
type = ...;
|
|
|
|
# generate :: Name -> Value -> Path
|
|
# A function for generating a file with a value of such a type
|
|
generate = ...;
|
|
|
|
});
|
|
*/
|
|
|
|
|
|
json = {}: {
|
|
|
|
type = with lib.types; let
|
|
valueType = nullOr (oneOf [
|
|
bool
|
|
int
|
|
float
|
|
str
|
|
path
|
|
(attrsOf valueType)
|
|
(listOf valueType)
|
|
]) // {
|
|
description = "JSON value";
|
|
};
|
|
in valueType;
|
|
|
|
generate = name: value: pkgs.runCommandNoCC name {
|
|
nativeBuildInputs = [ pkgs.jq ];
|
|
value = builtins.toJSON value;
|
|
passAsFile = [ "value" ];
|
|
} ''
|
|
jq . "$valuePath"> $out
|
|
'';
|
|
|
|
};
|
|
|
|
# YAML has been a strict superset of JSON since 1.2
|
|
yaml = {}:
|
|
let jsonSet = json {};
|
|
in jsonSet // {
|
|
type = jsonSet.type // {
|
|
description = "YAML value";
|
|
};
|
|
};
|
|
|
|
ini = {
|
|
# Represents lists as duplicate keys
|
|
listsAsDuplicateKeys ? false,
|
|
# Alternative to listsAsDuplicateKeys, converts list to non-list
|
|
# listToValue :: [IniAtom] -> IniAtom
|
|
listToValue ? null,
|
|
...
|
|
}@args:
|
|
assert !listsAsDuplicateKeys || listToValue == null;
|
|
{
|
|
|
|
type = with lib.types; let
|
|
|
|
singleIniAtom = nullOr (oneOf [
|
|
bool
|
|
int
|
|
float
|
|
str
|
|
]) // {
|
|
description = "INI atom (null, bool, int, float or string)";
|
|
};
|
|
|
|
iniAtom =
|
|
if listsAsDuplicateKeys then
|
|
coercedTo singleIniAtom lib.singleton (listOf singleIniAtom) // {
|
|
description = singleIniAtom.description + " or a list of them for duplicate keys";
|
|
}
|
|
else if listToValue != null then
|
|
coercedTo singleIniAtom lib.singleton (nonEmptyListOf singleIniAtom) // {
|
|
description = singleIniAtom.description + " or a non-empty list of them";
|
|
}
|
|
else
|
|
singleIniAtom;
|
|
|
|
in attrsOf (attrsOf iniAtom);
|
|
|
|
generate = name: value:
|
|
let
|
|
transformedValue =
|
|
if listToValue != null
|
|
then
|
|
lib.mapAttrs (section: lib.mapAttrs (key: val:
|
|
if lib.isList val then listToValue val else val
|
|
)) value
|
|
else value;
|
|
in pkgs.writeText name (lib.generators.toINI (removeAttrs args ["listToValue"]) transformedValue);
|
|
|
|
};
|
|
|
|
toml = {}: json {} // {
|
|
type = with lib.types; let
|
|
valueType = oneOf [
|
|
bool
|
|
int
|
|
float
|
|
str
|
|
path
|
|
(attrsOf valueType)
|
|
(listOf valueType)
|
|
] // {
|
|
description = "TOML value";
|
|
};
|
|
in valueType;
|
|
|
|
generate = name: value: pkgs.runCommandNoCC name {
|
|
nativeBuildInputs = [ pkgs.remarshal ];
|
|
value = builtins.toJSON value;
|
|
passAsFile = [ "value" ];
|
|
} ''
|
|
json2toml "$valuePath" "$out"
|
|
'';
|
|
|
|
};
|
|
}
|