1
1
forked from extern/flakelight

Replace nixpkgs nullOr type with custom type

`nullOr`'s merge function requires definitions to all be null or all be
non-null. It was being used where the intent was that null be used as a
value representing unset, and as such the merge should return null if
all definitions are null and ignore nulls otherwise. This adds a type
with that merge semantics.
This commit is contained in:
Archit Gupta 2024-02-07 00:54:03 -08:00
parent 9fe4cb1994
commit 543e3aaa4d
15 changed files with 74 additions and 50 deletions

View File

@ -5,8 +5,8 @@
{ config, lib, flakelight, genSystems, ... }: { config, lib, flakelight, genSystems, ... }:
let let
inherit (lib) isFunction mapAttrs mkIf mkMerge mkOption; inherit (lib) isFunction mapAttrs mkIf mkMerge mkOption;
inherit (lib.types) lazyAttrsOf nullOr raw; inherit (lib.types) lazyAttrsOf raw;
inherit (flakelight.types) optFunctionTo; inherit (flakelight.types) nullable optFunctionTo;
isApp = x: (x ? type) && (x.type == "app") && (x ? program); isApp = x: (x ? type) && (x.type == "app") && (x ? program);
@ -17,12 +17,12 @@ in
{ {
options = { options = {
app = mkOption { app = mkOption {
type = nullOr raw; type = nullable raw;
default = null; default = null;
}; };
apps = mkOption { apps = mkOption {
type = nullOr (optFunctionTo (lazyAttrsOf raw)); type = nullable (optFunctionTo (lazyAttrsOf raw));
default = null; default = null;
}; };
}; };

View File

@ -5,14 +5,15 @@
{ config, src, lib, inputs, outputs, flakelight, moduleArgs, ... }: { config, src, lib, inputs, outputs, flakelight, moduleArgs, ... }:
let let
inherit (lib) isList mkOption mkOrder mapAttrs optionalAttrs; inherit (lib) isList mkOption mkOrder mapAttrs optionalAttrs;
inherit (lib.types) listOf nullOr oneOf str; inherit (lib.types) listOf oneOf str;
inherit (builtins) pathExists; inherit (builtins) pathExists;
inherit (flakelight) selectAttr; inherit (flakelight) selectAttr;
inherit (flakelight.types) nullable;
in in
{ {
options = { options = {
description = mkOption { description = mkOption {
type = nullOr str; type = nullable str;
default = default =
if pathExists (src + /flake.nix) if pathExists (src + /flake.nix)
then (import (src + /flake.nix)).description or null then (import (src + /flake.nix)).description or null
@ -20,7 +21,7 @@ in
}; };
license = mkOption { license = mkOption {
type = nullOr (oneOf [ str (listOf str) ]); type = nullable (oneOf [ str (listOf str) ]);
default = null; default = null;
}; };
}; };

View File

@ -5,8 +5,8 @@
{ config, lib, flakelight, genSystems, ... }: { config, lib, flakelight, genSystems, ... }:
let let
inherit (lib) isFunction mapAttrs mkMerge mkOption mkIf; inherit (lib) isFunction mapAttrs mkMerge mkOption mkIf;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (flakelight.types) function optFunctionTo; inherit (flakelight.types) function nullable optFunctionTo;
wrapBundler = pkgs: bundler: drv: wrapBundler = pkgs: bundler: drv:
if isFunction (bundler (pkgs // drv)) if isFunction (bundler (pkgs // drv))
@ -16,12 +16,12 @@ in
{ {
options = { options = {
bundler = mkOption { bundler = mkOption {
type = nullOr function; type = nullable function;
default = null; default = null;
}; };
bundlers = mkOption { bundlers = mkOption {
type = nullOr (optFunctionTo (lazyAttrsOf function)); type = nullable (optFunctionTo (lazyAttrsOf function));
default = null; default = null;
}; };
}; };

View File

@ -5,8 +5,8 @@
{ config, src, lib, flakelight, genSystems, ... }: { config, src, lib, flakelight, genSystems, ... }:
let let
inherit (lib) isDerivation isFunction mkOption mkIf mapAttrs; inherit (lib) isDerivation isFunction mkOption mkIf mapAttrs;
inherit (lib.types) lazyAttrsOf nullOr raw; inherit (lib.types) lazyAttrsOf raw;
inherit (flakelight.types) optFunctionTo; inherit (flakelight.types) nullable optFunctionTo;
mkCheck = pkgs: name: cmd: mkCheck = pkgs: name: cmd:
let cmd' = if isFunction cmd then cmd pkgs else cmd; in let cmd' = if isFunction cmd then cmd pkgs else cmd; in
@ -20,7 +20,7 @@ let
in in
{ {
options.checks = mkOption { options.checks = mkOption {
type = nullOr (optFunctionTo (lazyAttrsOf raw)); type = nullable (optFunctionTo (lazyAttrsOf raw));
default = null; default = null;
}; };

View File

@ -6,10 +6,11 @@
let let
inherit (lib) filterAttrs functionArgs mapAttrs mkDefault mkIf mkMerge inherit (lib) filterAttrs functionArgs mapAttrs mkDefault mkIf mkMerge
mkOption; mkOption;
inherit (lib.types) attrs coercedTo functionTo lazyAttrsOf lines listOf nullOr inherit (lib.types) attrs coercedTo functionTo lazyAttrsOf lines listOf
package str submodule; package str submodule;
inherit (flakelight) supportedSystem; inherit (flakelight) supportedSystem;
inherit (flakelight.types) function optCallWith optFunctionTo packageDef; inherit (flakelight.types) function nullable optCallWith optFunctionTo
packageDef;
devShellModule.options = { devShellModule.options = {
inputsFrom = mkOption { inputsFrom = mkOption {
@ -38,7 +39,7 @@ let
}; };
overrideShell = mkOption { overrideShell = mkOption {
type = nullOr packageDef; type = nullable packageDef;
internal = true; internal = true;
default = null; default = null;
}; };
@ -53,7 +54,7 @@ in
options = { options = {
devShell = mkOption { devShell = mkOption {
default = null; default = null;
type = nullOr (coercedTo function wrapFn type = nullable (coercedTo function wrapFn
(coercedTo attrs (x: _: x) (coercedTo attrs (x: _: x)
(functionTo (submodule devShellModule)))); (functionTo (submodule devShellModule))));
}; };

View File

@ -5,13 +5,13 @@
{ config, lib, flakelight, moduleArgs, ... }: { config, lib, flakelight, moduleArgs, ... }:
let let
inherit (lib) mkOption mkIf mkMerge; inherit (lib) mkOption mkIf mkMerge;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (flakelight.types) module optCallWith; inherit (flakelight.types) module nullable optCallWith;
in in
{ {
options = { options = {
flakelightModule = mkOption { flakelightModule = mkOption {
type = nullOr module; type = nullable module;
default = null; default = null;
}; };

View File

@ -5,17 +5,17 @@
{ config, src, lib, flakelight, genSystems, ... }: { config, src, lib, flakelight, genSystems, ... }:
let let
inherit (lib) mkDefault mkMerge mkOption mkIf mapAttrsToList; inherit (lib) mkDefault mkMerge mkOption mkIf mapAttrsToList;
inherit (lib.types) functionTo lazyAttrsOf nullOr package str; inherit (lib.types) functionTo lazyAttrsOf package str;
inherit (flakelight.types) optFunctionTo; inherit (flakelight.types) nullable optFunctionTo;
in in
{ {
options = { options = {
formatter = mkOption { formatter = mkOption {
type = nullOr (functionTo package); type = nullable (functionTo package);
default = null; default = null;
}; };
formatters = mkOption { formatters = mkOption {
type = nullOr (optFunctionTo (lazyAttrsOf str)); type = nullable (optFunctionTo (lazyAttrsOf str));
default = null; default = null;
}; };
}; };

View File

@ -2,14 +2,15 @@
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com> # Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
{ config, lib, ... }: { config, lib, flakelight, ... }:
let let
inherit (lib) mkOption mkIf; inherit (lib) mkOption mkIf;
inherit (lib.types) functionTo nullOr raw uniq; inherit (lib.types) functionTo raw uniq;
inherit (flakelight.types) nullable;
in in
{ {
options.functor = mkOption { options.functor = mkOption {
type = nullOr (uniq (functionTo (functionTo raw))); type = nullable (uniq (functionTo (functionTo raw)));
default = null; default = null;
}; };

View File

@ -5,13 +5,13 @@
{ config, lib, flakelight, moduleArgs, ... }: { config, lib, flakelight, moduleArgs, ... }:
let let
inherit (lib) mkOption mkIf mkMerge; inherit (lib) mkOption mkIf mkMerge;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (flakelight.types) module optCallWith; inherit (flakelight.types) module nullable optCallWith;
in in
{ {
options = { options = {
homeModule = mkOption { homeModule = mkOption {
type = nullOr module; type = nullable module;
default = null; default = null;
}; };

View File

@ -2,14 +2,15 @@
# Copyright (C) 2023 Archit Gupta <archit@accelbread.com> # Copyright (C) 2023 Archit Gupta <archit@accelbread.com>
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
{ config, lib, genSystems, ... }: { config, lib, flakelight, genSystems, ... }:
let let
inherit (lib) mkIf mkOption; inherit (lib) mkIf mkOption;
inherit (lib.types) functionTo nullOr pkgs; inherit (lib.types) functionTo pkgs;
inherit (flakelight.types) nullable;
in in
{ {
options.legacyPackages = mkOption { options.legacyPackages = mkOption {
type = nullOr (functionTo pkgs); type = nullable (functionTo pkgs);
default = null; default = null;
}; };

View File

@ -5,13 +5,13 @@
{ config, lib, flakelight, moduleArgs, ... }: { config, lib, flakelight, moduleArgs, ... }:
let let
inherit (lib) mkOption mkIf mkMerge; inherit (lib) mkOption mkIf mkMerge;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (flakelight.types) module optCallWith; inherit (flakelight.types) module nullable optCallWith;
in in
{ {
options = { options = {
nixosModule = mkOption { nixosModule = mkOption {
type = nullOr module; type = nullable module;
default = null; default = null;
}; };

View File

@ -5,13 +5,13 @@
{ config, lib, flakelight, moduleArgs, ... }: { config, lib, flakelight, moduleArgs, ... }:
let let
inherit (lib) mkMerge mkOption mkIf; inherit (lib) mkMerge mkOption mkIf;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (flakelight.types) optCallWith overlay; inherit (flakelight.types) nullable optCallWith overlay;
in in
{ {
options = { options = {
overlay = mkOption { overlay = mkOption {
type = nullOr overlay; type = nullable overlay;
default = null; default = null;
}; };

View File

@ -7,9 +7,9 @@ let
inherit (builtins) hasAttr parseDrvName tryEval; inherit (builtins) hasAttr parseDrvName tryEval;
inherit (lib) filterAttrs findFirst functionArgs mapAttrs' mapAttrs mkIf inherit (lib) filterAttrs findFirst functionArgs mapAttrs' mapAttrs mkIf
mkMerge mkOption nameValuePair optionalAttrs; mkMerge mkOption nameValuePair optionalAttrs;
inherit (lib.types) lazyAttrsOf nullOr str uniq; inherit (lib.types) lazyAttrsOf str uniq;
inherit (flakelight) supportedSystem; inherit (flakelight) supportedSystem;
inherit (flakelight.types) optCallWith overlay packageDef; inherit (flakelight.types) nullable optCallWith overlay packageDef;
genPkg = final: prev: name: pkg: genPkg = final: prev: name: pkg:
let let
@ -32,7 +32,7 @@ in
{ {
options = { options = {
package = mkOption { package = mkOption {
type = nullOr packageDef; type = nullable packageDef;
default = null; default = null;
}; };
@ -42,7 +42,7 @@ in
}; };
pname = mkOption { pname = mkOption {
type = nullOr str; type = nullable str;
default = null; default = null;
}; };

View File

@ -6,9 +6,9 @@
let let
inherit (builtins) isPath isString; inherit (builtins) isPath isString;
inherit (lib) mkOption mkOptionType mkIf mkMerge; inherit (lib) mkOption mkOptionType mkIf mkMerge;
inherit (lib.types) lazyAttrsOf nullOr; inherit (lib.types) lazyAttrsOf;
inherit (lib.options) mergeEqualOption; inherit (lib.options) mergeEqualOption;
inherit (flakelight.types) optCallWith; inherit (flakelight.types) nullable optCallWith;
template = mkOptionType { template = mkOptionType {
name = "template"; name = "template";
@ -23,7 +23,7 @@ in
{ {
options = { options = {
template = mkOption { template = mkOption {
type = nullOr (optCallWith moduleArgs template); type = nullable (optCallWith moduleArgs template);
default = null; default = null;
}; };

View File

@ -6,11 +6,12 @@ inputs:
let let
inherit (inputs) nixpkgs; inherit (inputs) nixpkgs;
inherit (builtins) isAttrs isPath readDir; inherit (builtins) isAttrs isPath readDir;
inherit (nixpkgs.lib) attrNames composeManyExtensions evalModules filter inherit (nixpkgs.lib) all attrNames composeManyExtensions evalModules filter
findFirst fix genAttrs getValues hasSuffix isFunction isList mapAttrs findFirst fix genAttrs getValues hasSuffix isFunction isList mapAttrs
mapAttrsToList mkDefault mkOptionType pathExists pipe removePrefix mapAttrsToList mkDefault mkOptionType pathExists pipe removePrefix
removeSuffix singleton warn; removeSuffix singleton warn;
inherit (nixpkgs.lib.types) coercedTo functionTo listOf; inherit (nixpkgs.lib.types) coercedTo defaultFunctor functionTo listOf
optionDescriptionPhrase;
inherit (nixpkgs.lib.options) mergeEqualOption mergeOneOption; inherit (nixpkgs.lib.options) mergeEqualOption mergeOneOption;
builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k)) builtinModules = mapAttrsToList (k: _: ./builtinModules + ("/" + k))
@ -40,7 +41,7 @@ let
supportedSystem types; supportedSystem types;
}; };
types = { types = rec {
overlay = mkOptionType { overlay = mkOptionType {
name = "overlay"; name = "overlay";
description = "nixpkgs overlay"; description = "nixpkgs overlay";
@ -95,6 +96,25 @@ let
optCallWith = args: elemType: coercedTo (functionTo elemType) (x: x args) optCallWith = args: elemType: coercedTo (functionTo elemType) (x: x args)
elemType; elemType;
nullable = elemType: mkOptionType {
name = "nullable";
description = "nullable ${optionDescriptionPhrase
(class: class == "noun" || class == "composite") elemType}";
descriptionClass = "noun";
check = x: x == null || elemType.check x;
merge = loc: defs:
if all (def: def.value == null) defs then null
else elemType.merge loc (filter (def: def.value != null) defs);
emptyValue.value = null;
inherit (elemType) getSubOptions getSubModules;
substSubModules = m: nullable (elemType.substSubModules m);
functor = (defaultFunctor "nullable") // {
type = nullable;
wrapped = elemType;
};
nestedTypes = { inherit elemType; };
};
}; };
supportedSystem = { lib, stdenv, ... }: supportedSystem = { lib, stdenv, ... }: