about summary refs log tree commit diff
path: root/lib/fileset/internal.nix
diff options
context:
space:
mode:
Diffstat (limited to 'lib/fileset/internal.nix')
-rw-r--r--lib/fileset/internal.nix33
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix
index 35d556e78391c..9de5590d3effd 100644
--- a/lib/fileset/internal.nix
+++ b/lib/fileset/internal.nix
@@ -10,6 +10,7 @@ let
     split
     trace
     typeOf
+    fetchGit
     ;
 
   inherit (lib.attrsets)
@@ -55,6 +56,9 @@ let
     hasSuffix
     ;
 
+  inherit (lib.trivial)
+    inPureEvalMode
+    ;
 in
 # Rare case of justified usage of rec:
 # - This file is internal, so the return value doesn't matter, no need to make things overridable
@@ -852,4 +856,33 @@ rec {
     in
     _create localPath
       (recurse storePath);
+
+  # Create a file set from the files included in the result of a fetchGit call
+  # Type: String -> String -> Path -> Attrs -> FileSet
+  _fromFetchGit = function: argument: path: extraFetchGitAttrs:
+    let
+      # This imports the files unnecessarily, which currently can't be avoided
+      # because `builtins.fetchGit` is the only function exposing which files are tracked by Git.
+      # With the [lazy trees PR](https://github.com/NixOS/nix/pull/6530),
+      # the unnecessarily import could be avoided.
+      # However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
+      fetchResult = fetchGit ({
+        url = path;
+      } // extraFetchGitAttrs);
+    in
+    if inPureEvalMode then
+      throw "lib.fileset.${function}: This function is currently not supported in pure evaluation mode, since it currently relies on `builtins.fetchGit`. See https://github.com/NixOS/nix/issues/9292."
+    else if ! isPath path then
+      throw "lib.fileset.${function}: Expected the ${argument} to be a path, but it's a ${typeOf path} instead."
+    else if pathType path != "directory" then
+      throw "lib.fileset.${function}: Expected the ${argument} (${toString path}) to be a directory, but it's a file instead."
+    # We can identify local working directories by checking for .git,
+    # see https://git-scm.com/docs/gitrepository-layout#_description.
+    # Note that `builtins.fetchGit` _does_ work for bare repositories (where there's no `.git`),
+    # even though `git ls-files` wouldn't return any files in that case.
+    else if ! pathExists (path + "/.git") then
+      throw "lib.fileset.${function}: Expected the ${argument} (${toString path}) to point to a local working tree of a Git repository, but it's not."
+    else
+      _mirrorStorePath path fetchResult.outPath;
+
 }