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
@ -1,7 +1,7 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (builtins) attrNames isFunction;
|
inherit (builtins) attrNames;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ rec {
|
|||||||
makeOverridable = f: origArgs:
|
makeOverridable = f: origArgs:
|
||||||
let
|
let
|
||||||
ff = f origArgs;
|
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
|
in
|
||||||
if builtins.isAttrs ff then (ff // {
|
if builtins.isAttrs ff then (ff // {
|
||||||
override = newArgs: makeOverridable f (overrideWith newArgs);
|
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||||
@ -81,7 +81,7 @@ rec {
|
|||||||
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
|
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
|
||||||
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
|
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);
|
override = newArgs: makeOverridable f (overrideWith newArgs);
|
||||||
__functor = self: ff;
|
__functor = self: ff;
|
||||||
overrideDerivation = throw "overrideDerivation not yet supported for functors";
|
overrideDerivation = throw "overrideDerivation not yet supported for functors";
|
||||||
@ -112,8 +112,8 @@ rec {
|
|||||||
*/
|
*/
|
||||||
callPackageWith = autoArgs: fn: args:
|
callPackageWith = autoArgs: fn: args:
|
||||||
let
|
let
|
||||||
f = if builtins.isFunction fn then fn else import fn;
|
f = if lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||||
in makeOverridable f (auto // args);
|
in makeOverridable f (auto // args);
|
||||||
|
|
||||||
|
|
||||||
@ -122,8 +122,8 @@ rec {
|
|||||||
individual attributes. */
|
individual attributes. */
|
||||||
callPackagesWith = autoArgs: fn: args:
|
callPackagesWith = autoArgs: fn: args:
|
||||||
let
|
let
|
||||||
f = if builtins.isFunction fn then fn else import fn;
|
f = if lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
|
||||||
origArgs = auto // args;
|
origArgs = auto // args;
|
||||||
pkgs = f origArgs;
|
pkgs = f origArgs;
|
||||||
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
mkAttrOverridable = name: pkg: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
inherit (builtins) trace attrNamesToStr isAttrs isFunction isList isInt
|
inherit (builtins) trace attrNamesToStr isAttrs isList isInt
|
||||||
isString isBool head substring attrNames;
|
isString isBool head substring attrNames;
|
||||||
|
|
||||||
inherit (lib) all id mapAttrsFlatten elem;
|
inherit (lib) all id mapAttrsFlatten elem isFunction;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
|
@ -51,12 +51,12 @@ let
|
|||||||
|
|
||||||
inherit (builtins) add addErrorContext attrNames
|
inherit (builtins) add addErrorContext attrNames
|
||||||
concatLists deepSeq elem elemAt filter genericClosure genList
|
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
|
isString length lessThan listToAttrs pathExists readFile
|
||||||
replaceStrings seq stringLength sub substring tail;
|
replaceStrings seq stringLength sub substring tail;
|
||||||
inherit (trivial) id const concat or and boolToString mergeAttrs
|
inherit (trivial) id const concat or and boolToString mergeAttrs
|
||||||
flip mapNullable inNixShell min max importJSON warn info
|
flip mapNullable inNixShell min max importJSON warn info
|
||||||
nixpkgsVersion mod;
|
nixpkgsVersion mod functionArgs setFunctionArgs isFunction;
|
||||||
|
|
||||||
inherit (fixedPoints) fix fix' extends composeExtensions
|
inherit (fixedPoints) fix fix' extends composeExtensions
|
||||||
makeExtensible makeExtensibleWithCustomName;
|
makeExtensible makeExtensibleWithCustomName;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{ lib }:
|
{ lib }:
|
||||||
let
|
let
|
||||||
inherit (builtins) isFunction head tail isList isAttrs isInt attrNames;
|
inherit (builtins) head tail isList isAttrs isInt attrNames;
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ rec {
|
|||||||
f: # the function applied to the arguments
|
f: # the function applied to the arguments
|
||||||
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
initial: # you pass attrs, the functions below are passing a function taking the fix argument
|
||||||
let
|
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:
|
tidy = args:
|
||||||
let # apply all functions given in "applyPreTidy" in sequence
|
let # apply all functions given in "applyPreTidy" in sequence
|
||||||
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
applyPreTidyFun = fold ( n: a: x: n ( a x ) ) lib.id (maybeAttr "applyPreTidy" [] args);
|
||||||
@ -63,7 +63,7 @@ rec {
|
|||||||
let args = takeFixed fixed;
|
let args = takeFixed fixed;
|
||||||
mergeFun = args.${n};
|
mergeFun = args.${n};
|
||||||
in if isAttrs x then (mergeFun args x)
|
in if isAttrs x then (mergeFun args x)
|
||||||
else assert isFunction x;
|
else assert lib.isFunction x;
|
||||||
mergeFun args (x ( args // { inherit fixed; }));
|
mergeFun args (x ( args // { inherit fixed; }));
|
||||||
in overridableDelayableArgs f newArgs;
|
in overridableDelayableArgs f newArgs;
|
||||||
in
|
in
|
||||||
@ -374,7 +374,7 @@ rec {
|
|||||||
if isAttrs x then
|
if isAttrs x then
|
||||||
if x ? outPath then "derivation"
|
if x ? outPath then "derivation"
|
||||||
else "attrs"
|
else "attrs"
|
||||||
else if isFunction x then "function"
|
else if lib.isFunction x then "function"
|
||||||
else if isList x then "list"
|
else if isList x then "list"
|
||||||
else if x == true then "bool"
|
else if x == true then "bool"
|
||||||
else if x == false then "bool"
|
else if x == false then "bool"
|
||||||
|
@ -14,6 +14,8 @@ let
|
|||||||
libAttr = lib.attrsets;
|
libAttr = lib.attrsets;
|
||||||
|
|
||||||
flipMapAttrs = flip libAttr.mapAttrs;
|
flipMapAttrs = flip libAttr.mapAttrs;
|
||||||
|
|
||||||
|
inherit (lib) isFunction;
|
||||||
in
|
in
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
@ -110,7 +112,7 @@ rec {
|
|||||||
else if isString v then "\"" + v + "\""
|
else if isString v then "\"" + v + "\""
|
||||||
else if null == v then "null"
|
else if null == v then "null"
|
||||||
else if isFunction v then
|
else if isFunction v then
|
||||||
let fna = functionArgs v;
|
let fna = lib.functionArgs v;
|
||||||
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
showFnas = concatStringsSep "," (libAttr.mapAttrsToList
|
||||||
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
(name: hasDefVal: if hasDefVal then "(${name})" else name)
|
||||||
fna);
|
fna);
|
||||||
|
@ -155,7 +155,7 @@ rec {
|
|||||||
# a module will resolve strictly the attributes used as argument but
|
# a module will resolve strictly the attributes used as argument but
|
||||||
# not their values. The values are forwarding the result of the
|
# not their values. The values are forwarding the result of the
|
||||||
# evaluation of the option.
|
# 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}":'';
|
context = name: ''while evaluating the module argument `${name}' in "${key}":'';
|
||||||
extraArgs = builtins.listToAttrs (map (name: {
|
extraArgs = builtins.listToAttrs (map (name: {
|
||||||
inherit name;
|
inherit name;
|
||||||
|
@ -52,7 +52,7 @@ rec {
|
|||||||
|
|
||||||
# Pull in some builtins not included elsewhere.
|
# Pull in some builtins not included elsewhere.
|
||||||
inherit (builtins)
|
inherit (builtins)
|
||||||
pathExists readFile isBool isFunction
|
pathExists readFile isBool
|
||||||
isInt add sub lessThan
|
isInt add sub lessThan
|
||||||
seq deepSeq genericClosure;
|
seq deepSeq genericClosure;
|
||||||
|
|
||||||
@ -99,4 +99,29 @@ rec {
|
|||||||
*/
|
*/
|
||||||
warn = msg: builtins.trace "WARNING: ${msg}";
|
warn = msg: builtins.trace "WARNING: ${msg}";
|
||||||
info = msg: builtins.trace "INFO: ${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:
|
substFunction = x:
|
||||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
||||||
else if builtins.isList x then map 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;
|
else x;
|
||||||
|
|
||||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||||
|
@ -85,7 +85,7 @@ rec {
|
|||||||
|
|
||||||
testScript' =
|
testScript' =
|
||||||
# Call the test script with the computed nodes.
|
# Call the test script with the computed nodes.
|
||||||
if builtins.isFunction testScript
|
if lib.isFunction testScript
|
||||||
then testScript { inherit nodes; }
|
then testScript { inherit nodes; }
|
||||||
else testScript;
|
else testScript;
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@ with lib;
|
|||||||
|
|
||||||
let
|
let
|
||||||
isConfig = x:
|
isConfig = x:
|
||||||
builtins.isAttrs x || builtins.isFunction x;
|
builtins.isAttrs x || lib.isFunction x;
|
||||||
|
|
||||||
optCall = f: x:
|
optCall = f: x:
|
||||||
if builtins.isFunction f
|
if lib.isFunction f
|
||||||
then f x
|
then f x
|
||||||
else f;
|
else f;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ let
|
|||||||
overlayType = mkOptionType {
|
overlayType = mkOptionType {
|
||||||
name = "nixpkgs-overlay";
|
name = "nixpkgs-overlay";
|
||||||
description = "nixpkgs overlay";
|
description = "nixpkgs overlay";
|
||||||
check = builtins.isFunction;
|
check = lib.isFunction;
|
||||||
merge = lib.mergeOneOption;
|
merge = lib.mergeOneOption;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ let
|
|||||||
# you should use files).
|
# you should use files).
|
||||||
moduleFiles =
|
moduleFiles =
|
||||||
# FIXME: use typeOf (Nix 1.6.1).
|
# 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
|
# Partition module files because between NixOS and non-NixOS files. NixOS
|
||||||
# files may change if the repository is updated.
|
# files may change if the repository is updated.
|
||||||
|
@ -2,4 +2,4 @@ f: { system ? builtins.currentSystem, ... } @ args:
|
|||||||
|
|
||||||
with import ../lib/testing.nix { inherit system; };
|
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
|
let
|
||||||
explicitRequires =
|
explicitRequires =
|
||||||
if builtins.isFunction packagesFun
|
if lib.isFunction packagesFun
|
||||||
then packagesFun self
|
then packagesFun self
|
||||||
else packagesFun;
|
else packagesFun;
|
||||||
in
|
in
|
||||||
|
@ -6,8 +6,8 @@ rec {
|
|||||||
*/
|
*/
|
||||||
callPackageWith = autoArgs: fn: args:
|
callPackageWith = autoArgs: fn: args:
|
||||||
let
|
let
|
||||||
f = if builtins.isFunction fn then fn else import fn;
|
f = if pkgs.lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs f) autoArgs;
|
auto = builtins.intersectAttrs (stdenv.lib.functionArgs f) autoArgs;
|
||||||
in f (auto // args);
|
in f (auto // args);
|
||||||
|
|
||||||
callPackage = callPackageWith pkgs;
|
callPackage = callPackageWith pkgs;
|
||||||
|
@ -81,8 +81,8 @@ let
|
|||||||
# lost on `.override`) but determine the auto-args based on `drv` (the problem here
|
# 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
|
# is that nix has no way to "passthrough" args while preserving the reflection
|
||||||
# info that callPackage uses to determine the arguments).
|
# info that callPackage uses to determine the arguments).
|
||||||
drv = if builtins.isFunction fn then fn else import fn;
|
drv = if stdenv.lib.isFunction fn then fn else import fn;
|
||||||
auto = builtins.intersectAttrs (builtins.functionArgs drv) scope;
|
auto = builtins.intersectAttrs (stdenv.lib.functionArgs drv) scope;
|
||||||
|
|
||||||
# this wraps the `drv` function to add a `overrideScope` function to the result.
|
# this wraps the `drv` function to add a `overrideScope` function to the result.
|
||||||
drvScope = allArgs: drv allArgs // {
|
drvScope = allArgs: drv allArgs // {
|
||||||
|
@ -186,7 +186,7 @@ let
|
|||||||
# There should be an IOVideo here, but they haven't released it :(
|
# 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" {};
|
adv_cmds = applePackage "adv_cmds" "osx-10.5.8" "102ssayxbg9wb35mdmhswbnw0bg7js3pfd8fcbic83c5q3bqa6c6" {};
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ in let
|
|||||||
# { /* the config */ } and
|
# { /* the config */ } and
|
||||||
# { pkgs, ... } : { /* the config */ }
|
# { pkgs, ... } : { /* the config */ }
|
||||||
config =
|
config =
|
||||||
if builtins.isFunction configExpr
|
if lib.isFunction configExpr
|
||||||
then configExpr { inherit pkgs; }
|
then configExpr { inherit pkgs; }
|
||||||
else configExpr;
|
else configExpr;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ let
|
|||||||
makeOverridablePythonPackage = f: origArgs:
|
makeOverridablePythonPackage = f: origArgs:
|
||||||
let
|
let
|
||||||
ff = f origArgs;
|
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
|
in
|
||||||
if builtins.isAttrs ff then (ff // {
|
if builtins.isAttrs ff then (ff // {
|
||||||
overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
|
overridePythonAttrs = newArgs: makeOverridablePythonPackage f (overrideWith newArgs);
|
||||||
|
Loading…
Reference in New Issue
Block a user