summary refs log tree commit diff
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2018-01-31 14:02:19 -0500
committerShea Levy <shea@shealevy.com>2018-01-31 14:02:19 -0500
commit943592f69850fd07dd2422da062b1c1ebc45974d (patch)
tree3376a06cd3ab25a1622c8f320573ab09b55a9470
parent0d7a0d7572d35526ddf34b6d011b7b88a8904b36 (diff)
downloadnixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar.gz
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar.bz2
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar.lz
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar.xz
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.tar.zst
nixpkgs-943592f69850fd07dd2422da062b1c1ebc45974d.zip
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.
-rw-r--r--lib/customisation.nix14
-rw-r--r--lib/debug.nix4
-rw-r--r--lib/default.nix4
-rw-r--r--lib/deprecated.nix8
-rw-r--r--lib/generators.nix4
-rw-r--r--lib/modules.nix2
-rw-r--r--lib/trivial.nix27
-rw-r--r--nixos/doc/manual/default.nix2
-rw-r--r--nixos/lib/testing.nix2
-rw-r--r--nixos/modules/misc/nixpkgs.nix6
-rw-r--r--nixos/modules/profiles/clone-config.nix2
-rw-r--r--nixos/tests/make-test.nix2
-rw-r--r--pkgs/build-support/emacs/wrapper.nix2
-rw-r--r--pkgs/development/beam-modules/lib.nix4
-rw-r--r--pkgs/development/haskell-modules/make-package-set.nix4
-rw-r--r--pkgs/os-specific/darwin/apple-source-releases/default.nix2
-rw-r--r--pkgs/top-level/default.nix2
-rw-r--r--pkgs/top-level/python-packages.nix2
18 files changed, 60 insertions, 33 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix
index 3988f4e9b69..823395f04d4 100644
--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -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;
diff --git a/lib/debug.nix b/lib/debug.nix
index 646ef220ad0..d163e60b695 100644
--- a/lib/debug.nix
+++ b/lib/debug.nix
@@ -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
 
diff --git a/lib/default.nix b/lib/default.nix
index 6d2a95e559c..97d7c10192a 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -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;
diff --git a/lib/deprecated.nix b/lib/deprecated.nix
index 2a0f5a55bf1..34cf336d1f4 100644
--- a/lib/deprecated.nix
+++ b/lib/deprecated.nix
@@ -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"
diff --git a/lib/generators.nix b/lib/generators.nix
index f207033c955..73017f2c679 100644
--- a/lib/generators.nix
+++ b/lib/generators.nix
@@ -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);
diff --git a/lib/modules.nix b/lib/modules.nix
index 8c3584bbbf4..654c4c588de 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -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;
diff --git a/lib/trivial.nix b/lib/trivial.nix
index c452c7b65bc..d8d51298143 100644
--- a/lib/trivial.nix
+++ b/lib/trivial.nix
@@ -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));
 }
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 9bc83be6610..8079a2feb29 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -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.
diff --git a/nixos/lib/testing.nix b/nixos/lib/testing.nix
index 532fff681d3..cf213d906f5 100644
--- a/nixos/lib/testing.nix
+++ b/nixos/lib/testing.nix
@@ -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;
 
diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix
index 1793c1447d6..b01f5431909 100644
--- a/nixos/modules/misc/nixpkgs.nix
+++ b/nixos/modules/misc/nixpkgs.nix
@@ -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;
   };
 
diff --git a/nixos/modules/profiles/clone-config.nix b/nixos/modules/profiles/clone-config.nix
index 77d86f8d740..5b4e68beb6a 100644
--- a/nixos/modules/profiles/clone-config.nix
+++ b/nixos/modules/profiles/clone-config.nix
@@ -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.
diff --git a/nixos/tests/make-test.nix b/nixos/tests/make-test.nix
index f3e26aa7e74..1b571a008e0 100644
--- a/nixos/tests/make-test.nix
+++ b/nixos/tests/make-test.nix
@@ -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)
diff --git a/pkgs/build-support/emacs/wrapper.nix b/pkgs/build-support/emacs/wrapper.nix
index 27633c912b2..4e780b104b0 100644
--- a/pkgs/build-support/emacs/wrapper.nix
+++ b/pkgs/build-support/emacs/wrapper.nix
@@ -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
diff --git a/pkgs/development/beam-modules/lib.nix b/pkgs/development/beam-modules/lib.nix
index 26d868a8e7c..d6b83cb1af0 100644
--- a/pkgs/development/beam-modules/lib.nix
+++ b/pkgs/development/beam-modules/lib.nix
@@ -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;
diff --git a/pkgs/development/haskell-modules/make-package-set.nix b/pkgs/development/haskell-modules/make-package-set.nix
index 223f0652887..0f866a96e71 100644
--- a/pkgs/development/haskell-modules/make-package-set.nix
+++ b/pkgs/development/haskell-modules/make-package-set.nix
@@ -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 // {
diff --git a/pkgs/os-specific/darwin/apple-source-releases/default.nix b/pkgs/os-specific/darwin/apple-source-releases/default.nix
index 478f9e7e303..cca729016c2 100644
--- a/pkgs/os-specific/darwin/apple-source-releases/default.nix
+++ b/pkgs/os-specific/darwin/apple-source-releases/default.nix
@@ -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" {};
 
diff --git a/pkgs/top-level/default.nix b/pkgs/top-level/default.nix
index 96d5e1fe283..9cf9eb4db65 100644
--- a/pkgs/top-level/default.nix
+++ b/pkgs/top-level/default.nix
@@ -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;
 
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 1820125b0a5..bc3ea1027e7 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -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);