diff --git a/lib/customisation.nix b/lib/customisation.nix index 7c24dc242d06..802c9ef9a4b8 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -285,18 +285,9 @@ rec { arg: let loc = builtins.unsafeGetAttrPos arg fargs; - # loc' can be removed once lib/minver.nix is >2.3.4, since that includes - # https://github.com/NixOS/nix/pull/3468 which makes loc be non-null - loc' = - if loc != null then - loc.file + ":" + toString loc.line - else if !isFunction fn then - toString (lib.filesystem.resolveDefaultNix fn) - else - ""; in "Function called without required argument \"${arg}\" at " - + "${loc'}${prettySuggestions (getSuggestions arg)}"; + + "${loc.file}:${loc.line}${prettySuggestions (getSuggestions arg)}"; # Only show the error for the first missing argument error = errorForArg (head (attrNames missingArgs)); diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix index 17393a81860f..3c51c6d4dab4 100644 --- a/lib/fileset/default.nix +++ b/lib/fileset/default.nix @@ -112,7 +112,6 @@ let _intersection _difference _fromFetchGit - _fetchGitSubmodulesMinver _emptyWithoutBase ; @@ -1000,16 +999,10 @@ in path: if !isBool recurseSubmodules then throw "lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it's a ${typeOf recurseSubmodules} instead." - else if recurseSubmodules && versionOlder nixVersion _fetchGitSubmodulesMinver then - 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." else _fromFetchGit "gitTrackedWith" "second argument" path # This is the only `fetchGit` parameter that makes sense in this context. - # We can't just pass `submodules = recurseSubmodules` here because - # this would fail for Nix versions that don't support `submodules`. - ( - lib.optionalAttrs recurseSubmodules { - submodules = true; - } - ); + { + submodules = recurseSubmodules; + }; } diff --git a/lib/fileset/internal.nix b/lib/fileset/internal.nix index 4674a321b3ae..59b8408ae8d6 100644 --- a/lib/fileset/internal.nix +++ b/lib/fileset/internal.nix @@ -899,14 +899,6 @@ rec { ${baseNameOf root} = fromFile (baseNameOf root) rootType; }; - # Support for `builtins.fetchGit` with `submodules = true` was introduced in 2.4 - # https://github.com/NixOS/nix/commit/55cefd41d63368d4286568e2956afd535cb44018 - _fetchGitSubmodulesMinver = "2.4"; - - # Support for `builtins.fetchGit` with `shallow = true` was introduced in 2.4 - # https://github.com/NixOS/nix/commit/d1165d8791f559352ff6aa7348e1293b2873db1c - _fetchGitShallowMinver = "2.4"; - # Mirrors the contents of a Nix store path relative to a local path as a file set. # Some notes: # - The store path is read at evaluation time. @@ -961,16 +953,8 @@ rec { fetchResult = fetchGit ( { url = path; + shallow = true; } - # In older Nix versions, repositories were always assumed to be deep clones, which made `fetchGit` fail for shallow clones - # For newer versions this was fixed, but the `shallow` flag is required. - # The only behavioral difference is that for shallow clones, `fetchGit` doesn't return a `revCount`, - # which we don't need here, so it's fine to always pass it. - - # Unfortunately this means older Nix versions get a poor error message for shallow repositories, and there's no good way to improve that. - # Checking for `.git/shallow` doesn't seem worth it, especially since that's more of an implementation detail, - # and would also require more code to handle worktrees where `.git` is a file. - // optionalAttrs (versionAtLeast nixVersion _fetchGitShallowMinver) { shallow = true; } // extraFetchGitAttrs ); in diff --git a/lib/fileset/tests.sh b/lib/fileset/tests.sh index 405fa04d8e06..043c1156a43f 100755 --- a/lib/fileset/tests.sh +++ b/lib/fileset/tests.sh @@ -1336,14 +1336,6 @@ expectFailure 'gitTrackedWith {} ./.' 'lib.fileset.gitTrackedWith: Expected the # recurseSubmodules has to be a boolean expectFailure 'gitTrackedWith { recurseSubmodules = null; } ./.' 'lib.fileset.gitTrackedWith: Expected the attribute `recurseSubmodules` of the first argument to be a boolean, but it'\''s a null instead.' -# recurseSubmodules = true is not supported on all Nix versions -if [[ "$(nix-instantiate --eval --expr "$prefixExpression (versionAtLeast builtins.nixVersion _fetchGitSubmodulesMinver)")" == true ]]; then - fetchGitSupportsSubmodules=1 -else - fetchGitSupportsSubmodules= - expectFailure 'gitTrackedWith { recurseSubmodules = true; } ./.' 'lib.fileset.gitTrackedWith: Setting the attribute `recurseSubmodules` to `true` is only supported for Nix version 2.4 and after, but Nix version [0-9.]+ is used.' -fi - # Checks that `gitTrackedWith` contains the same files as `git ls-files` # for the current working directory. # If --recurse-submodules is passed, the flag is passed through to `git ls-files` @@ -1393,9 +1385,7 @@ checkGitTrackedWith() { # Allows testing both variants together checkGitTracked() { checkGitTrackedWith - if [[ -n "$fetchGitSupportsSubmodules" ]]; then - checkGitTrackedWith --recurse-submodules - fi + checkGitTrackedWith --recurse-submodules } createGitRepo() { @@ -1430,51 +1420,45 @@ expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTracked: T [[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' ## Even with submodules -if [[ -n "$fetchGitSupportsSubmodules" ]]; then - ## Both the main repo with the submodule - echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTrackedWith { recurseSubmodules = true; } ./.; }' > default.nix - createGitRepo sub - git submodule add ./sub sub >/dev/null - ## But also the submodule itself - echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTracked ./.; }' > sub/default.nix - git -C sub add . +## Both the main repo with the submodule +echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTrackedWith { recurseSubmodules = true; } ./.; }' > default.nix +createGitRepo sub +git submodule add ./sub sub >/dev/null +## But also the submodule itself +echo '{ fs }: fs.toSource { root = ./.; fileset = fs.gitTracked ./.; }' > sub/default.nix +git -C sub add . - ## We can evaluate it locally just fine, `fetchGit` is used underneath to filter git-tracked files - expectEqual '(import ./. { fs = lib.fileset; }).outPath' '(builtins.fetchGit { url = ./.; submodules = true; }).outPath' - expectEqual '(import ./sub { fs = lib.fileset; }).outPath' '(builtins.fetchGit ./sub).outPath' +## We can evaluate it locally just fine, `fetchGit` is used underneath to filter git-tracked files +expectEqual '(import ./. { fs = lib.fileset; }).outPath' '(builtins.fetchGit { url = ./.; submodules = true; }).outPath' +expectEqual '(import ./sub { fs = lib.fileset; }).outPath' '(builtins.fetchGit ./sub).outPath' - ## We can also evaluate when importing from fetched store paths - storePathWithSub=$(expectStorePath 'builtins.fetchGit { url = ./.; submodules = true; }') - expectEqual '(import '"$storePathWithSub"' { fs = lib.fileset; }).outPath' \""$storePathWithSub"\" - storePathSub=$(expectStorePath 'builtins.fetchGit ./sub') - expectEqual '(import '"$storePathSub"' { fs = lib.fileset; }).outPath' \""$storePathSub"\" +## We can also evaluate when importing from fetched store paths +storePathWithSub=$(expectStorePath 'builtins.fetchGit { url = ./.; submodules = true; }') +expectEqual '(import '"$storePathWithSub"' { fs = lib.fileset; }).outPath' \""$storePathWithSub"\" +storePathSub=$(expectStorePath 'builtins.fetchGit ./sub') +expectEqual '(import '"$storePathSub"' { fs = lib.fileset; }).outPath' \""$storePathSub"\" - ## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}") - expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTrackedWith: The second argument \(.*\) is a store path within a working tree of a Git repository. - [[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. - [[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. - [[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. - [[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' - expectFailure 'import "${./.}/sub" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*/sub\) is a store path within a working tree of a Git repository. - [[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. - [[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. - [[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. - [[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' -fi +## But it fails if the path is imported with a fetcher that doesn't remove .git (like just using "${./.}") +expectFailure 'import "${./.}" { fs = lib.fileset; }' 'lib.fileset.gitTrackedWith: The second argument \(.*\) is a store path within a working tree of a Git repository. +[[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. +[[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. +[[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. +[[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' +expectFailure 'import "${./.}/sub" { fs = lib.fileset; }' 'lib.fileset.gitTracked: The argument \(.*/sub\) is a store path within a working tree of a Git repository. +[[:blank:]]*This indicates that a source directory was imported into the store using a method such as `import "\$\{./.\}"` or `path:.`. +[[:blank:]]*This function currently does not support such a use case, since it currently relies on `builtins.fetchGit`. +[[:blank:]]*You could make this work by using a fetcher such as `fetchGit` instead of copying the whole repository. +[[:blank:]]*If you can'\''t avoid copying the repo to the store, see https://github.com/NixOS/nix/issues/9292.' rm -rf -- * -# shallow = true is not supported on all Nix versions -# and older versions don't support shallow clones at all -if [[ "$(nix-instantiate --eval --expr "$prefixExpression (versionAtLeast builtins.nixVersion _fetchGitShallowMinver)")" == true ]]; then - createGitRepo full - # Extra commit such that there's a commit that won't be in the shallow clone - git -C full commit --allow-empty -q -m extra - git clone -q --depth 1 "file://${PWD}/full" shallow - cd shallow - checkGitTracked - cd .. - rm -rf -- * -fi +createGitRepo full +# Extra commit such that there's a commit that won't be in the shallow clone +git -C full commit --allow-empty -q -m extra +git clone -q --depth 1 "file://${PWD}/full" shallow +cd shallow +checkGitTracked +cd .. +rm -rf -- * # Go through all stages of Git files # See https://www.git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository