about summary refs log tree commit diff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/customisation.nix31
-rw-r--r--lib/default.nix4
-rw-r--r--lib/meta.nix25
-rw-r--r--lib/modules.nix6
-rw-r--r--lib/strings.nix4
-rw-r--r--lib/systems/parse.nix2
-rw-r--r--lib/tests/misc.nix21
-rwxr-xr-xlib/tests/modules.sh6
8 files changed, 75 insertions, 24 deletions
diff --git a/lib/customisation.nix b/lib/customisation.nix
index e13320076025c..0d023aa361cfc 100644
--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -278,9 +278,24 @@ rec {
         };
     in self;
 
-  /* Like the above, but aims to support cross compilation. It's still ugly, but
+  /* backward compatibility with old uncurried form; deprecated */
+  makeScopeWithSplicing =
+    splicePackages: newScope: otherSplices: keep: extra: f:
+    makeScopeWithSplicing'
+    { inherit splicePackages newScope; }
+    { inherit otherSplices keep extra f; };
+
+  /* Like makeScope, but aims to support cross compilation. It's still ugly, but
      hopefully it helps a little bit. */
-  makeScopeWithSplicing = splicePackages: newScope: otherSplices: keep: extra: f:
+  makeScopeWithSplicing' =
+    { splicePackages
+    , newScope
+    }:
+    { otherSplices
+    , keep ? (_self: {})
+    , extra ? (_spliced0: {})
+    , f
+    }:
     let
       spliced0 = splicePackages {
         pkgsBuildBuild = otherSplices.selfBuildBuild;
@@ -296,13 +311,11 @@ rec {
         callPackage = newScope spliced; # == self.newScope {};
         # N.B. the other stages of the package set spliced in are *not*
         # overridden.
-        overrideScope = g: makeScopeWithSplicing
-          splicePackages
-          newScope
-          otherSplices
-          keep
-          extra
-          (lib.fixedPoints.extends g f);
+        overrideScope = g: (makeScopeWithSplicing'
+          { inherit splicePackages newScope; }
+          { inherit otherSplices keep extra;
+            f = lib.fixedPoints.extends g f;
+          });
         packages = f;
       };
     in self;
diff --git a/lib/default.nix b/lib/default.nix
index 56af195d7c95b..509636452b2b5 100644
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -113,11 +113,11 @@ let
       noDepEntry fullDepEntry packEntry stringAfter;
     inherit (self.customisation) overrideDerivation makeOverridable
       callPackageWith callPackagesWith extendDerivation hydraJob
-      makeScope makeScopeWithSplicing;
+      makeScope makeScopeWithSplicing makeScopeWithSplicing';
     inherit (self.derivations) lazyDerivation;
     inherit (self.meta) addMetaAttrs dontDistribute setName updateName
       appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
-      hiPrioSet getLicenseFromSpdxId getExe;
+      hiPrioSet getLicenseFromSpdxId getExe getExe';
     inherit (self.filesystem) pathType pathIsDirectory pathIsRegularFile;
     inherit (self.sources) cleanSourceFilter
       cleanSource sourceByRegex sourceFilesBySuffices
diff --git a/lib/meta.nix b/lib/meta.nix
index 21404b3a2bfaa..44730a71551eb 100644
--- a/lib/meta.nix
+++ b/lib/meta.nix
@@ -143,9 +143,24 @@ rec {
        => "/nix/store/am9ml4f4ywvivxnkiaqwr0hyxka1xjsf-mustache-go-1.3.0/bin/mustache"
   */
   getExe = x:
-    "${lib.getBin x}/bin/${x.meta.mainProgram or (
-      # This could be turned into an error when 23.05 is at end of life
-      lib.warn "getExe: Package ${lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name} does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, specify the full path to the program, such as \"\${lib.getBin foo}/bin/bar\"."
-      lib.getName x
-    )}";
+    let
+      y = x.meta.mainProgram or (
+        # This could be turned into an error when 23.05 is at end of life
+        lib.warn "getExe: Package ${lib.strings.escapeNixIdentifier x.meta.name or x.pname or x.name} does not have the meta.mainProgram attribute. We'll assume that the main program has the same name for now, but this behavior is deprecated, because it leads to surprising errors when the assumption does not hold. If the package has a main program, please set `meta.mainProgram` in its definition to make this warning go away. Otherwise, if the package does not have a main program, or if you don't control its definition, use getExe' to specify the name to the program, such as lib.getExe' foo \"bar\"."
+          lib.getName
+          x
+      );
+    in
+    getExe' x y;
+
+  /* Get the path of a program of a derivation.
+
+     Type: getExe' :: derivation -> string -> string
+     Example:
+       getExe' pkgs.hello "hello"
+       => "/nix/store/g124820p9hlv4lj8qplzxw1c44dxaw1k-hello-2.12/bin/hello"
+       getExe' pkgs.imagemagick "convert"
+       => "/nix/store/5rs48jamq7k6sal98ymj9l4k2bnwq515-imagemagick-7.1.1-15/bin/convert"
+  */
+  getExe' = x: y: "${lib.getBin x}/bin/${y}";
 }
