feat: modernize
This commit is contained in:
221
packages/repo-lib/lib/shell.nix
Normal file
221
packages/repo-lib/lib/shell.nix
Normal file
@@ -0,0 +1,221 @@
|
||||
{
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user