Skip to content

Commit eec765f

Browse files
committed
lib.fileset: Refactor gitTracked and gitTrackedWith
Introduce an internal function for them to share more behavior. This makes future changes easier.
1 parent 09dc040 commit eec765f

2 files changed

Lines changed: 48 additions & 41 deletions

File tree

lib/fileset/default.nix

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ let
107107
_printFileset
108108
_intersection
109109
_difference
110-
_mirrorStorePath
110+
_fromFetchGit
111111
_fetchGitSubmodulesMinver
112112
_emptyWithoutBase
113113
;
@@ -148,7 +148,6 @@ let
148148
inherit (lib.trivial)
149149
isFunction
150150
pipe
151-
inPureEvalMode
152151
;
153152

154153
in {
@@ -754,18 +753,11 @@ in {
754753
This directory must contain a `.git` file or subdirectory.
755754
*/
756755
path:
757-
# See the gitTrackedWith implementation for more explanatory comments
758-
let
759-
fetchResult = builtins.fetchGit path;
760-
in
761-
if inPureEvalMode then
762-
throw "lib.fileset.gitTracked: 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."
763-
else if ! isPath path then
764-
throw "lib.fileset.gitTracked: Expected the argument to be a path, but it's a ${typeOf path} instead."
765-
else if ! pathExists (path + "/.git") then
766-
throw "lib.fileset.gitTracked: Expected the argument (${toString path}) to point to a local working tree of a Git repository, but it's not."
767-
else
768-
_mirrorStorePath path fetchResult.outPath;
756+
_fromFetchGit
757+
"gitTracked"
758+
"argument"
759+
path
760+
{};
769761

770762
/*
771763
Create a file set containing all [Git-tracked files](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository) in a repository.
@@ -807,35 +799,19 @@ in {
807799
This directory must contain a `.git` file or subdirectory.
808800
*/
809801
path:
810-
let
811-
# This imports the files unnecessarily, which currently can't be avoided
812-
# because `builtins.fetchGit` is the only function exposing which files are tracked by Git.
813-
# With the [lazy trees PR](https://github.com/NixOS/nix/pull/6530),
814-
# the unnecessarily import could be avoided.
815-
# However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
816-
fetchResult = builtins.fetchGit {
817-
url = path;
818-
819-
# This is the only `fetchGit` parameter that makes sense in this context.
820-
# We can't just pass `submodules = recurseSubmodules` here because
821-
# this would fail for Nix versions that don't support `submodules`.
822-
${if recurseSubmodules then "submodules" else null} = true;
823-
};
824-
in
825-
if inPureEvalMode then
826-
throw "lib.fileset.gitTrackedWith: 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."
827-
else if ! isBool recurseSubmodules then
802+
if ! isBool recurseSubmodules then
828803
throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead."
829804
else if recurseSubmodules && versionOlder nixVersion _fetchGitSubmodulesMinver then
830805
throw "lib.fileset.gitTrackedWith: Setting the attribute `recurseSubmodules` to `true` is only supported for Nix version ${_fetchGitSubmodulesMinver} and after, but Nix version ${nixVersion} is used."
831-
else if ! isPath path then
832-
throw "lib.fileset.gitTrackedWith: Expected the second argument to be a path, but it's a ${typeOf path} instead."
833-
# We can identify local working directories by checking for .git,
834-
# see https://git-scm.com/docs/gitrepository-layout#_description.
835-
# Note that `builtins.fetchGit` _does_ work for bare repositories (where there's no `.git`),
836-
# even though `git ls-files` wouldn't return any files in that case.
837-
else if ! pathExists (path + "/.git") then
838-
throw "lib.fileset.gitTrackedWith: Expected the second argument (${toString path}) to point to a local working tree of a Git repository, but it's not."
839806
else
840-
_mirrorStorePath path fetchResult.outPath;
807+
_fromFetchGit
808+
"gitTrackedWith"
809+
"second argument"
810+
path
811+
# This is the only `fetchGit` parameter that makes sense in this context.
812+
# We can't just pass `submodules = recurseSubmodules` here because
813+
# this would fail for Nix versions that don't support `submodules`.
814+
(lib.optionalAttrs recurseSubmodules {
815+
submodules = true;
816+
});
841817
}

lib/fileset/internal.nix

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ let
1010
split
1111
trace
1212
typeOf
13+
fetchGit
1314
;
1415

1516
inherit (lib.attrsets)
@@ -55,6 +56,9 @@ let
5556
hasSuffix
5657
;
5758

59+
inherit (lib.trivial)
60+
inPureEvalMode
61+
;
5862
in
5963
# Rare case of justified usage of rec:
6064
# - This file is internal, so the return value doesn't matter, no need to make things overridable
@@ -852,4 +856,31 @@ rec {
852856
in
853857
_create localPath
854858
(recurse storePath);
859+
860+
# Create a file set from the files included in the result of a fetchGit call
861+
# Type: String -> String -> Path -> Attrs -> FileSet
862+
_fromFetchGit = function: argument: path: extraFetchGitAttrs:
863+
let
864+
# This imports the files unnecessarily, which currently can't be avoided
865+
# because `builtins.fetchGit` is the only function exposing which files are tracked by Git.
866+
# With the [lazy trees PR](https://github.com/NixOS/nix/pull/6530),
867+
# the unnecessarily import could be avoided.
868+
# However a simpler alternative still would be [a builtins.gitLsFiles](https://github.com/NixOS/nix/issues/2944).
869+
fetchResult = fetchGit ({
870+
url = path;
871+
} // extraFetchGitAttrs);
872+
in
873+
if inPureEvalMode then
874+
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."
875+
else if ! isPath path then
876+
throw "lib.fileset.${function}: Expected the ${argument} to be a path, but it's a ${typeOf path} instead."
877+
# We can identify local working directories by checking for .git,
878+
# see https://git-scm.com/docs/gitrepository-layout#_description.
879+
# Note that `builtins.fetchGit` _does_ work for bare repositories (where there's no `.git`),
880+
# even though `git ls-files` wouldn't return any files in that case.
881+
else if ! pathExists (path + "/.git") then
882+
throw "lib.fileset.${function}: Expected the ${argument} (${toString path}) to point to a local working tree of a Git repository, but it's not."
883+
else
884+
_mirrorStorePath path fetchResult.outPath;
885+
855886
}

0 commit comments

Comments
 (0)