about summary refs log tree commit diff
path: root/lib/trivial.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/trivial.nix')
-rw-r--r--lib/trivial.nix110
1 files changed, 69 insertions, 41 deletions
diff --git a/lib/trivial.nix b/lib/trivial.nix
index 546aed746d1c9..f0afbf609fcab 100644
--- a/lib/trivial.nix
+++ b/lib/trivial.nix
@@ -12,6 +12,9 @@ let
     version
     versionSuffix
     warn;
+  inherit (lib)
+    isString
+    ;
 in {
 
   ## Simple (higher order) functions
@@ -718,98 +721,97 @@ in {
   importTOML = path:
     builtins.fromTOML (builtins.readFile path);
 
-  ## Warnings
-
-  # See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
-  # to expand to Nix builtins that carry metadata so that Nix can filter out
-  # the INFO messages without parsing the message string.
-  #
-  # Usage:
-  # {
-  #   foo = lib.warn "foo is deprecated" oldFoo;
-  #   bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar;
-  # }
-  #
-  # TODO: figure out a clever way to integrate location information from
-  # something like __unsafeGetAttrPos.
-
   /**
-    Print a warning before returning the second argument. This function behaves
-    like `builtins.trace`, but requires a string message and formats it as a
-    warning, including the `warning: ` prefix.
 
-    To get a call stack trace and abort evaluation, set the environment variable
-    `NIX_ABORT_ON_WARN=true` and set the Nix options `--option pure-eval false --show-trace`
+    `warn` *`message`* *`value`*
+
+    Print a warning before returning the second argument.
+
+    See [`builtins.warn`](https://nix.dev/manual/nix/latest/language/builtins.html#builtins-warn) (Nix >= 2.23).
+    On older versions, the Nix 2.23 behavior is emulated with [`builtins.trace`](https://nix.dev/manual/nix/latest/language/builtins.html#builtins-warn), including the [`NIX_ABORT_ON_WARN`](https://nix.dev/manual/nix/latest/command-ref/conf-file#conf-abort-on-warn) behavior, but not the `nix.conf` setting or command line option.
 
     # Inputs
 
-    `msg`
+    *`message`* (String)
 
-    : Warning message to print.
+    : Warning message to print before evaluating *`value`*.
 
-    `val`
+    *`value`* (any value)
 
     : Value to return as-is.
 
     # Type
 
     ```
-    string -> a -> a
+    String -> a -> a
     ```
   */
   warn =
-    if lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"]
-    then msg: builtins.trace "warning: ${msg}" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
-    else msg: builtins.trace "warning: ${msg}";
+    # Since Nix 2.23, https://github.com/NixOS/nix/pull/10592
+    builtins.warn or (
+      let mustAbort = lib.elem (builtins.getEnv "NIX_ABORT_ON_WARN") ["1" "true" "yes"];
+      in
+        # Do not eta reduce v, so that we have the same strictness as `builtins.warn`.
+        msg: v:
+          # `builtins.warn` requires a string message, so we enforce that in our implementation, so that callers aren't accidentally incompatible with newer Nix versions.
+          assert isString msg;
+          if mustAbort
+          then builtins.trace "evaluation warning: ${msg}" (abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors.")
+          else builtins.trace "evaluation warning: ${msg}" v
+    );
 
   /**
-    Like warn, but only warn when the first argument is `true`.
 
+    `warnIf` *`condition`* *`message`* *`value`*
+
+    Like `warn`, but only warn when the first argument is `true`.
 
     # Inputs
 
-    `cond`
+    *`condition`* (Boolean)
 
-    : 1\. Function argument
+    : `true` to trigger the warning before continuing with *`value`*.
 
-    `msg`
+    *`message`* (String)
 
-    : 2\. Function argument
+    : Warning message to print before evaluating
 
-    `val`
+    *`value`* (any value)
 
     : Value to return as-is.
 
     # Type
 
     ```
-    bool -> string -> a -> a
+    Bool -> String -> a -> a
     ```
   */
   warnIf = cond: msg: if cond then warn msg else x: x;
 
   /**
-    Like warnIf, but negated (warn if the first argument is `false`).
 
+    `warnIfNot` *`condition`* *`message`* *`value`*
+
+    Like `warnIf`, but negated: warn if the first argument is `false`.
 
     # Inputs
 
-    `cond`
+    *`condition`*
 
-    : 1\. Function argument
+    : `false` to trigger the warning before continuing with `val`.
 
-    `msg`
+    *`message`*
 
-    : 2\. Function argument
+    : Warning message to print before evaluating *`value`*.
 
-    `val`
+    *`value`*
 
     : Value to return as-is.
 
     # Type
 
     ```
-    bool -> string -> a -> a
+    Boolean -> String -> a -> a
     ```
   */
   warnIfNot = cond: msg: if cond then x: x else warn msg;
@@ -1075,6 +1077,32 @@ in {
     else k: v;
 
   /**
+    Convert a hexadecimal string to it's integer representation.
+
+    # Type
+
+    ```
+    fromHexString :: String -> [ String ]
+    ```
+
+    # Examples
+
+    ```nix
+    fromHexString "FF"
+    => 255
+
+    fromHexString (builtins.hashString "sha256" "test")
+    => 9223372036854775807
+    ```
+  */
+  fromHexString = value:
+  let
+    noPrefix = lib.strings.removePrefix "0x" (lib.strings.toLower value);
+  in let
+    parsed = builtins.fromTOML "v=0x${noPrefix}";
+  in parsed.v;
+
+  /**
     Convert the given positive integer to a string of its hexadecimal
     representation. For example: