Add setFunctionArgs lib function.
Among other things, this will allow *2nix tools to output plain data while still being composable with the traditional callPackage/.override interfaces.
This commit is contained in:
parent
0d7a0d7572
commit
943592f698
18 changed files with 60 additions and 33 deletions
|
@ -1,7 +1,7 @@
|
|||
{ lib }:
|
||||
let
|
||||
|
||||
inherit (builtins) attrNames isFunction;
|
||||
inherit (builtins) attrNames;
|
||||
|
||||
in
|
||||
|
||||
|
@ -72,7 +72,7 @@ rec {
|
|||
makeOverridable = f: origArgs:
|
||||
let
|
||||
ff = f origArgs;
|
||||
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
|
||||
overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs);
|
||||
in
|
||||
if builtins.isAttrs ff then (ff // {
|
||||
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||
|
@ -81,7 +81,7 @@ rec {
|
|||
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
|
||||
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
|
||||
})
|
||||
else if builtins.isFunction ff then {
|
||||
else if lib.isFunction ff then {
|
||||
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||
__functor = self: ff;
|
||||
overrideDerivation = throw "overrideDerivation not yet supported for functors";
|
||||
|
@ -112,8 +112,8 @@ rec {
|
|||
*/
|
||||
callPackageWith = autoArgs: fn: args:
|
||||
let
|
||||
f = if builtins.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
||||
f = if lib.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||
in makeOverridable f (auto // args);
|
||||
|
||||
|
||||
|
@ -122,8 +122,8 @@ rec {
|
|||
individual attributes. */
|
||||
callPackagesWith = autoArgs: fn: args:
|
||||
let
|
||||
f = if builtins.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
||||
f = if lib.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||
origArgs = auto // args;
|
||||
pkgs = f origArgs;
|
||||
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
let
|
||||
|
||||
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
|
||||
inherit (builtins) trace attrNamesToStr isAttrs isList isInt
|
||||
isString isBool head substring attrNames;
|
||||
|
||||
inherit (lib) all id mapAttrsFlatten elem;
|
||||
inherit (lib) all id mapAttrsFlatten elem isFunction;
|
||||
|
||||
in
|
||||
|
||||
|
|
|
@ -51,12 +51,12 @@ let
|
|||
|
||||
inherit (builtins) add addErrorContext attrNames
|
||||
concatLists deepSeq elem elemAt filter genericClosure genList
|
||||
getAttr hasAttr head isAttrs isBool isFunction isInt isList
|
||||
getAttr hasAttr head isAttrs isBool isInt isList
|
||||
isString length lessThan listToAttrs pathExists readFile
|
||||
replaceStrings seq stringLength sub substring tail;
|
||||
inherit (trivial) id const concat or and boolToString mergeAttrs
|
||||
flip mapNullable inNixShell min max importJSON warn info
|
||||
nixpkgsVersion mod;
|
||||
nixpkgsVersion mod functionArgs setFunctionArgs isFunction;
|
||||
|
||||
inherit (fixedPoints) fix fix' extends composeExtensions
|
||||
makeExtensible makeExtensibleWithCustomName;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ lib }:
|
||||
let
|
||||
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
|
||||
inherit (builtins) head tail isList isAttrs isInt attrNames;
|
||||
|
||||
in
|
||||
|
||||
|
@ -53,7 +53,7 @@ rec {
|
|||
f: # the function applied to the arguments
|
||||
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
||||
let
|
||||
takeFixed = if isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
|
||||
takeFixed = if lib.isFunction initial then initial else (fixed : initial); # transform initial to an expression always taking the fixed argument
|
||||
tidy = args:
|
||||
let # apply all functions given in "applyPreTidy" in sequence
|
||||
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
||||
|
@ -63,7 +63,7 @@ rec {
|
|||
let args = takeFixed fixed;
|
||||
mergeFun = args.${n};
|
||||
in if isAttrs x then (mergeFun args x)
|
||||
else assert isFunction x;
|
||||
else assert lib.isFunction x;
|
||||
mergeFun args (x ( args // { inherit fixed; }));
|
||||
in overridableDelayableArgs f newArgs;
|
||||
in
|
||||
|
@ -374,7 +374,7 @@ rec {
|
|||
if isAttrs x then
|
||||
if x ? outPath then "derivation"
|
||||
else "attrs"
|
||||
else if isFunction x then "function"
|
||||
else if lib.isFunction x then "function"
|
||||
else if isList x then "list"
|
||||
else if x == true then "bool"
|
||||
else if x == false then "bool"
|
||||
|
|
|
@ -14,6 +14,8 @@ let
|
|||
libAttr = lib.attrsets;
|
||||
|
||||
flipMapAttrs = flip libAttr.mapAttrs;
|
||||
|
||||
inherit (lib) isFunction;
|
||||
in
|
||||
|
||||
rec {
|
||||
|
@ -110,7 +112,7 @@ rec {
|
|||
else if isString v then "\"" + v + "\""
|
||||
else if null == v then "null"
|
||||
else if isFunction v then
|
||||
let fna = functionArgs v;
|
||||
let fna = lib.functionArgs v;
|
||||
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
||||
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
||||
fna);
|
||||
|
|
|
@ -155,7 +155,7 @@ rec {
|
|||
# a module will resolve strictly the attributes used as argument but
|
||||
# not their values. The values are forwarding the result of the
|
||||
# evaluation of the option.
|
||||
requiredArgs = builtins.attrNames (builtins.functionArgs f);
|
||||
requiredArgs = builtins.attrNames (lib.functionArgs f);
|
||||
context = name: ''while evaluating the module argument `${name}' in "${key}":'';
|
||||
extraArgs = builtins.listToAttrs (map (name: {
|
||||
inherit name;
|
||||
|
|
|
@ -52,7 +52,7 @@ rec {
|
|||
|
||||
# Pull in some builtins not included elsewhere.
|
||||
inherit (builtins)
|
||||
pathExists readFile isBool isFunction
|
||||
pathExists readFile isBool
|
||||
isInt add sub lessThan
|
||||
seq deepSeq genericClosure;
|
||||
|
||||
|
@ -99,4 +99,29 @@ rec {
|
|||
*/
|
||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||
info = msg: builtins.trace "INFO: ${msg}";
|
||||
|
||||
# | Add metadata about expected function arguments to a function.
|
||||
# The metadata should match the format given by
|
||||
# builtins.functionArgs, i.e. a set from expected argument to a bool
|
||||
# representing whether that argument has a default or not.
|
||||
# setFunctionArgs : (a → b) → Map String Bool → (a → b)
|
||||
#
|
||||
# This function is necessary because you can't dynamically create a
|
||||
# function of the { a, b ? foo, ... }: format, but some facilities
|
||||
# like callPackage expect to be able to query expected arguments.
|
||||
setFunctionArgs = f: args:
|
||||
{ # TODO: Should we add call-time "type" checking like built in?
|
||||
__functor = self: f;
|
||||
__functionArgs = args;
|
||||
};
|
||||
|
||||
# | Extract the expected function arguments from a function.
|
||||
# This works both with nix-native { a, b ? foo, ... }: style
|
||||
# functions and functions with args set with 'setFunctionArgs'. It
|
||||
# has the same return type and semantics as builtins.functionArgs.
|
||||
# setFunctionArgs : (a → b) → Map String Bool.
|
||||
functionArgs = f: f.__functionArgs or (builtins.functionArgs f);
|
||||
|
||||
isFunction = f: builtins.isFunction f ||
|
||||
(f ? __functor && isFunction (f.__functor f));
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ let
|
|||
substFunction = x:
|
||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||
else if builtins.isList x then map substFunction x
|
||||
else if builtins.isFunction x then "<function>"
|
||||
else if lib.isFunction x then "<function>"
|
||||
else x;
|
||||
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
|
|
|
@ -85,7 +85,7 @@ rec {
|
|||
|
||||
testScript' =
|
||||
# Call the test script with the computed nodes.
|
||||
if builtins.isFunction testScript
|
||||
if lib.isFunction testScript
|
||||
then testScript { inherit nodes; }
|
||||
else testScript;
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ with lib;
|
|||
|
||||
let
|
||||
isConfig = x:
|
||||
builtins.isAttrs x || builtins.isFunction x;
|
||||
builtins.isAttrs x || lib.isFunction x;
|
||||
|
||||
optCall = f: x:
|
||||
if builtins.isFunction f
|
||||
if lib.isFunction f
|
||||
then f x
|
||||
else f;
|
||||
|
||||
|
@ -38,7 +38,7 @@ let
|
|||
overlayType = mkOptionType {
|
||||
name = "nixpkgs-overlay";
|
||||
description = "nixpkgs overlay";
|
||||
check = builtins.isFunction;
|
||||
check = lib.isFunction;
|
||||
merge = lib.mergeOneOption;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ let
|
|||
# you should use files).
|
||||
moduleFiles =
|
||||
# FIXME: use typeOf (Nix 1.6.1).
|
||||
filter (x: !isAttrs x && !builtins.isFunction x) modules;
|
||||
filter (x: !isAttrs x && !lib.isFunction x) modules;
|
||||
|
||||
# Partition module files because between NixOS and non-NixOS files. NixOS
|
||||
# files may change if the repository is updated.
|
||||
|
|
|
@ -2,4 +2,4 @@ f: { system ? builtins.currentSystem, ... } @ args:
|
|||
|
||||
with import ../lib/testing.nix { inherit system; };
|
||||
|
||||
makeTest (if builtins.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f)
|
||||
makeTest (if lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f)
|
||||
|
|
|
@ -40,7 +40,7 @@ packagesFun: # packages explicitly requested by the user
|
|||
|
||||
let
|
||||
explicitRequires =
|
||||
if builtins.isFunction packagesFun
|
||||
if lib.isFunction packagesFun
|
||||
then packagesFun self
|
||||
else packagesFun;
|
||||
in
|
||||
|
|
|
@ -6,8 +6,8 @@ rec {
|
|||
*/
|
||||
callPackageWith = autoArgs: fn: args:
|
||||
let
|
||||
f = if builtins.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
||||
f = if pkgs.lib.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (stdenv.lib.functionArgs f) autoArgs;
|
||||
in f (auto // args);
|
||||
|
||||
callPackage = callPackageWith pkgs;
|
||||
|
|
|
@ -81,8 +81,8 @@ let
|
|||
# lost on `.override`) but determine the auto-args based on `drv` (the problem here
|
||||
# is that nix has no way to "passthrough" args while preserving the reflection
|
||||
# info that callPackage uses to determine the arguments).
|
||||
drv = if builtins.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (builtins.functionArgs drv) scope;
|
||||
drv = if stdenv.lib.isFunction fn then fn else import fn;
|
||||
auto = builtins.intersectAttrs (stdenv.lib.functionArgs drv) scope;
|
||||
|
||||
# this wraps the `drv` function to add a `overrideScope` function to the result.
|
||||
drvScope = allArgs: drv allArgs // {
|
||||
|
|
|
@ -186,7 +186,7 @@ let
|
|||
# There should be an IOVideo here, but they haven't released it :(
|
||||
};
|
||||
|
||||
IOKitSrcs = stdenv.lib.mapAttrs (name: value: if builtins.isFunction value then value name else value) IOKitSpecs;
|
||||
IOKitSrcs = stdenv.lib.mapAttrs (name: value: if stdenv.lib.isFunction value then value name else value) IOKitSpecs;
|
||||
|
||||
adv_cmds = applePackage "adv_cmds" "osx-10.5.8" "102ssayxbg9wb35mdmhswbnw0bg7js3pfd8fcbic83c5q3bqa6c6" {};
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ in let
|
|||
# { /* the config */ } and
|
||||
# { pkgs, ... } : { /* the config */ }
|
||||
config =
|
||||
if builtins.isFunction configExpr
|
||||
if lib.isFunction configExpr
|
||||
then configExpr { inherit pkgs; }
|
||||
else configExpr;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ let
|
|||
makeOverridablePythonPackage = f: origArgs:
|
||||
let
|
||||
ff = f origArgs;
|
||||
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
|
||||
overrideWith = newArgs: origArgs // (if pkgs.lib.isFunction newArgs then newArgs origArgs else newArgs);
|
||||
in
|
||||
if builtins.isAttrs ff then (ff // {
|
||||
overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
|
||||
|
|
Loading…
Reference in a new issue