forked from extern/flakelight
efcf01325b
Since the formatter always depended on devShell packages, building the formatter involved building all the devShell packages, which can be slow. In the case where formatters are set to plain strings, such as "nixpkgs-fmt", depending on the devShell packages is necessary in order to put the formatting utility on the path. But when a formatters option is set to an package, such as "${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt", then that formatter option does not depend on the devShell packages. Flakelight now detects if any of the configured formatters are using the first form, and only if so does it add the devShell packages dependency. This allows the first form to still work, without incurring a cost for flakes that only use the second form. Users can use the second form for all formatters options if they wish to not build the devShell packages when using the formatter.
66 lines
2.1 KiB
Nix
66 lines
2.1 KiB
Nix
# flakelight -- Framework for simplifying flake setup
|
|
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
{ config, src, lib, flakelight, genSystems, ... }:
|
|
let
|
|
inherit (builtins) all hasContext;
|
|
inherit (lib) mkDefault mkMerge mkOption mkIf mapAttrsToList;
|
|
inherit (lib.types) functionTo lazyAttrsOf package str;
|
|
inherit (flakelight.types) nullable optFunctionTo;
|
|
in
|
|
{
|
|
options = {
|
|
formatter = mkOption {
|
|
type = nullable (functionTo package);
|
|
default = null;
|
|
};
|
|
formatters = mkOption {
|
|
type = nullable (optFunctionTo (lazyAttrsOf str));
|
|
default = null;
|
|
};
|
|
};
|
|
|
|
config = mkMerge [
|
|
(mkIf (config.formatter != null) {
|
|
outputs.formatter = genSystems config.formatter;
|
|
})
|
|
|
|
(mkIf (config.formatters != null) {
|
|
outputs.formatter = mkDefault (genSystems
|
|
({ pkgs, lib, fd, coreutils, ... }:
|
|
let
|
|
inherit (lib) attrValues makeBinPath;
|
|
formatters = config.formatters pkgs;
|
|
fullContext = all hasContext (attrValues formatters);
|
|
packages =
|
|
if config.devShell == null then [ ]
|
|
else (config.devShell pkgs).packages pkgs;
|
|
caseArms = toString (mapAttrsToList
|
|
(n: v: "\n ${n}) ${v} \"$f\" & ;;")
|
|
formatters);
|
|
in
|
|
pkgs.writeShellScriptBin "formatter" ''
|
|
PATH=${if fullContext then "" else makeBinPath packages}
|
|
for f in "$@"; do
|
|
if [ -d "$f" ]; then
|
|
${fd}/bin/fd "$f" -Htf -x "$0" &
|
|
else
|
|
case "$(${coreutils}/bin/basename "$f")" in${caseArms}
|
|
esac
|
|
fi
|
|
done &>/dev/null
|
|
wait
|
|
''));
|
|
})
|
|
|
|
(mkIf ((config.formatters != null) || (config.formatter != null)) {
|
|
checks.formatting = { lib, outputs', diffutils, ... }: ''
|
|
${lib.getExe outputs'.formatter} .
|
|
${diffutils}/bin/diff -qr ${src} . |\
|
|
sed 's/Files .* and \(.*\) differ/File \1 not formatted/g'
|
|
'';
|
|
})
|
|
];
|
|
}
|