Add functor option for flake's __functor attribute

This allows for conveniently making flakes callable.

Setting this is expected to be uncommon in general, but having the
option is useful as flakelight module flakes can use this to reduce the
boilerplate in using them.
This commit is contained in:
Archit Gupta 2023-09-13 21:00:14 -07:00
parent 46ade23b8c
commit 62083df539
5 changed files with 58 additions and 12 deletions

View File

@ -684,6 +684,32 @@ These can be paths, which is preferred as it results in better debug output:
} }
``` ```
### functor
The `functor` option allows you to make your flake callable.
If it is set to a function, that function will be set as the `__functor`
attribute of your flake outputs.
Flakelight uses it so that calling your `flakelight` input calls
`flakelight.lib.mkFlake`.
As an example:
```nix
{
inputs.flakelight.url = "github:accelbread/flakelight";
outputs = { flakelight, ... }:
flakelight ./. {
outputs.testvalue = 5;
functor = self: x: x + self.testvalue;
}
}
```
With the above flake, another flake that has imports it with the name `addFive`
would be able to call `addFive 4` to get 9.
### meta ### meta
The following options are available for configuring the meta attributes of the The following options are available for configuring the meta attributes of the
@ -746,6 +772,7 @@ The following options can be autoloaded (no module args):
- nixosModule - nixosModule
- homeModule - homeModule
- flakelightModule - flakelightModule
- functor
### flakelight ### flakelight

View File

@ -0,0 +1,19 @@
# flakelight -- Framework for simplifying flake setup
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT
{ config, lib, ... }:
let
inherit (lib) mkOption mkIf;
inherit (lib.types) functionTo nullOr raw uniq;
in
{
options.functor = mkOption {
type = nullOr (uniq (functionTo (functionTo raw)));
default = null;
};
config.outputs = mkIf (config.functor != null) {
__functor = config.functor;
};
}

View File

@ -43,6 +43,7 @@ in
homeConfigurations = autoImportArgs' [ "homeConfigurations" "home" ]; homeConfigurations = autoImportArgs' [ "homeConfigurations" "home" ];
flakelightModule = autoImport' "flakelightModule"; flakelightModule = autoImport' "flakelightModule";
flakelightModules = autoImportArgs' "flakelightModules"; flakelightModules = autoImportArgs' "flakelightModules";
functor = autoImport' "functor";
in in
mkMerge [ mkMerge [
{ _module.args = { inherit autoloadArgs; }; } { _module.args = { inherit autoloadArgs; }; }
@ -78,5 +79,6 @@ in
(mkIf (homeConfigurations != null) { inherit homeConfigurations; }) (mkIf (homeConfigurations != null) { inherit homeConfigurations; })
(mkIf (flakelightModule != null) { inherit flakelightModule; }) (mkIf (flakelightModule != null) { inherit flakelightModule; })
(mkIf (flakelightModules != null) { inherit flakelightModules; }) (mkIf (flakelightModules != null) { inherit flakelightModules; })
(mkIf (functor != null) { inherit functor; })
]; ];
} }

View File

@ -2,14 +2,14 @@
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com> # Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
localInputs: nixpkgs:
let let
inherit (builtins) isAttrs isPath readDir; inherit (builtins) isAttrs isPath readDir;
inherit (localInputs.nixpkgs.lib) attrNames composeManyExtensions inherit (nixpkgs.lib) attrNames composeManyExtensions
filter findFirst genAttrs getValues hasSuffix isFunction isList filter findFirst genAttrs getValues hasSuffix isFunction isList
mapAttrsToList pathExists pipe removePrefix removeSuffix evalModules mapAttrsToList pathExists pipe removePrefix removeSuffix evalModules
mkDefault mkOptionType singleton; mkDefault mkOptionType singleton;
inherit (localInputs.nixpkgs.lib.types) coercedTo functionTo listOf; inherit (nixpkgs.lib.types) coercedTo functionTo listOf;
builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k)) builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k))
(readDir ./builtinModules); (readDir ./builtinModules);
@ -17,7 +17,7 @@ let
mkFlake = src: root: (evalModules { mkFlake = src: root: (evalModules {
specialArgs.modulesPath = ./builtinModules; specialArgs.modulesPath = ./builtinModules;
modules = builtinModules ++ [ modules = builtinModules ++ [
{ inputs.nixpkgs = mkDefault localInputs.nixpkgs; } { inputs.nixpkgs = mkDefault nixpkgs; }
{ _module.args = { inherit src flakelight; }; } { _module.args = { inherit src flakelight; }; }
root root
]; ];
@ -94,7 +94,4 @@ let
let v = autoImport dir name; in let v = autoImport dir name; in
if isFunction v then v args else v; if isFunction v then v args else v;
in in
{ flakelight
lib = flakelight;
__functor = _: mkFlake;
}

View File

@ -6,10 +6,11 @@
description = description =
"A modular Nix flake framework for simplifying flake definitions"; "A modular Nix flake framework for simplifying flake definitions";
inputs.nixpkgs.url = "nixpkgs/nixos-unstable"; inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
outputs = inputs: outputs = { nixpkgs, ... }:
let flakelight = import ./. inputs; in let lib = import ./. nixpkgs; in
flakelight ./. { lib.mkFlake ./. {
outputs = flakelight; outputs = { inherit lib; };
functor = _: lib.mkFlake;
templates = import ./templates; templates = import ./templates;
checks.statix = pkgs: "${pkgs.statix}/bin/statix check"; checks.statix = pkgs: "${pkgs.statix}/bin/statix check";
}; };