mirror of
https://github.com/nix-community/flakelight.git
synced 2024-11-28 18:33:18 +01:00
Reimplement framework using the module system
This commit is contained in:
parent
4df2ca87b5
commit
f6c4424f6e
@ -1,7 +0,0 @@
|
||||
_: {
|
||||
devTools = pkgs: with pkgs; [ nixpkgs-fmt nodePackages.prettier ];
|
||||
formatters = {
|
||||
"*.nix" = "nixpkgs-fmt";
|
||||
"*.md | *.json | *.yml" = "prettier --write";
|
||||
};
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{ src, lib }:
|
||||
let
|
||||
inherit (lib) getExe optionalAttrs optionalString pathExists;
|
||||
in
|
||||
{
|
||||
checks = optionalAttrs (pathExists (src + /.editorconfig)) {
|
||||
# By default, high false-positive flags are disabled.
|
||||
editorconfig = { editorconfig-checker }:
|
||||
"${getExe editorconfig-checker}"
|
||||
+ optionalString (!pathExists (src + /.ecrc))
|
||||
" -disable-indent-size -disable-max-line-length";
|
||||
};
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
_: {
|
||||
shellHook = { lib, flakelite }: ''
|
||||
if [ -f flake.nix ] && [ -d .git/hooks ] &&
|
||||
[ ! -f .git/hooks/pre-commit ]; then
|
||||
echo Installing git pre-commit hook...
|
||||
cp ${lib.getExe flakelite.inputs'.flakelite.packages.pre-commit-hook
|
||||
} .git/hooks
|
||||
fi
|
||||
'';
|
||||
}
|
43
builtinModules/apps.nix
Normal file
43
builtinModules/apps.nix
Normal file
@ -0,0 +1,43 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) isFunction mapAttrs mkIf mkMerge mkOption;
|
||||
inherit (lib.types) lazyAttrsOf nullOr raw;
|
||||
inherit (flakelite.types) optFunctionTo;
|
||||
|
||||
isApp = x: (x ? type) && (x.type == "app") && (x ? program);
|
||||
|
||||
mkApp = pkgs: app:
|
||||
let
|
||||
app' = if isFunction app then app pkgs else app;
|
||||
in
|
||||
if isApp app' then app' else { type = "app"; program = "${app'}"; };
|
||||
in
|
||||
{
|
||||
options = {
|
||||
app = mkOption {
|
||||
type = nullOr raw;
|
||||
default = null;
|
||||
};
|
||||
|
||||
apps = mkOption {
|
||||
type = nullOr (optFunctionTo (lazyAttrsOf raw));
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (config.app != null) {
|
||||
apps.default = config.app;
|
||||
})
|
||||
|
||||
(mkIf (config.apps != null) {
|
||||
perSystem = pkgs: {
|
||||
apps = mapAttrs (_: mkApp pkgs) (config.apps pkgs);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
24
builtinModules/builtinFormatters.nix
Normal file
24
builtinModules/builtinFormatters.nix
Normal file
@ -0,0 +1,24 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ lib, ... }:
|
||||
let
|
||||
inherit (lib) mkEnableOption;
|
||||
in
|
||||
{
|
||||
options.flakelite.builtinFormatters =
|
||||
mkEnableOption "default formatters" // { default = true; };
|
||||
|
||||
config = {
|
||||
devShell.packages = pkgs: [
|
||||
pkgs.nixpkgs-fmt
|
||||
pkgs.nodePackages.prettier
|
||||
];
|
||||
|
||||
formatters = {
|
||||
"*.nix" = "nixpkgs-fmt";
|
||||
"*.md | *.json | *.yml" = "prettier --write";
|
||||
};
|
||||
};
|
||||
}
|
46
builtinModules/builtinOverlay.nix
Normal file
46
builtinModules/builtinOverlay.nix
Normal file
@ -0,0 +1,46 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, src, lib, inputs, outputs, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) isList mkOption mkOrder mapAttrs optionalAttrs;
|
||||
inherit (lib.types) listOf nullOr oneOf str;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
description = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
license = mkOption {
|
||||
type = nullOr (oneOf [ str (listOf str) ]);
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
|
||||
config.withOverlays = mkOrder 10 (final: prev:
|
||||
let
|
||||
system = prev.stdenv.hostPlatform.system;
|
||||
in
|
||||
{
|
||||
inherit src inputs outputs flakelite system;
|
||||
inputs' = mapAttrs (_: mapAttrs (_: v: v.${system} or { })) inputs;
|
||||
outputs' = mapAttrs (_: v: v.${system} or { }) outputs;
|
||||
|
||||
defaultMeta = {
|
||||
platforms = config.systems;
|
||||
} // optionalAttrs (config.description != null) {
|
||||
inherit (config) description;
|
||||
} // optionalAttrs (config.license != null) {
|
||||
license =
|
||||
let
|
||||
getLicense = license: final.lib.licenses.${license} or
|
||||
(final.lib.meta.getLicenseFromSpdxId license);
|
||||
in
|
||||
if isList config.license then map getLicense config.license
|
||||
else getLicense config.license;
|
||||
};
|
||||
});
|
||||
}
|
32
builtinModules/checks.nix
Normal file
32
builtinModules/checks.nix
Normal file
@ -0,0 +1,32 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, src, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) isDerivation isFunction mkOption mkIf mapAttrs;
|
||||
inherit (lib.types) lazyAttrsOf nullOr raw;
|
||||
inherit (flakelite.types) optFunctionTo;
|
||||
|
||||
mkCheck = pkgs: src: name: cmd:
|
||||
let
|
||||
cmd' = if isFunction cmd then cmd pkgs else cmd;
|
||||
in
|
||||
if isDerivation cmd' then cmd' else
|
||||
pkgs.runCommand "check-${name}" { } ''
|
||||
cp --no-preserve=mode -r ${src} src
|
||||
cd src
|
||||
${cmd'}
|
||||
touch $out
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.checks = mkOption {
|
||||
type = nullOr (optFunctionTo (lazyAttrsOf raw));
|
||||
default = null;
|
||||
};
|
||||
|
||||
config.perSystem = mkIf (config.checks != null) (pkgs: {
|
||||
checks = mapAttrs (mkCheck pkgs src) (config.checks pkgs);
|
||||
});
|
||||
}
|
69
builtinModules/core.nix
Normal file
69
builtinModules/core.nix
Normal file
@ -0,0 +1,69 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, inputs, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (builtins) all head isAttrs length;
|
||||
inherit (lib) foldAttrs getFiles getValues mapAttrs mergeAttrs mkOption
|
||||
mkOptionType showFiles showOption;
|
||||
inherit (lib.types) functionTo lazyAttrsOf listOf nonEmptyStr raw uniq;
|
||||
inherit (flakelite.types) optListOf overlay;
|
||||
|
||||
outputs = mkOptionType {
|
||||
name = "outputs";
|
||||
description = "output values";
|
||||
descriptionClass = "noun";
|
||||
merge = loc: defs:
|
||||
if (length defs) == 1 then (head defs).value
|
||||
else if all isAttrs (getValues defs) then
|
||||
(lazyAttrsOf outputs).merge loc defs
|
||||
else throw "The option `${showOption loc}' has conflicting definitions in ${showFiles (getFiles defs)}";
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
inputs = mkOption {
|
||||
type = lazyAttrsOf raw;
|
||||
};
|
||||
|
||||
systems = mkOption {
|
||||
type = uniq (listOf nonEmptyStr);
|
||||
default = [ "x86_64-linux" "aarch64-linux" ];
|
||||
};
|
||||
|
||||
outputs = mkOption {
|
||||
type = lazyAttrsOf outputs;
|
||||
default = { };
|
||||
};
|
||||
|
||||
perSystem = mkOption {
|
||||
type = functionTo (lazyAttrsOf outputs);
|
||||
default = _: { };
|
||||
};
|
||||
|
||||
nixpkgs.config = mkOption {
|
||||
type = lazyAttrsOf raw;
|
||||
default = { };
|
||||
};
|
||||
|
||||
withOverlays = mkOption {
|
||||
type = optListOf overlay;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
_module.args = { inherit (config) inputs outputs; };
|
||||
|
||||
outputs = foldAttrs mergeAttrs { } (map
|
||||
(system: mapAttrs
|
||||
(_: v: { ${system} = v; })
|
||||
(config.perSystem (import inputs.nixpkgs {
|
||||
inherit system;
|
||||
config = config.nixpkgs.config;
|
||||
overlays = config.withOverlays;
|
||||
})))
|
||||
config.systems);
|
||||
};
|
||||
}
|
70
builtinModules/devShells.nix
Normal file
70
builtinModules/devShells.nix
Normal file
@ -0,0 +1,70 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) any attrValues filterAttrs mapAttrs mkIf mkMerge mkOption
|
||||
optionalAttrs;
|
||||
inherit (lib.types) lazyAttrsOf functionTo lines listOf nullOr package str;
|
||||
inherit (flakelite) supportedSystem;
|
||||
inherit (flakelite.types) optFunctionTo packageDef;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
devShell = {
|
||||
inputsFrom = mkOption {
|
||||
type = nullOr
|
||||
(functionTo (listOf package));
|
||||
default = null;
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = nullOr
|
||||
(functionTo (listOf package));
|
||||
default = null;
|
||||
};
|
||||
|
||||
shellHook = mkOption {
|
||||
type = nullOr (optFunctionTo lines);
|
||||
default = null;
|
||||
};
|
||||
|
||||
env = mkOption {
|
||||
type = nullOr
|
||||
(optFunctionTo (lazyAttrsOf str));
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
|
||||
devShells = mkOption {
|
||||
type = lazyAttrsOf packageDef;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (any (x: x != null) (attrValues config.devShell)) {
|
||||
devShells.default = { pkgs, mkShell }: mkShell (
|
||||
optionalAttrs (config.devShell.env != null)
|
||||
(config.devShell.env pkgs)
|
||||
// optionalAttrs (config.devShell.inputsFrom != null) {
|
||||
inputsFrom = config.devShell.inputsFrom pkgs;
|
||||
}
|
||||
// optionalAttrs (config.devShell.packages != null) {
|
||||
packages = config.devShell.packages pkgs;
|
||||
}
|
||||
// optionalAttrs (config.devShell.shellHook != null) {
|
||||
shellHook = config.devShell.shellHook pkgs;
|
||||
}
|
||||
);
|
||||
})
|
||||
|
||||
(mkIf (config.devShells != { }) {
|
||||
perSystem = pkgs: {
|
||||
devShells = filterAttrs (_: supportedSystem pkgs)
|
||||
(mapAttrs (_: v: pkgs.callPackage v { }) config.devShells);
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
22
builtinModules/editorconfig.nix
Normal file
22
builtinModules/editorconfig.nix
Normal file
@ -0,0 +1,22 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, src, ... }:
|
||||
let
|
||||
inherit (lib) mkEnableOption mkIf optionalString pathExists;
|
||||
in
|
||||
{
|
||||
options.flakelite.editorconfig =
|
||||
mkEnableOption "editorconfig check" // { default = true; };
|
||||
|
||||
config.checks = mkIf
|
||||
(config.flakelite.editorconfig && (pathExists (src + /.editorconfig)))
|
||||
{
|
||||
# By default, high false-positive flags are disabled.
|
||||
editorconfig = { editorconfig-checker, ... }:
|
||||
"${editorconfig-checker}/bin/editorconfig-checker"
|
||||
+ optionalString (!pathExists (src + /.ecrc))
|
||||
" -disable-indent-size -disable-max-line-length";
|
||||
};
|
||||
}
|
40
builtinModules/formatter.nix
Normal file
40
builtinModules/formatter.nix
Normal file
@ -0,0 +1,40 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, src, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) mkOption mkIf mapAttrsToList;
|
||||
inherit (lib.types) lazyAttrsOf nullOr str;
|
||||
inherit (flakelite.types) optFunctionTo;
|
||||
in
|
||||
{
|
||||
options.formatters = mkOption {
|
||||
type = nullOr (optFunctionTo (lazyAttrsOf str));
|
||||
default = null;
|
||||
};
|
||||
|
||||
config = mkIf (config.formatters != null) {
|
||||
perSystem = { pkgs, lib, fd, coreutils, ... }: {
|
||||
formatter = pkgs.writeShellScriptBin "formatter" ''
|
||||
PATH=${lib.makeBinPath (config.devShell.packages pkgs)}
|
||||
for f in "$@"; do
|
||||
if [ -d "$f" ]; then
|
||||
${fd}/bin/fd "$f" -Htf -x "$0"
|
||||
else
|
||||
case "$(${coreutils}/bin/basename "$f")" in
|
||||
${toString (mapAttrsToList
|
||||
(n: v: "${n}) ${v} \"$f\";;") (config.formatters pkgs))}
|
||||
esac
|
||||
fi
|
||||
done &>/dev/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'
|
||||
'';
|
||||
};
|
||||
}
|
34
builtinModules/homeConfigurations.nix
Normal file
34
builtinModules/homeConfigurations.nix
Normal file
@ -0,0 +1,34 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (builtins) isAttrs;
|
||||
inherit (lib) foldl mapAttrsToList mergeOneOption mkOption mkOptionType mkIf
|
||||
recursiveUpdate;
|
||||
inherit (lib.types) lazyAttrsOf;
|
||||
|
||||
homeConfiguration = mkOptionType {
|
||||
name = "homeConfiguration";
|
||||
description = "homeConfiguration";
|
||||
descriptionClass = "noun";
|
||||
check = x: isAttrs x && x ? activationPackage;
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.homeConfigurations = mkOption {
|
||||
type = lazyAttrsOf homeConfiguration;
|
||||
default = { };
|
||||
};
|
||||
|
||||
config.outputs = mkIf (config.homeConfigurations != { }) {
|
||||
inherit (config) homeConfigurations;
|
||||
checks = foldl recursiveUpdate { } (mapAttrsToList
|
||||
(n: v: {
|
||||
${v.config.nixpkgs.system}."home-${n}" = v.activationPackage;
|
||||
})
|
||||
config.homeConfigurations);
|
||||
};
|
||||
}
|
33
builtinModules/homeModules.nix
Normal file
33
builtinModules/homeModules.nix
Normal file
@ -0,0 +1,33 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) mkOption mkIf mkMerge;
|
||||
inherit (lib.types) lazyAttrsOf nullOr;
|
||||
inherit (flakelite.types) module;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
homeModule = mkOption {
|
||||
type = nullOr module;
|
||||
default = null;
|
||||
};
|
||||
|
||||
homeModules = mkOption {
|
||||
type = lazyAttrsOf module;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (config.homeModule != null) {
|
||||
homeModules.default = config.homeModule;
|
||||
})
|
||||
|
||||
(mkIf (config.homeModules != { }) {
|
||||
outputs = { inherit (config) homeModules; };
|
||||
})
|
||||
];
|
||||
}
|
75
builtinModules/nixDir.nix
Normal file
75
builtinModules/nixDir.nix
Normal file
@ -0,0 +1,75 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, src, lib, flakelite, ... }@args:
|
||||
let
|
||||
inherit (lib) isFunction mkOption mkIf mkMerge optionalAttrs;
|
||||
inherit (flakelite) autoImport;
|
||||
inherit (flakelite.types) path;
|
||||
in
|
||||
{
|
||||
options.nixDir = mkOption {
|
||||
type = path;
|
||||
default = src + /nix;
|
||||
};
|
||||
|
||||
config =
|
||||
let
|
||||
autoImport' = autoImport config.nixDir;
|
||||
autoImportArgs = n:
|
||||
let v = autoImport' n; in
|
||||
if isFunction v then v args else v;
|
||||
outputs = autoImportArgs "outputs";
|
||||
perSystem = autoImport' "perSystem";
|
||||
withOverlays = autoImport' "withOverlays";
|
||||
package = autoImport' "package";
|
||||
packages = autoImportArgs "packages";
|
||||
overlays = autoImportArgs "overlays";
|
||||
devShell = autoImportArgs "devShell";
|
||||
devShells = autoImportArgs "devShells";
|
||||
app = autoImport' "app";
|
||||
apps = autoImport' "apps";
|
||||
checks = autoImport' "checks";
|
||||
nixosModule = autoImport' "nixosModule";
|
||||
nixosModules = autoImportArgs "nixosModules";
|
||||
nixosConfigurations = autoImportArgs [ "nixosConfigurations" "nixos" ];
|
||||
homeModule = autoImport' "homeModule";
|
||||
homeModules = autoImportArgs "homeModules";
|
||||
homeConfigurations = autoImportArgs [ "homeConfigurations" "home" ];
|
||||
template = autoImportArgs "template";
|
||||
templates = autoImportArgs "templates";
|
||||
formatters = autoImport' "formatters";
|
||||
in
|
||||
mkMerge [
|
||||
(mkIf (outputs != null) { inherit outputs; })
|
||||
(mkIf (perSystem != null) { inherit perSystem; })
|
||||
(mkIf (withOverlays != null) { inherit withOverlays; })
|
||||
(mkIf (package != null) { inherit package; })
|
||||
(mkIf (packages != null) { inherit packages; })
|
||||
(mkIf (overlays != null) { inherit overlays; })
|
||||
(mkIf (devShell != null) {
|
||||
devShell = optionalAttrs (devShell ? inputsFrom)
|
||||
{ inherit (devShell) inputsFrom; }
|
||||
// optionalAttrs (devShell ? packages)
|
||||
{ inherit (devShell) packages; }
|
||||
// optionalAttrs (devShell ? shellHook)
|
||||
{ inherit (devShell) shellHook; }
|
||||
// optionalAttrs (devShell ? env)
|
||||
{ inherit (devShell) env; };
|
||||
})
|
||||
(mkIf (devShells != null) { inherit devShells; })
|
||||
(mkIf (app != null) { inherit app; })
|
||||
(mkIf (apps != null) { inherit apps; })
|
||||
(mkIf (checks != null) { inherit checks; })
|
||||
(mkIf (nixosModule != null) { inherit nixosModule; })
|
||||
(mkIf (nixosModules != null) { inherit nixosModules; })
|
||||
(mkIf (nixosConfigurations != null) { inherit nixosConfigurations; })
|
||||
(mkIf (homeModule != null) { inherit homeModule; })
|
||||
(mkIf (homeModules != null) { inherit homeModules; })
|
||||
(mkIf (homeConfigurations != null) { inherit homeConfigurations; })
|
||||
(mkIf (template != null) { inherit template; })
|
||||
(mkIf (templates != null) { inherit templates; })
|
||||
(mkIf (formatters != null) { inherit formatters; })
|
||||
];
|
||||
}
|
37
builtinModules/nixosConfigurations.nix
Normal file
37
builtinModules/nixosConfigurations.nix
Normal file
@ -0,0 +1,37 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (builtins) isAttrs;
|
||||
inherit (lib) foldl mapAttrsToList mergeOneOption mkIf mkOption mkOptionType
|
||||
recursiveUpdate;
|
||||
inherit (lib.types) lazyAttrsOf;
|
||||
|
||||
nixosConfiguration = mkOptionType {
|
||||
name = "nixosConfiguration";
|
||||
description = "nixosConfiguration";
|
||||
descriptionClass = "noun";
|
||||
check = x: isAttrs x
|
||||
&& x ? config.nixpkgs.system
|
||||
&& x ? config.system.build.toplevel;
|
||||
merge = mergeOneOption;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.nixosConfigurations = mkOption {
|
||||
type = lazyAttrsOf nixosConfiguration;
|
||||
default = { };
|
||||
};
|
||||
|
||||
config.outputs = mkIf (config.nixosConfigurations != { }) {
|
||||
inherit (config) nixosConfigurations;
|
||||
checks = foldl recursiveUpdate { } (mapAttrsToList
|
||||
(n: v: {
|
||||
${v.config.nixpkgs.system}."nixos-${n}" =
|
||||
v.config.system.build.toplevel;
|
||||
})
|
||||
config.nixosConfigurations);
|
||||
};
|
||||
}
|
33
builtinModules/nixosModules.nix
Normal file
33
builtinModules/nixosModules.nix
Normal file
@ -0,0 +1,33 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) mkOption mkIf mkMerge;
|
||||
inherit (lib.types) lazyAttrsOf nullOr;
|
||||
inherit (flakelite.types) module;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
nixosModule = mkOption {
|
||||
type = nullOr module;
|
||||
default = null;
|
||||
};
|
||||
|
||||
nixosModules = mkOption {
|
||||
type = lazyAttrsOf module;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (config.nixosModule != null) {
|
||||
nixosModules.default = config.nixosModule;
|
||||
})
|
||||
|
||||
(mkIf (config.nixosModules != { }) {
|
||||
outputs = { inherit (config) nixosModules; };
|
||||
})
|
||||
];
|
||||
}
|
18
builtinModules/overlays.nix
Normal file
18
builtinModules/overlays.nix
Normal file
@ -0,0 +1,18 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (lib) mkOption mkIf;
|
||||
inherit (lib.types) lazyAttrsOf;
|
||||
inherit (flakelite.types) overlay;
|
||||
in
|
||||
{
|
||||
options.overlays = mkOption {
|
||||
type = lazyAttrsOf overlay;
|
||||
default = { };
|
||||
};
|
||||
|
||||
config.outputs = mkIf (config.overlays != { }) { inherit (config) overlays; };
|
||||
}
|
68
builtinModules/packages.nix
Normal file
68
builtinModules/packages.nix
Normal file
@ -0,0 +1,68 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, flakelite, ... }:
|
||||
let
|
||||
inherit (builtins) attrNames functionArgs intersectAttrs parseDrvName;
|
||||
inherit (lib) composeManyExtensions filterAttrs fix genAttrs mapAttrs mapAttrs'
|
||||
mkIf mkMerge mkOption mkOrder nameValuePair optional optionalAttrs remove;
|
||||
inherit (lib.types) lazyAttrsOf nullOr;
|
||||
inherit (flakelite) supportedSystem;
|
||||
inherit (flakelite.types) packageDef;
|
||||
|
||||
getName = pkg: pkg.pname or (parseDrvName pkg.name).name;
|
||||
|
||||
callPkg = pkgs: def: def (intersectAttrs (functionArgs def) pkgs);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
package = mkOption {
|
||||
type = nullOr packageDef;
|
||||
default = null;
|
||||
};
|
||||
|
||||
packages = mkOption {
|
||||
type = lazyAttrsOf packageDef;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (config.package != null) {
|
||||
packages.default = config.package;
|
||||
})
|
||||
|
||||
(mkIf (config.packages != { }) {
|
||||
withOverlays = mkOrder 2000 (final: prev:
|
||||
let
|
||||
pkgNames = attrNames config.packages;
|
||||
pkgNames' = remove "default" pkgNames;
|
||||
defaultName = getName (fix (self:
|
||||
prev // (genAttrs pkgNames
|
||||
(n: callPkg self config.packages.${n})))).default;
|
||||
in
|
||||
(optionalAttrs (config.packages ? default) {
|
||||
${defaultName} = final.callPackage config.packages.default { };
|
||||
}) //
|
||||
(genAttrs pkgNames' (n: final.callPackage config.packages.${n} { })));
|
||||
|
||||
overlays.default = final: prev:
|
||||
let
|
||||
pkgs' = fix (composeManyExtensions config.withOverlays) prev;
|
||||
defaultName = getName (callPkg pkgs' config.packages.default);
|
||||
pkgNames = (remove "default" (attrNames config.packages))
|
||||
++ (optional (config.packages ? default) defaultName);
|
||||
pkgs = final.appendOverlays config.withOverlays;
|
||||
in
|
||||
genAttrs pkgNames (n: pkgs.${n});
|
||||
|
||||
perSystem = pkgs: rec {
|
||||
packages = filterAttrs (_: supportedSystem pkgs)
|
||||
(mapAttrs (_: v: pkgs.callPackage v { }) config.packages);
|
||||
|
||||
checks = mapAttrs' (n: nameValuePair ("packages-" + n)) packages;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
42
builtinModules/templates.nix
Normal file
42
builtinModules/templates.nix
Normal file
@ -0,0 +1,42 @@
|
||||
# flakelite -- Framework for making flakes simple
|
||||
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (builtins) isPath isString;
|
||||
inherit (lib) mkOption mkOptionType mkIf mkMerge;
|
||||
inherit (lib.types) lazyAttrsOf nullOr;
|
||||
|
||||
template = mkOptionType {
|
||||
name = "template";
|
||||
description = "template definition";
|
||||
descriptionClass = "noun";
|
||||
check = x: (x ? path) && (isPath x.path) &&
|
||||
(x ? description) && (isString x.description) &&
|
||||
((! x ? welcomeText) || (isString x.welcomeText));
|
||||
};
|
||||
in
|
||||
{
|
||||
options = {
|
||||
template = mkOption {
|
||||
type = nullOr template;
|
||||
default = null;
|
||||
};
|
||||
|
||||
templates = mkOption {
|
||||
type = lazyAttrsOf template;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
(mkIf (config.template != null) {
|
||||
templates.default = config.template;
|
||||
})
|
||||
|
||||
(mkIf (config.templates != { }) {
|
||||
outputs = { inherit (config) templates; };
|
||||
})
|
||||
];
|
||||
}
|
536
default.nix
536
default.nix
@ -4,65 +4,69 @@
|
||||
|
||||
localInputs:
|
||||
let
|
||||
inherit (builtins) intersectAttrs isPath readDir;
|
||||
inherit (localInputs.nixpkgs.lib) attrNames attrVals attrValues
|
||||
callPackageWith composeManyExtensions concat concatStringsSep filter
|
||||
filterAttrs findFirst foldAttrs foldl functionArgs genAttrs hasSuffix
|
||||
isFunction isList isString listToAttrs mapAttrs mapAttrsToList mapAttrs'
|
||||
mergeAttrs nameValuePair optional optionalAttrs parseDrvName pathExists pipe
|
||||
recursiveUpdate removePrefix removeSuffix zipAttrsWith;
|
||||
inherit (builtins) isAttrs isPath readDir;
|
||||
inherit (localInputs.nixpkgs.lib) attrNames composeManyExtensions
|
||||
filter findFirst genAttrs getValues hasSuffix isFunction isList mapAttrs
|
||||
mapAttrsToList pathExists pipe removePrefix removeSuffix evalModules
|
||||
mkDefault mkOptionType singleton;
|
||||
inherit (localInputs.nixpkgs.lib.types) coercedTo functionTo listOf;
|
||||
|
||||
/* Attributes in flakelite's lib output.
|
||||
*/
|
||||
exports = {
|
||||
inherit mkFlake systems importDir autoImport autoImportAttrs defaultPkgName
|
||||
supportedSystem mergeModules moduleAttrs rootAttrs ensureFn callFn
|
||||
filterArgs callPkg callPkgs tryImport mkApp mkCheck liftFn2 fnConcat
|
||||
fnMergeAttrs;
|
||||
};
|
||||
builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k))
|
||||
(readDir ./builtinModules);
|
||||
|
||||
/* Module which is always included as first module.
|
||||
*/
|
||||
baseModule = { inputs, root, args }: {
|
||||
# Ensures nixpkgs and flakelite are available for modules.
|
||||
inputs = {
|
||||
flakelite = localInputs.self;
|
||||
inherit (localInputs) nixpkgs;
|
||||
};
|
||||
withOverlay = final: prev: {
|
||||
# Allows access to flakelite lib functions from package sets.
|
||||
# Also adds pkgs-specific additional args.
|
||||
flakelite = args // {
|
||||
# Inputs with system auto-selected.
|
||||
# i.e. inputs.self.packages.${system} -> inputs'.self.packages
|
||||
inputs' = mapAttrs
|
||||
(_: mapAttrs
|
||||
(_: v: v.${prev.system} or { }))
|
||||
inputs;
|
||||
# Default package meta attribute generated from root module attrs.
|
||||
meta = {
|
||||
platforms = root.systems;
|
||||
} // optionalAttrs (root ? description) {
|
||||
inherit (root) description;
|
||||
} // optionalAttrs (root ? license) {
|
||||
license =
|
||||
if isList root.license
|
||||
then attrVals root.license final.lib.licenses
|
||||
else final.lib.licenses.${root.license};
|
||||
};
|
||||
mkFlake = src: root: (evalModules {
|
||||
specialArgs.modulesPath = ./builtinModules;
|
||||
modules = builtinModules ++ [
|
||||
{ inputs.nixpkgs = mkDefault localInputs.nixpkgs; }
|
||||
{ _module.args = { inherit src flakelite; }; }
|
||||
root
|
||||
];
|
||||
}).config.outputs;
|
||||
|
||||
flakelite = {
|
||||
inherit mkFlake supportedSystem importDir autoImport;
|
||||
|
||||
types = {
|
||||
overlay = mkOptionType {
|
||||
name = "overlay";
|
||||
description = "nixpkgs overlay";
|
||||
descriptionClass = "noun";
|
||||
check = isFunction;
|
||||
merge = _: defs: composeManyExtensions (getValues defs);
|
||||
};
|
||||
# These attrs are important enough for top-level pkg set.
|
||||
inherit (final.flakelite) inputs inputs';
|
||||
|
||||
packageDef = mkOptionType {
|
||||
name = "packageDef";
|
||||
description = "package definition";
|
||||
descriptionClass = "noun";
|
||||
check = isFunction;
|
||||
};
|
||||
|
||||
path = mkOptionType {
|
||||
name = "path";
|
||||
description = "path";
|
||||
descriptionClass = "noun";
|
||||
check = isPath;
|
||||
};
|
||||
|
||||
module = mkOptionType {
|
||||
name = "module";
|
||||
description = "module";
|
||||
descriptionClass = "noun";
|
||||
check = x: isPath x || isFunction x || isAttrs x;
|
||||
merge = _: defs: { imports = getValues defs; };
|
||||
};
|
||||
|
||||
optListOf = elemType: coercedTo elemType singleton (listOf elemType);
|
||||
|
||||
optFunctionTo = elemType: coercedTo elemType (x: _: x)
|
||||
(functionTo elemType);
|
||||
};
|
||||
};
|
||||
|
||||
builtinModules = attrValues (importDir ./builtin-modules);
|
||||
supportedSystem = { lib, stdenv, ... }:
|
||||
lib.meta.availableOn stdenv.hostPlatform;
|
||||
|
||||
/* Import each nix file in a directory as attrs. Attr name is file name with
|
||||
extension stripped. To allow use in an importable directory, default.nix is
|
||||
skipped. To provide a file that will result in a "default" attr, name the
|
||||
file "_default.nix".
|
||||
*/
|
||||
importDir = path: genAttrs
|
||||
(pipe (readDir path) [
|
||||
attrNames
|
||||
@ -74,12 +78,6 @@ let
|
||||
(p: import (path + (if pathExists
|
||||
(path + "/_${p}.nix") then "/_${p}.nix" else "/${p}.nix")));
|
||||
|
||||
/* Try to load a name from a directory. If a nix file by that name exits,
|
||||
import it. If an importable directory with that name exists, import it.
|
||||
Else, if a non-importable directory with that name exists, load the nix
|
||||
files in that dir as an attrset. Returns null if the name could not be
|
||||
loaded. If name is a list, tries all names in that list.
|
||||
*/
|
||||
autoImport = dir: name:
|
||||
if isList name
|
||||
then findFirst (x: x != null) null (map (autoImport dir) name)
|
||||
@ -92,428 +90,8 @@ let
|
||||
then importDir (dir + "/${name}")
|
||||
else null;
|
||||
|
||||
/* List of attrs that can be provided by a module.
|
||||
*/
|
||||
moduleAttrs = [
|
||||
"inputs"
|
||||
"withOverlay"
|
||||
"withOverlays"
|
||||
"nixpkgsConfig"
|
||||
"package"
|
||||
"packages"
|
||||
"devTools"
|
||||
"shellHook"
|
||||
"devShell"
|
||||
"devShells"
|
||||
"env"
|
||||
"overlay"
|
||||
"overlays"
|
||||
"app"
|
||||
"apps"
|
||||
"checks"
|
||||
"nixosModule"
|
||||
"nixosModules"
|
||||
"nixosConfigurations"
|
||||
"homeModule"
|
||||
"homeModules"
|
||||
"homeConfigurations"
|
||||
"template"
|
||||
"templates"
|
||||
"formatters"
|
||||
];
|
||||
|
||||
/* List of handled attrs in root module. Does not have optionally checked
|
||||
attrs like name, description, or license, or attrs used by modules.
|
||||
*/
|
||||
rootAttrs = moduleAttrs ++ [
|
||||
"systems"
|
||||
"perSystem"
|
||||
"outputs"
|
||||
"nixDir"
|
||||
];
|
||||
|
||||
/* Alternative names for autoloading root attrs.
|
||||
*/
|
||||
attrAliases = {
|
||||
"nixosConfigurations" = [ "nixos" ];
|
||||
"homeConfigurations" = [ "home" ];
|
||||
# Lets `nix-shell` shell.nix be used automatically if no ./nix dir.
|
||||
"devShell" = [ "shell" ];
|
||||
"nixpkgsConfig" = [ "nixpkgs/config" ];
|
||||
};
|
||||
|
||||
/* Generate an attrset by importing attrs from dir. Filters null values.
|
||||
Alternative names from aliases are used.
|
||||
*/
|
||||
autoImportAttrs = dir: attrs: aliases:
|
||||
filterAttrs (_: v: v != null) (genAttrs attrs
|
||||
(attr: autoImport dir ([ attr ] ++ aliases.${attr} or [ ])));
|
||||
|
||||
/* Makes the parameter callable, if it isn't. This allows values that are not
|
||||
always functions to be applied to parameters.
|
||||
*/
|
||||
ensureFn = v: if isFunction v then v else _: v;
|
||||
|
||||
/* Takes a binary function and returns a binary function that operates on
|
||||
functions that return the original parameter types.
|
||||
|
||||
Type: liftFn2 :: (a -> b -> c) -> (d -> a) -> (d -> b) -> d -> c
|
||||
*/
|
||||
liftFn2 = fn: a: b: args: fn (a args) (b args);
|
||||
|
||||
fnConcat = liftFn2 concat;
|
||||
fnMergeAttrs = liftFn2 mergeAttrs;
|
||||
|
||||
/* Takes a function which takes a list, and returns a binary function.
|
||||
|
||||
Type: mkBinary :: ([a] -> b) -> a -> a -> b
|
||||
*/
|
||||
mkBinary = fn: a: b: fn [ a b ];
|
||||
|
||||
/* Merges attrsets of overlays, combining overlays with same name.
|
||||
*/
|
||||
mergeOverlayAttrs = mkBinary (zipAttrsWith (_: composeManyExtensions));
|
||||
|
||||
fnConcatScripts = liftFn2 (mkBinary (concatStringsSep "\n"));
|
||||
|
||||
mergeModules = a: b: mapAttrs (n: v: v a.${n} b.${n}) {
|
||||
inputs = mergeAttrs;
|
||||
withOverlays = concat;
|
||||
nixpkgsConfig = mergeAttrs;
|
||||
packages = mergeAttrs;
|
||||
devTools = fnConcat;
|
||||
shellHook = fnConcatScripts;
|
||||
devShells = fnMergeAttrs;
|
||||
env = fnMergeAttrs;
|
||||
overlays = mergeOverlayAttrs;
|
||||
apps = fnMergeAttrs;
|
||||
checks = fnMergeAttrs;
|
||||
nixosModules = mergeAttrs;
|
||||
nixosConfigurations = mergeAttrs;
|
||||
homeModules = mergeAttrs;
|
||||
homeConfigurations = mergeAttrs;
|
||||
templates = mergeAttrs;
|
||||
formatters = fnMergeAttrs;
|
||||
};
|
||||
|
||||
/* Calls f with required arguments from args. If the function does not have
|
||||
named arguments, just passes it args instead of nothing like callPackage
|
||||
does. If f is not a function, returns f.
|
||||
*/
|
||||
callFn = args: f:
|
||||
let
|
||||
f' = ensureFn f;
|
||||
in
|
||||
if functionArgs f' == { } then f' args
|
||||
else f' (intersectAttrs (functionArgs f) args);
|
||||
|
||||
/* Ensures x is called with only it's required parameters.
|
||||
*/
|
||||
filterArgs = x: args: callFn args x;
|
||||
|
||||
/* If arg is importable, imports it, else returns arg as is.
|
||||
*/
|
||||
tryImport = x: if (isPath x) || (isString x) then import x else x;
|
||||
|
||||
/* Like callFn, but intended for functions that return derivations. Uses
|
||||
callPackage so will make result overridable. Trys importing the value if a
|
||||
path.
|
||||
*/
|
||||
callPkg = args: f:
|
||||
let
|
||||
f' = ensureFn (tryImport f);
|
||||
in
|
||||
if functionArgs f' == { } then f' args
|
||||
else (args.callPackage or (callPackageWith args)) f' { };
|
||||
|
||||
callPkgs = pkgs: mapAttrs (_: callPkg pkgs);
|
||||
|
||||
/* Gets the name for the default package using value set in root module or
|
||||
derivation attrs.
|
||||
*/
|
||||
defaultPkgName = root: pkg: root.name or pkg.pname or (parseDrvName pkg).name;
|
||||
|
||||
/* Merges elements of a list of sets recursively. Each element can optionally
|
||||
be a function that takes the merged previous elements.
|
||||
*/
|
||||
recUpdateSets = foldl (acc: x: recursiveUpdate acc ((ensureFn x) acc)) { };
|
||||
|
||||
isApp = x: (x ? type) && (x.type == "app") && (x ? program);
|
||||
|
||||
/* Turns app into an app attribute, if it is not already. Passes it pkgs if it
|
||||
is a function.
|
||||
*/
|
||||
mkApp = pkgs: app:
|
||||
let
|
||||
app' = callFn pkgs app;
|
||||
in
|
||||
if isApp app' then app'
|
||||
else { type = "app"; program = "${app'}"; };
|
||||
|
||||
/* Makes cmd into a derivation for a flake's checks output. If it is not
|
||||
already a derivation, makes one that runs cmd on the flake source and
|
||||
depends on its success. Passes cmd pkgs if it is its a function.
|
||||
*/
|
||||
mkCheck = pkgs: src: name: cmd:
|
||||
let
|
||||
cmd' = callFn pkgs cmd;
|
||||
in
|
||||
if pkgs.lib.isDerivation cmd' then cmd' else
|
||||
pkgs.runCommand "check-${name}" { } ''
|
||||
cp --no-preserve=mode -r ${src} src
|
||||
cd src
|
||||
${cmd'}
|
||||
touch $out
|
||||
'';
|
||||
|
||||
/* Takes a packages set and a package and returns true if the package is
|
||||
supported on the system for that packages set. If unknown, returns true.
|
||||
*/
|
||||
supportedSystem = { lib, stdenv, ... }: pkg:
|
||||
if pkg ? meta.platforms
|
||||
then lib.meta.availableOn stdenv.hostPlatform pkg
|
||||
else true;
|
||||
|
||||
systems = rec {
|
||||
# Linux systems with binary caches.
|
||||
linuxDefault = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
# Linux systems supported as a host platform.
|
||||
linuxAll = linuxDefault ++ [
|
||||
"armv6l-linux"
|
||||
"armv7l-linux"
|
||||
"i686-linux"
|
||||
];
|
||||
};
|
||||
|
||||
/* Creates flake outputs; takes the path of the flake and the root module.
|
||||
*/
|
||||
mkFlake = src: root:
|
||||
let
|
||||
# These are passed to modules and non-system-dependent module attrs.
|
||||
nonSysArgs = exports // {
|
||||
args = nonSysArgs;
|
||||
flakelite = exports;
|
||||
root = root';
|
||||
inherit src;
|
||||
inherit (merged) inputs;
|
||||
inherit (merged.inputs.nixpkgs) lib;
|
||||
};
|
||||
|
||||
applyNonSysArgs = callFn nonSysArgs;
|
||||
|
||||
moduleAttrDefaults = {
|
||||
inputs = { };
|
||||
withOverlays = [ ];
|
||||
nixpkgsConfig = { };
|
||||
packages = { };
|
||||
devTools = _: [ ];
|
||||
shellHook = _: "";
|
||||
devShells = _: { };
|
||||
env = _: { };
|
||||
overlays = { };
|
||||
apps = _: { };
|
||||
checks = _: { };
|
||||
nixosModules = { };
|
||||
nixosConfigurations = { };
|
||||
homeModules = { };
|
||||
homeConfigurations = { };
|
||||
templates = { };
|
||||
formatters = _: { };
|
||||
};
|
||||
|
||||
normalizeModule = module:
|
||||
let
|
||||
module' = moduleAttrDefaults // module;
|
||||
in
|
||||
module' // {
|
||||
withOverlays = (applyNonSysArgs module'.withOverlays)
|
||||
++ optional (module' ? withOverlay) module'.withOverlay;
|
||||
nixpkgsConfig = applyNonSysArgs module'.nixpkgsConfig;
|
||||
packages = (applyNonSysArgs module'.packages)
|
||||
// optionalAttrs (module' ? package) {
|
||||
default = module'.package;
|
||||
};
|
||||
devTools = filterArgs module'.devTools;
|
||||
shellHook = filterArgs module'.shellHook;
|
||||
devShells = fnMergeAttrs (filterArgs module'.devShells)
|
||||
(_: optionalAttrs (module' ? devShell) {
|
||||
default = module'.devShell;
|
||||
});
|
||||
env = filterArgs module'.env;
|
||||
overlays = (applyNonSysArgs module'.overlays)
|
||||
// optionalAttrs (module' ? overlay) {
|
||||
default = module'.overlay;
|
||||
};
|
||||
apps = fnMergeAttrs (filterArgs module'.apps)
|
||||
(_: optionalAttrs (module' ? app) {
|
||||
default = module'.app;
|
||||
});
|
||||
checks = filterArgs module'.checks;
|
||||
nixosModules = (applyNonSysArgs module'.nixosModules)
|
||||
// optionalAttrs (module' ? nixosModule) {
|
||||
default = module'.nixosModule;
|
||||
};
|
||||
nixosConfigurations = applyNonSysArgs module'.nixosConfigurations;
|
||||
homeModules = (applyNonSysArgs module'.homeModules)
|
||||
// optionalAttrs (module' ? homeModule) {
|
||||
default = module'.homeModule;
|
||||
};
|
||||
homeConfigurations = applyNonSysArgs module'.homeConfigurations;
|
||||
templates = (applyNonSysArgs module'.templates)
|
||||
// optionalAttrs (module' ? template) {
|
||||
default = module'.template;
|
||||
};
|
||||
formatters = filterArgs module'.formatters;
|
||||
};
|
||||
|
||||
# Root module with autoloads, normalization, and additional attrs.
|
||||
root' =
|
||||
let
|
||||
appliedRoot = applyNonSysArgs root;
|
||||
nixDir = appliedRoot.nixDir or (src + /nix);
|
||||
fullRoot = (autoImportAttrs nixDir rootAttrs attrAliases)
|
||||
// appliedRoot;
|
||||
in
|
||||
normalizeModule fullRoot // {
|
||||
modules = fullRoot.modules or
|
||||
(pipe (removeAttrs root'.inputs [ "self" ]) [
|
||||
(filterAttrs (_: v: v ? flakeliteModule))
|
||||
(mapAttrsToList (_: v: v.flakeliteModule))
|
||||
]);
|
||||
systems = applyNonSysArgs (fullRoot.systems or systems.linuxDefault);
|
||||
perSystem = filterArgs (fullRoot.perSystem or { });
|
||||
outputs = applyNonSysArgs (fullRoot.outputs or { });
|
||||
inherit nixDir;
|
||||
};
|
||||
|
||||
modules = [ baseModule ] ++ builtinModules ++ root'.modules;
|
||||
|
||||
# Merge result of all the modules.
|
||||
merged = foldl mergeModules moduleAttrDefaults
|
||||
((map (m: normalizeModule (applyNonSysArgs m)) modules)
|
||||
++ [ root' ]);
|
||||
|
||||
# Returns package set for a system.
|
||||
pkgsFor = system: import merged.inputs.nixpkgs {
|
||||
inherit system;
|
||||
config = merged.nixpkgsConfig;
|
||||
overlays = merged.withOverlays ++ [
|
||||
(final: _: callPkgs final merged.packages)
|
||||
];
|
||||
};
|
||||
|
||||
# Attrset mapping systems to corresponding package sets.
|
||||
systemPkgs = listToAttrs (map
|
||||
(system: nameValuePair system (pkgsFor system))
|
||||
root'.systems);
|
||||
|
||||
# Calls fn for each supported system. Fn should return an attrset whose
|
||||
# attrs normally would have values in system attrs. Merges results into
|
||||
# attrset with system attrs.
|
||||
eachSystem = fn: foldAttrs mergeAttrs { } (map
|
||||
(system: mapAttrs
|
||||
(_: v: { ${system} = v; })
|
||||
(fn systemPkgs.${system}))
|
||||
root'.systems);
|
||||
|
||||
# Replaces the "default" attr in set with the default package name.
|
||||
replaceDefault = set:
|
||||
if set ? default
|
||||
then (removeAttrs set [ "default" ]) //
|
||||
{ ${defaultPkgName root' set.default} = set.default; }
|
||||
else set;
|
||||
in
|
||||
recUpdateSets [
|
||||
(optionalAttrs (merged.packages != { }) ({
|
||||
# Packages in overlay depend on withOverlays which are not in pkg set.
|
||||
overlays.default = final: _: callPkgs
|
||||
(final.appendOverlays merged.withOverlays)
|
||||
(replaceDefault merged.packages);
|
||||
} // eachSystem (pkgs: rec {
|
||||
# Packages are generated in overlay on system pkgs; grab from there.
|
||||
packages = filterAttrs (_: supportedSystem pkgs)
|
||||
(intersectAttrs merged.packages pkgs);
|
||||
checks = mapAttrs' (n: nameValuePair ("packages-" + n)) packages;
|
||||
})))
|
||||
(prev: optionalAttrs (merged.overlays != { }) ({
|
||||
overlays = mergeOverlayAttrs (prev.overlays or { }) merged.overlays;
|
||||
}))
|
||||
(eachSystem ({ pkgs, lib, ... }:
|
||||
optionalAttrs (merged.formatters pkgs != { }) rec {
|
||||
formatter = pkgs.writeShellScriptBin "formatter" ''
|
||||
PATH=${lib.makeBinPath (merged.devTools pkgs)}
|
||||
for f in "$@"; do
|
||||
if [ -d "$f" ]; then
|
||||
${pkgs.fd}/bin/fd "$f" -Htf -x "$0"
|
||||
else
|
||||
case "$(${pkgs.coreutils}/bin/basename "$f")" in
|
||||
${toString (mapAttrsToList
|
||||
(n: v: "${n}) ${callFn pkgs v} \"$f\";;")
|
||||
(merged.formatters pkgs))}
|
||||
esac
|
||||
fi
|
||||
done &>/dev/null
|
||||
'';
|
||||
checks.formatting = mkCheck pkgs src "formatting" ''
|
||||
${lib.getExe formatter} .
|
||||
${pkgs.diffutils}/bin/diff -qr ${src} . |\
|
||||
sed 's/Files .* and \(.*\) differ/File \1 not formatted/g'
|
||||
'';
|
||||
}))
|
||||
(eachSystem (pkgs:
|
||||
let
|
||||
checks = mapAttrs (mkCheck pkgs src) (merged.checks pkgs);
|
||||
in
|
||||
optionalAttrs (checks != { }) { inherit checks; }))
|
||||
(eachSystem (pkgs:
|
||||
let
|
||||
apps = mapAttrs (_: mkApp pkgs) (merged.apps pkgs);
|
||||
in
|
||||
optionalAttrs (apps != { }) { inherit apps; }))
|
||||
(optionalAttrs (merged.nixosModules != { }) {
|
||||
inherit (merged) nixosModules;
|
||||
})
|
||||
(optionalAttrs (merged.nixosConfigurations != { }) {
|
||||
inherit (merged) nixosConfigurations;
|
||||
checks = recUpdateSets (mapAttrsToList
|
||||
(n: v: {
|
||||
${v.config.nixpkgs.system}."nixos-${n}" =
|
||||
v.config.system.build.toplevel;
|
||||
})
|
||||
merged.nixosConfigurations);
|
||||
})
|
||||
(optionalAttrs (merged.homeModules != { }) {
|
||||
inherit (merged) homeModules;
|
||||
})
|
||||
(optionalAttrs (merged.homeConfigurations != { }) {
|
||||
inherit (merged) homeConfigurations;
|
||||
checks = recUpdateSets (mapAttrsToList
|
||||
(n: v: {
|
||||
${v.config.nixpkgs.system}."home-${n}" = v.activationPackage;
|
||||
})
|
||||
merged.homeConfigurations);
|
||||
})
|
||||
(optionalAttrs (merged.templates != { }) {
|
||||
inherit (merged) templates;
|
||||
})
|
||||
(prev: eachSystem ({ pkgs, system, mkShell, ... }: {
|
||||
devShells = {
|
||||
default = mkShell (merged.env pkgs // {
|
||||
inputsFrom = optional (prev ? packages.${system}.default)
|
||||
prev.packages.${system}.default;
|
||||
packages = merged.devTools pkgs;
|
||||
shellHook = merged.shellHook pkgs;
|
||||
});
|
||||
} // (callPkgs pkgs (merged.devShells pkgs));
|
||||
}))
|
||||
(eachSystem root'.perSystem)
|
||||
(_: root'.outputs)
|
||||
];
|
||||
in
|
||||
{
|
||||
lib = exports;
|
||||
lib = flakelite;
|
||||
__functor = _: mkFlake;
|
||||
}
|
||||
|
@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1680665430,
|
||||
"narHash": "sha256-MTVhTukwza1Jlq2gECITZPFnhROmylP2uv3O3cSqQCE=",
|
||||
"lastModified": 1692447944,
|
||||
"narHash": "sha256-fkJGNjEmTPvqBs215EQU4r9ivecV5Qge5cF/QDLVn3U=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5233fd2ba76a3accb5aaa999c00509a11fd0793c",
|
||||
"rev": "d680ded26da5cf104dd2735a51e88d2d8f487b4d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-22.11",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
|
@ -3,13 +3,10 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
{
|
||||
inputs.nixpkgs.url = "nixpkgs/nixos-22.11";
|
||||
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||
outputs = inputs:
|
||||
let
|
||||
flakelite = import ./. inputs;
|
||||
in
|
||||
flakelite ./. {
|
||||
nixDir = ./.;
|
||||
outputs = _: flakelite;
|
||||
};
|
||||
flakelite ./. { outputs = flakelite; };
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
{ writeShellApplication
|
||||
, coreutils
|
||||
, nix
|
||||
, git
|
||||
, gnutar
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "pre-commit";
|
||||
runtimeInputs = [ coreutils nix git gnutar ];
|
||||
text = ''
|
||||
TREE=$(mktemp -d)
|
||||
git archive "$(git write-tree)" | tar -xC "$TREE"
|
||||
nix flake check "$TREE"
|
||||
'';
|
||||
}
|
Loading…
Reference in New Issue
Block a user