{ config, pkgs, lib, ... }: {
options = {
yq-merge = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
text = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.lines;
description = "Pass to home.home.<xxx>.text";
};
preOnChange = lib.mkOption {
default = "";
type = lib.types.lines;
};
postOnChange = lib.mkOption {
default = "";
type = lib.types.lines;
};
};
}
);
default = {};
description = ''
Use yq to merge config file.
The yq-merge."<name>" receive attr same as `home.file`.
'';
example = ./test.nix;
};
};
config = {
home.file = builtins.mapAttrs (old_target: value: rec {
inherit (value) text;
target = "${dirOf old_target}/yq-merge.${baseNameOf old_target}";
onChange = /*bash*/ ''
${value.preOnChange}
if [[ -e ${old_target} ]]; then
# Operator: `*d` means deeply merge and deeply merge array
# See: https://mikefarah.gitbook.io/yq/operators/multiply-merge
# Noted: If the element of array is string, the old array will be overwrite.
${pkgs.yq-go}/bin/yq -i ea '. as $item ireduce ({}; . *d $item )' ${old_target} ${target}
else
cat ${target} > ${old_target}
fi
${value.postOnChange}
'';
}) config.yq-merge;
};
}