From 124703168968a104a61291ef0de35fa05e1813f6 Mon Sep 17 00:00:00 2001 From: Tim Black Date: Tue, 27 May 2025 15:25:19 -0700 Subject: [PATCH] pkgs/build-support/fetchgit: add fetchTags parameter Added fetchTags feature to fetchgit, explicit and clear support for fetching all tags after the source tree fetch completes. Doing this at build-time in the fetcher is required for packages that invoke commands like 'git describe' which require tags, and since the nix store is read-only by design, it is not possible to git fetch --tags at activation- or run-time. This feature may have been possible by specifying a postFetch option including calling git fetch --tags, however doing so obfuscates the solution to this very real problem. Explicit support for fetching tags should be a first class citizen just like fetching other refs. --- .gitignore | 1 + doc/build-helpers/fetchers.chapter.md | 4 ++++ pkgs/build-support/fetchgit/builder.sh | 1 + pkgs/build-support/fetchgit/default.nix | 6 +++++- pkgs/build-support/fetchgit/nix-prefetch-git | 10 ++++++++++ pkgs/build-support/fetchgit/tests.nix | 12 ++++++++++++ 6 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4327aeb119e5..5177a02b15b3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ .nixos-test-history .vscode/ .helix/ +*.vim outputs/ result-* result diff --git a/doc/build-helpers/fetchers.chapter.md b/doc/build-helpers/fetchers.chapter.md index 997f97f81bdb..96b85d7b0d4f 100644 --- a/doc/build-helpers/fetchers.chapter.md +++ b/doc/build-helpers/fetchers.chapter.md @@ -795,6 +795,10 @@ Additionally, the following optional arguments can be given: : Clone the entire repository as opposing to just creating a shallow clone. This implies `leaveDotGit`. +*`fetchTags`* (Boolean) + +: Whether to fetch all tags from the remote repository. This is useful when the build process needs to run `git describe` or other commands that require tag information to be available. This parameter implies `leaveDotGit`, as tags are stored in the `.git` directory. + *`sparseCheckout`* (List of String) : Prevent git from fetching unnecessary blobs from server. diff --git a/pkgs/build-support/fetchgit/builder.sh b/pkgs/build-support/fetchgit/builder.sh index 569a67182844..819b0127a852 100644 --- a/pkgs/build-support/fetchgit/builder.sh +++ b/pkgs/build-support/fetchgit/builder.sh @@ -13,6 +13,7 @@ $SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" --name "$name" ${fetchLFS:+--fetch-lfs} \ ${deepClone:+--deepClone} \ ${fetchSubmodules:+--fetch-submodules} \ + ${fetchTags:+--fetch-tags} \ ${sparseCheckout:+--sparse-checkout "$sparseCheckout"} \ ${nonConeMode:+--non-cone-mode} \ ${branchName:+--branch-name "$branchName"} diff --git a/pkgs/build-support/fetchgit/default.nix b/pkgs/build-support/fetchgit/default.nix index 1da8d2591c5b..9fd433ff6d66 100644 --- a/pkgs/build-support/fetchgit/default.nix +++ b/pkgs/build-support/fetchgit/default.nix @@ -28,7 +28,7 @@ lib.makeOverridable ( url, tag ? null, rev ? null, - leaveDotGit ? deepClone, + leaveDotGit ? deepClone || fetchTags, outputHash ? lib.fakeHash, outputHashAlgo ? null, fetchSubmodules ? true, @@ -55,6 +55,8 @@ lib.makeOverridable ( netrcImpureEnvVars ? [ ], meta ? { }, allowedRequisites ? null, + # fetch all tags after tree (useful for git describe) + fetchTags ? false, }: /* @@ -81,6 +83,7 @@ lib.makeOverridable ( */ assert nonConeMode -> (sparseCheckout != [ ]); + assert fetchTags -> leaveDotGit; let revWithTag = @@ -136,6 +139,7 @@ lib.makeOverridable ( nonConeMode preFetch postFetch + fetchTags ; rev = revWithTag; diff --git a/pkgs/build-support/fetchgit/nix-prefetch-git b/pkgs/build-support/fetchgit/nix-prefetch-git index 7ba7fa568cd6..9d55c9019e08 100755 --- a/pkgs/build-support/fetchgit/nix-prefetch-git +++ b/pkgs/build-support/fetchgit/nix-prefetch-git @@ -11,6 +11,7 @@ leaveDotGit=$NIX_PREFETCH_GIT_LEAVE_DOT_GIT fetchSubmodules= fetchLFS= builder= +fetchTags= branchName=$NIX_PREFETCH_GIT_BRANCH_NAME # ENV params @@ -56,6 +57,7 @@ Options: --leave-dotGit Keep the .git directories. --fetch-lfs Fetch git Large File Storage (LFS) files. --fetch-submodules Fetch submodules. + --fetch-tags Fetch all tags (useful for git describe). --builder Clone as fetchgit does, but url, rev, and out option are mandatory. --quiet Only print the final json summary. " @@ -86,6 +88,7 @@ for arg; do --leave-dotGit) leaveDotGit=true;; --fetch-lfs) fetchLFS=true;; --fetch-submodules) fetchSubmodules=true;; + --fetch-tags) fetchTags=true;; --builder) builder=true;; -h|--help) usage; exit;; *) @@ -234,6 +237,12 @@ clone(){ exit 1 ) + # Fetch all tags if requested + if test -n "$fetchTags"; then + echo "fetching all tags..." >&2 + clean_git fetch origin 'refs/tags/*:refs/tags/*' || echo "warning: failed to fetch some tags" >&2 + fi + # Checkout linked sources. if test -n "$fetchSubmodules"; then init_submodules @@ -403,6 +412,7 @@ print_results() { "fetchLFS": $([[ -n "$fetchLFS" ]] && echo true || echo false), "fetchSubmodules": $([[ -n "$fetchSubmodules" ]] && echo true || echo false), "deepClone": $([[ -n "$deepClone" ]] && echo true || echo false), + "fetchTags": $([[ -n "$fetchTags" ]] && echo true || echo false), "leaveDotGit": $([[ -n "$leaveDotGit" ]] && echo true || echo false) } EOF diff --git a/pkgs/build-support/fetchgit/tests.nix b/pkgs/build-support/fetchgit/tests.nix index e26917a4f673..ce733347cfa0 100644 --- a/pkgs/build-support/fetchgit/tests.nix +++ b/pkgs/build-support/fetchgit/tests.nix @@ -83,4 +83,16 @@ rev = "v3.0.14"; sha256 = "sha256-bd0Lx75Gd1pcBJtwz5WGki7XoYSpqhinCT3a77wpY2c="; }; + + fetchTags = testers.invalidateFetcherByDrvHash fetchgit { + name = "fetchgit-fetch-tags-test"; + url = "https://github.com/NixOS/nix"; + rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a"; + fetchTags = true; + leaveDotGit = true; + sha256 = "sha256-2vfZnYjZlnC8ODz6B6aOqAqtb1Wbjojnn/5TmzwUrmo="; + postFetch = '' + cd $out && git describe --tags --always > describe-output.txt 2>&1 || echo "git describe failed" > describe-output.txt + ''; + }; }