summary refs log tree commit diff
path: root/lib/sources.nix
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2020-10-20 13:47:24 +0200
committerRobert Hensing <robert@roberthensing.nl>2020-10-22 13:46:47 +0200
commitafa6c51f27fb86fda71f91a51b093a5fc3de797d (patch)
tree99dc279dd61c53c85643f66a1c0c83e7004a9c3b /lib/sources.nix
parent5aa2a98dfa0b54fef1b5cc7059ac8c4b1248a739 (diff)
downloadnixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar.gz
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar.bz2
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar.lz
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar.xz
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.tar.zst
nixpkgs-afa6c51f27fb86fda71f91a51b093a5fc3de797d.zip
lib: Use Nix's static scope checking, fix error message, optimize
Nix can perform static scope checking, but whenever code is inside
a `with` expression, the analysis breaks down, because it can't
know statically what's in the attribute set whose attributes were
brought into scope. In those cases, Nix has to assume that
everything works out.

Except it doesnt. Removing `with` from lib/ revealed an undefined
variable in an error message.

If that doesn't convince you that we're better off without `with`,
I can tell you that this PR results in a 3% evaluation performance
improvement because Nix can look up local variables by index.
This adds up with applications like the module system.

Furthermore, removing `with` makes the binding site of each
variable obvious, which helps with comprehension.
Diffstat (limited to 'lib/sources.nix')
-rw-r--r--lib/sources.nix40
1 files changed, 28 insertions, 12 deletions
diff --git a/lib/sources.nix b/lib/sources.nix
index 776fcc32052..c7a3a959152 100644
--- a/lib/sources.nix
+++ b/lib/sources.nix
@@ -1,16 +1,33 @@
 # Functions for copying sources to the Nix store.
 { lib }:
 
+let
+  inherit (builtins)
+    hasContext
+    match
+    readDir
+    readFile
+    storeDir
+    tryEval
+    ;
+  inherit (lib)
+    filter
+    getAttr
+    isString
+    pathExists
+    split
+    ;
+in
 rec {
 
   # Returns the type of a path: regular (for file), symlink, or directory
-  pathType = p: with builtins; getAttr (baseNameOf p) (readDir (dirOf p));
+  pathType = p: getAttr (baseNameOf p) (readDir (dirOf p));
 
   # Returns true if the path exists and is a directory, false otherwise
-  pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false;
+  pathIsDirectory = p: if pathExists p then (pathType p) == "directory" else false;
 
   # Returns true if the path exists and is a regular file, false otherwise
-  pathIsRegularFile = p: if builtins.pathExists p then (pathType p) == "regular" else false;
+  pathIsRegularFile = p: if pathExists p then (pathType p) == "regular" else false;
 
   # Bring in a path as a source, filtering out all Subversion and CVS
   # directories, as well as backup files (*~).
@@ -19,8 +36,8 @@ rec {
     (baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) ||
     # Filter out editor backup / swap files.
     lib.hasSuffix "~" baseName ||
-    builtins.match "^\\.sw[a-z]$" baseName != null ||
-    builtins.match "^\\..*\\.sw[a-z]$" baseName != null ||
+    match "^\\.sw[a-z]$" baseName != null ||
+    match "^\\..*\\.sw[a-z]$" baseName != null ||
 
     # Filter out generates files.
     lib.hasSuffix ".o" baseName ||
@@ -89,7 +106,7 @@ rec {
     in lib.cleanSourceWith {
       filter = (path: type:
         let relPath = lib.removePrefix (toString origSrc + "/") (toString path);
-        in lib.any (re: builtins.match re relPath != null) regexes);
+        in lib.any (re: match re relPath != null) regexes);
       inherit src;
     };
 
@@ -102,13 +119,12 @@ rec {
       in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts;
     in cleanSourceWith { inherit filter; src = path; };
 
-  pathIsGitRepo = path: (builtins.tryEval (commitIdFromGitRepo path)).success;
+  pathIsGitRepo = path: (tryEval (commitIdFromGitRepo path)).success;
 
   # Get the commit id of a git repo
   # Example: commitIdFromGitRepo <nixpkgs/.git>
   commitIdFromGitRepo =
     let readCommitFromFile = file: path:
-      with builtins;
         let fileName       = toString path + "/" + file;
             packedRefsName = toString path + "/packed-refs";
             absolutePath   = base: path:
@@ -145,11 +161,11 @@ rec {
            # packed-refs file, so we have to grep through it:
            then
              let fileContent = readFile packedRefsName;
-                 matchRef = builtins.match "([a-z0-9]+) ${file}";
-                 isRef = s: builtins.isString s && (matchRef s) != null;
+                 matchRef = match "([a-z0-9]+) ${file}";
+                 isRef = s: isString s && (matchRef s) != null;
                  # there is a bug in libstdc++ leading to stackoverflow for long strings:
                  # https://github.com/NixOS/nix/issues/2147#issuecomment-659868795
-                 refs = builtins.filter isRef (builtins.split "\n" fileContent);
+                 refs = filter isRef (split "\n" fileContent);
              in if refs == []
                 then throw ("Could not find " + file + " in " + packedRefsName)
                 else lib.head (matchRef (lib.head refs))
@@ -157,7 +173,7 @@ rec {
            else throw ("Not a .git directory: " + path);
     in readCommitFromFile "HEAD";
 
-  pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir);
+  pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir);
 
   canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src));
 }