diff --git a/lib/modules.nix b/lib/modules.nix
index 9371ba4b27a4e..5c2fb48868c1f 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -633,7 +633,7 @@ let
           optionDecls = filter
             (m: m.options?_type
                 && (m.options._type == "option"
-                    || throwDeclarationTypeError loc m.options._type
+                    || throwDeclarationTypeError loc m.options._type m._file
                 )
             )
             decls;
@@ -698,14 +698,14 @@ let
           ) unmatchedDefnsByName);
     };
 
-  throwDeclarationTypeError = loc: actualTag:
+  throwDeclarationTypeError = loc: actualTag: file:
     let
       name = lib.strings.escapeNixIdentifier (lib.lists.last loc);
       path = showOption loc;
       depth = length loc;
 
       paragraphs = [
-        "Expected an option declaration at option path `${path}` but got an attribute set with type ${actualTag}"
+        "In module ${file}: expected an option declaration at option path `${path}` but got an attribute set with type ${actualTag}"
       ] ++ optional (actualTag == "option-type") ''
           When declaring an option, you must wrap the type in a `mkOption` call. It should look somewhat like:
               ${comment}
diff --git a/lib/strings.nix b/lib/strings.nix
index 1eb6cf9c1afbe..df891c8998872 100644
--- a/lib/strings.nix
+++ b/lib/strings.nix
@@ -629,10 +629,10 @@ rec {
             This behavior is deprecated and will throw an error in the future.''
     (let
       preLen = stringLength prefix;
-      sLen = stringLength str;
     in
       if substring 0 preLen str == prefix then
-        substring preLen (sLen - preLen) str
+        # -1 will take the string until the end
+        substring preLen (-1) str
       else
         str);
 
diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix
index 6eb4f27cc5194..34bfd94b3ce50 100644
--- a/lib/systems/parse.nix
+++ b/lib/systems/parse.nix
@@ -221,6 +221,8 @@ rec {
   vendors = setTypes types.openVendor {
     apple = {};
     pc = {};
+    knuth = {};
+
     # Actually matters, unlocking some MinGW-w64-specific options in GCC. See
     # bottom of https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/
     w64 = {};
diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix
index dcfa4c540f0cb..6d55ae684771e 100644
--- a/lib/tests/misc.nix
+++ b/lib/tests/misc.nix
@@ -349,6 +349,27 @@ runTests {
     expected = true;
   };
 
+  testRemovePrefixExample1 = {
+    expr = removePrefix "foo." "foo.bar.baz";
+    expected = "bar.baz";
+  };
+  testRemovePrefixExample2 = {
+    expr = removePrefix "xxx" "foo.bar.baz";
+    expected = "foo.bar.baz";
+  };
+  testRemovePrefixEmptyPrefix = {
+    expr = removePrefix "" "foo";
+    expected = "foo";
+  };
+  testRemovePrefixEmptyString = {
+    expr = removePrefix "foo" "";
+    expected = "";
+  };
+  testRemovePrefixEmptyBoth = {
+    expr = removePrefix "" "";
+    expected = "";
+  };
+
   testNormalizePath = {
     expr = strings.normalizePath "//a/b//c////d/";
     expected = "/a/b/c/d/";
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 5f2e3f2a31144..2c5e4cdbcec10 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -394,9 +394,9 @@ checkConfigError \
   ./declare-set.nix ./declare-enable-nested.nix
 
 # Options: accidental use of an option-type instead of option (or other tagged type; unlikely)
-checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type option-type' config.result ./options-type-error-typical.nix
-checkConfigError 'Expected an option declaration at option path .result.here. but got an attribute set with type option-type' config.result.here ./options-type-error-typical-nested.nix
-checkConfigError 'Expected an option declaration at option path .result. but got an attribute set with type configuration' config.result ./options-type-error-configuration.nix
+checkConfigError 'In module .*/options-type-error-typical.nix: expected an option declaration at option path .result. but got an attribute set with type option-type' config.result ./options-type-error-typical.nix
+checkConfigError 'In module .*/options-type-error-typical-nested.nix: expected an option declaration at option path .result.here. but got an attribute set with type option-type' config.result.here ./options-type-error-typical-nested.nix
+checkConfigError 'In module .*/options-type-error-configuration.nix: expected an option declaration at option path .result. but got an attribute set with type configuration' config.result ./options-type-error-configuration.nix
 
 # Check that that merging of option collisions doesn't depend on type being set
 checkConfigError 'The option .group..*would be a parent of the following options, but its type .<no description>. does not support nested options.\n\s*- option.s. with prefix .group.enable..*' config.group.enable ./merge-typeless-option.nix