222 lines
7.4 KiB
Nix
222 lines
7.4 KiB
Nix
{
|
|
lib,
|
|
treefmt-nix,
|
|
lefthookNix,
|
|
shellHookTemplatePath,
|
|
defaultShellBanner,
|
|
normalizeShellBanner,
|
|
normalizeLefthookConfig,
|
|
parallelHookStageConfig,
|
|
checkToLefthookConfig,
|
|
hookToLefthookConfig,
|
|
}:
|
|
let
|
|
buildShellHook =
|
|
{
|
|
hooksShellHook,
|
|
shellEnvScript,
|
|
bootstrap,
|
|
shellBannerScript,
|
|
extraShellText,
|
|
toolLabelWidth,
|
|
}:
|
|
let
|
|
template = builtins.readFile shellHookTemplatePath;
|
|
in
|
|
builtins.replaceStrings
|
|
[
|
|
"@HOOKS_SHELL_HOOK@"
|
|
"@TOOL_LABEL_WIDTH@"
|
|
"@SHELL_ENV_SCRIPT@"
|
|
"@BOOTSTRAP@"
|
|
"@SHELL_BANNER_SCRIPT@"
|
|
"@EXTRA_SHELL_TEXT@"
|
|
]
|
|
[
|
|
hooksShellHook
|
|
(toString toolLabelWidth)
|
|
shellEnvScript
|
|
bootstrap
|
|
shellBannerScript
|
|
extraShellText
|
|
]
|
|
template;
|
|
in
|
|
{
|
|
inherit buildShellHook;
|
|
|
|
buildShellArtifacts =
|
|
{
|
|
pkgs,
|
|
system,
|
|
src,
|
|
includeStandardPackages ? true,
|
|
formatting,
|
|
tools ? [ ],
|
|
shellConfig ? {
|
|
env = { };
|
|
extraShellText = "";
|
|
bootstrap = "";
|
|
banner = defaultShellBanner;
|
|
},
|
|
checkSpecs ? { },
|
|
rawHookEntries ? { },
|
|
lefthookConfig ? { },
|
|
extraPackages ? [ ],
|
|
}:
|
|
let
|
|
standardPackages = with pkgs; [
|
|
nixfmt
|
|
gitlint
|
|
gitleaks
|
|
shfmt
|
|
];
|
|
toolPackages = lib.filter (pkg: pkg != null) (builtins.map (tool: tool.package or null) tools);
|
|
selectedStandardPackages = lib.optionals includeStandardPackages standardPackages;
|
|
|
|
treefmtEval = treefmt-nix.lib.evalModule pkgs {
|
|
projectRootFile = "flake.nix";
|
|
programs = {
|
|
nixfmt.enable = true;
|
|
}
|
|
// formatting.programs;
|
|
settings.formatter = { } // formatting.settings;
|
|
};
|
|
treefmtWrapper = treefmtEval.config.build.wrapper;
|
|
lefthookBinWrapper = pkgs.writeShellScript "lefthook-dumb-term" ''
|
|
exec env TERM=dumb ${lib.getExe pkgs.lefthook} "$@"
|
|
'';
|
|
|
|
normalizedLefthookConfig = normalizeLefthookConfig "lefthook config" lefthookConfig;
|
|
lefthookCheck = lefthookNix.lib.${system}.run {
|
|
inherit src;
|
|
config = lib.foldl' lib.recursiveUpdate { } (
|
|
[
|
|
{
|
|
output = [
|
|
"failure"
|
|
"summary"
|
|
];
|
|
}
|
|
(parallelHookStageConfig "pre-commit")
|
|
(parallelHookStageConfig "pre-push")
|
|
(lib.setAttrByPath [ "pre-commit" "commands" "treefmt" ] {
|
|
run = "${treefmtWrapper}/bin/treefmt --no-cache {staged_files}";
|
|
stage_fixed = true;
|
|
})
|
|
(lib.setAttrByPath [ "pre-commit" "commands" "gitleaks" ] {
|
|
run = "${pkgs.gitleaks}/bin/gitleaks protect --staged";
|
|
})
|
|
(lib.setAttrByPath [ "commit-msg" "commands" "gitlint" ] {
|
|
run = "${pkgs.gitlint}/bin/gitlint --staged --msg-filename {1}";
|
|
})
|
|
]
|
|
++ lib.mapAttrsToList (name: check: checkToLefthookConfig pkgs name check) checkSpecs
|
|
++ lib.mapAttrsToList hookToLefthookConfig rawHookEntries
|
|
++ [ normalizedLefthookConfig ]
|
|
);
|
|
};
|
|
selectedCheckOutputs = {
|
|
formatting-check = treefmtEval.config.build.check src;
|
|
hook-check = lefthookCheck;
|
|
lefthook-check = lefthookCheck;
|
|
};
|
|
|
|
toolNames = builtins.map (tool: tool.name) tools;
|
|
toolNameWidth =
|
|
if toolNames == [ ] then
|
|
0
|
|
else
|
|
builtins.foldl' (maxWidth: name: lib.max maxWidth (builtins.stringLength name)) 0 toolNames;
|
|
toolLabelWidth = toolNameWidth + 1;
|
|
|
|
shellEnvScript = lib.concatStringsSep "\n" (
|
|
lib.mapAttrsToList (
|
|
name: value: "export ${name}=${lib.escapeShellArg (toString value)}"
|
|
) shellConfig.env
|
|
);
|
|
|
|
banner = normalizeShellBanner (shellConfig.banner or { });
|
|
|
|
shellBannerScript =
|
|
if banner.style == "pretty" then
|
|
''
|
|
repo_lib_print_pretty_header \
|
|
${lib.escapeShellArg banner.borderColor} \
|
|
${lib.escapeShellArg banner.titleColor} \
|
|
${lib.escapeShellArg banner.icon} \
|
|
${lib.escapeShellArg banner.title} \
|
|
${lib.escapeShellArg banner.subtitleColor} \
|
|
${lib.escapeShellArg banner.subtitle}
|
|
''
|
|
+ lib.concatMapStrings (tool: ''
|
|
repo_lib_print_pretty_tool \
|
|
${lib.escapeShellArg banner.borderColor} \
|
|
${lib.escapeShellArg tool.name} \
|
|
${lib.escapeShellArg tool.banner.color} \
|
|
${lib.escapeShellArg (if tool.banner.icon == null then "" else tool.banner.icon)} \
|
|
${lib.escapeShellArg (if tool.banner.iconColor == null then "" else tool.banner.iconColor)} \
|
|
${lib.escapeShellArg (if tool.required then "1" else "0")} \
|
|
${lib.escapeShellArg (toString tool.version.line)} \
|
|
${lib.escapeShellArg (toString tool.version.group)} \
|
|
${lib.escapeShellArg (if tool.version.regex == null then "" else tool.version.regex)} \
|
|
${lib.escapeShellArg (if tool.version.match == null then "" else tool.version.match)} \
|
|
${lib.escapeShellArg tool.executable} \
|
|
${lib.escapeShellArgs tool.version.args}
|
|
'') tools
|
|
+ ''
|
|
repo_lib_print_pretty_footer \
|
|
${lib.escapeShellArg banner.borderColor}
|
|
''
|
|
else
|
|
''
|
|
repo_lib_print_simple_header \
|
|
${lib.escapeShellArg banner.titleColor} \
|
|
${lib.escapeShellArg banner.icon} \
|
|
${lib.escapeShellArg banner.title} \
|
|
${lib.escapeShellArg banner.subtitleColor} \
|
|
${lib.escapeShellArg banner.subtitle}
|
|
''
|
|
+ lib.concatMapStrings (tool: ''
|
|
repo_lib_print_simple_tool \
|
|
${lib.escapeShellArg tool.name} \
|
|
${lib.escapeShellArg tool.banner.color} \
|
|
${lib.escapeShellArg (if tool.banner.icon == null then "" else tool.banner.icon)} \
|
|
${lib.escapeShellArg (if tool.banner.iconColor == null then "" else tool.banner.iconColor)} \
|
|
${lib.escapeShellArg (if tool.required then "1" else "0")} \
|
|
${lib.escapeShellArg (toString tool.version.line)} \
|
|
${lib.escapeShellArg (toString tool.version.group)} \
|
|
${lib.escapeShellArg (if tool.version.regex == null then "" else tool.version.regex)} \
|
|
${lib.escapeShellArg (if tool.version.match == null then "" else tool.version.match)} \
|
|
${lib.escapeShellArg tool.executable} \
|
|
${lib.escapeShellArgs tool.version.args}
|
|
'') tools
|
|
+ ''
|
|
printf "\n"
|
|
'';
|
|
in
|
|
{
|
|
checks = selectedCheckOutputs;
|
|
formatter = treefmtWrapper;
|
|
shell = pkgs.mkShell {
|
|
LEFTHOOK_BIN = builtins.toString lefthookBinWrapper;
|
|
packages = lib.unique (
|
|
selectedStandardPackages
|
|
++ extraPackages
|
|
++ toolPackages
|
|
++ [
|
|
pkgs.lefthook
|
|
treefmtWrapper
|
|
]
|
|
);
|
|
shellHook = buildShellHook {
|
|
hooksShellHook = lefthookCheck.shellHook;
|
|
inherit toolLabelWidth shellEnvScript shellBannerScript;
|
|
bootstrap = shellConfig.bootstrap;
|
|
extraShellText = shellConfig.extraShellText;
|
|
};
|
|
};
|
|
}
|
|
// selectedCheckOutputs;
|
|
}
|