Hi,
I have a module that builds a pre-commit configuration file. It looks like this:
{ config, lib, pkgs, ... }:
let
inherit (lib) mkOption types;
hook = types.submodule (
{ config, name, ... }:
{
options = {
enable = mkOption {
type = types.bool;
description = "Enable/disable this hook from being included in the config";
default = true;
};
id = mkOption {
type = types.str;
description = "The id of the hook - used in pre-commit-config.yaml";
default = name;
};
name = mkOption {
type = types.str;
description = "The name of the hook - shown during hook execution";
default = name;
};
entry = mkOption {
type = types.str;
description = "The entry point - the executable to run";
default = "";
};
language = mkOption {
type = types.str;
description = "The language of the hook - tells pre-commit how to install the hook";
default = "system";
};
files = mkOption {
type = types.str;
description = "The pattern of files to run on";
default = "";
};
exclude = mkOption {
type = types.str;
description = "Exclude files that were matched by `files`";
default = "^$";
};
types = mkOption {
type = types.listOf types.str;
description = "List of file types to run on (AND)";
default = [ "file" ];
};
types_or = mkOption {
type = types.listOf types.str;
description = "List of file types to run on (OR)";
default = [ ];
};
exclude_types = mkOption {
type = types.listOf types.str;
description = "The pattern of files to exclude.";
default = [ ];
};
always_run = mkOption {
type = types.bool;
description = "If true this hook will run even if there are no matching files";
default = false;
};
fail_fast = mkOption {
type = types.bool;
description = "If true pre-commit will stop running hooks if this hook fails";
default = false;
};
verbose = mkOption {
type = types.bool;
description = "If true, forces the output of the hook to be printed even when the hook passes";
default = false;
};
pass_filenames = mkOption {
type = types.bool;
description = "if false no filenames will be passed to the hook.";
default = true;
};
require_serial = mkOption {
type = types.bool;
description = "if true this hook will execute using a single process instead of in parallel.";
default = false;
};
description = mkOption {
type = types.str;
description = "Description of the hook. Used for metadata purposes only";
default = "";
};
language_version = mkOption {
type = types.str;
description = "Sets version of language used to run hook";
default = "default";
};
args = mkOption {
type = types.listOf types.str;
description = "list of additional parameters to pass to the hook";
default = [ ];
};
stages = mkOption {
type = types.listOf types.str;
description = "Confines the hook to the given stages";
default = [ "commit" ];
};
};
}
);
repo = types.submodule (
{ config, name, ... }:
{
options = {
repo = mkOption {
type = types.str;
description = "The address of the repository";
default = name;
};
hooks = mkOption {
type = types.attrsOf hook;
description = "The hooks to include in the configuration";
default = { };
};
};
}
);
in
{
options = {
default_stages = mkOption {
type = types.listOf types.str;
description = "The default stages to use for hooks";
default = [ "commit" ];
};
repos = mkOption {
type = types.attrsOf repo;
description = "The repositories to use";
default = { };
};
};
}
The default values are simply the ones that pre-commit
uses when parsing the configuration. Thus, it’s redundant to reproduce the default values here, it would be better if they were just omitted entirely. The problem is that I need these options to be optional but, if not specified, the generated config should omit the attribute name. Just leaving the default to ""
for example still includes the attribute name in the resulting config with the value set to an empty string.
Is there a way to force the config to be generated without options that were not explicitly given values?