diff options
| author | Yuriy Taraday <yuriy.taraday@tweag.io> | 2025-07-18 16:45:45 +0200 |
|---|---|---|
| committer | Yuriy Taraday <yuriy.taraday@tweag.io> | 2025-08-08 16:20:05 +0200 |
| commit | 3985afc65c20a020ae24820d9ccb23eb2fa40c85 (patch) | |
| tree | df2b759cc015f9b3e683c2fb802971e33c629ad6 | |
| parent | winbox4: 4.0beta21 -> 4.0beta26 (#427148) (diff) | |
| download | nixpkgs-3985afc65c20a020ae24820d9ccb23eb2fa40c85.tar.gz | |
nix-prefetch-git: Add --root-dir argument
With this argument nix-prefetch-git will make a subdirectory of the Git
repository a root of the resulting store path. This is helpful for
dealing with monorepos where many projects are in separate directories
and don't need a new source hash every time the monorepo is updated.
The corresponding fetchgit change follows.
| -rwxr-xr-x | pkgs/build-support/fetchgit/nix-prefetch-git | 62 |
1 files changed, 45 insertions, 17 deletions
diff --git a/pkgs/build-support/fetchgit/nix-prefetch-git b/pkgs/build-support/fetchgit/nix-prefetch-git index f8dd93912644..e8bcca7f6b42 100755 --- a/pkgs/build-support/fetchgit/nix-prefetch-git +++ b/pkgs/build-support/fetchgit/nix-prefetch-git @@ -59,6 +59,7 @@ Options: --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. + --root-dir dir Directory in the repository that will be copied to the output instead of the full repository. --quiet Only print the final json summary. " exit 1 @@ -90,6 +91,7 @@ for arg; do --fetch-submodules) fetchSubmodules=true;; --fetch-tags) fetchTags=true;; --builder) builder=true;; + --root-dir) argfun=set_rootDir;; -h|--help) usage; exit;; *) : $((++argi)) @@ -150,10 +152,16 @@ url_to_name(){ local base base=$(basename "$url" .git | cut -d: -f2) - if [[ $ref =~ ^[a-z0-9]+$ ]]; then - echo "$base-${ref:0:7}" + if test -n "$rootDir"; then + # Sanitize by removing leading dots and replacing all invalid character sequences with dashes. + # See sanitizeDerivationName in ../../../lib/strings.nix for reference. + echo "$base-$(sed -E 's/^\.+//;s/[^[:alnum:]+._?=-]+/-/g' <<< $rootDir)" else - echo "$base" + if [[ $ref =~ ^[a-z0-9]+$ ]]; then + echo "$base-${ref:0:7}" + else + echo "$base" + fi fi } @@ -348,6 +356,23 @@ clone_user_rev() { fi } +clone_user_rev_to_tmpfile(){ + local url="$1" + local rev="${2:-HEAD}" + + # nix>=2.20 rejects adding symlinked paths to the store, so use realpath + # to resolve to a physical path. https://github.com/NixOS/nix/issues/11941 + tmpPath="$(realpath "$(mktemp -d --tmpdir git-checkout-tmp-XXXXXXXX)")" + exit_handlers+=(remove_tmpPath) + + tmpOut="$tmpPath/out/$storePathName" + tmpClone="$tmpPath/clone" + mkdir -p "$tmpPath/out" "$tmpClone" + + # Perform the checkout. + clone_user_rev "$tmpClone" "$url" "$rev" +} + exit_handlers=() run_exit_handlers() { @@ -413,7 +438,8 @@ print_results() { "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) + "leaveDotGit": $([[ -n "$leaveDotGit" ]] && echo true || echo false), + "rootDir": "$(json_escape "$rootDir")" } EOF fi @@ -451,8 +477,13 @@ export GIT_CONFIG_NOSYSTEM=1 if test -n "$builder"; then test -n "$out" -a -n "$url" -a -n "$rev" || usage - mkdir -p "$out" - clone_user_rev "$out" "$url" "$rev" + if test -n "$rootDir"; then + clone_user_rev_to_tmpfile "$url" "$rev" + mv "$tmpClone/$rootDir" "$out" + else + mkdir -p "$out" + clone_user_rev "$out" "$url" "$rev" + fi else if test -z "$hashType"; then hashType=sha256 @@ -471,22 +502,19 @@ else # If we don't know the hash or a path with that hash doesn't exist, # download the file and add it to the store. if test -z "$finalPath"; then - # nix>=2.20 rejects adding symlinked paths to the store, so use realpath - # to resolve to a physical path. https://github.com/NixOS/nix/issues/11941 - tmpPath="$(realpath "$(mktemp -d --tmpdir git-checkout-tmp-XXXXXXXX)")" - exit_handlers+=(remove_tmpPath) + clone_user_rev_to_tmpfile "$url" "$rev" - tmpFile="$tmpPath/$storePathName" - mkdir -p "$tmpFile" - - # Perform the checkout. - clone_user_rev "$tmpFile" "$url" "$rev" + if test -z "$rootDir"; then + mv "$tmpClone" "$tmpOut" + else + mv "$tmpClone/$rootDir" "$tmpOut" + fi # Compute the hash. - hash=$(nix-hash --type $hashType --base32 "$tmpFile") + hash=$(nix-hash --type $hashType --base32 "$tmpOut") # Add the downloaded file to the Nix store. - finalPath=$(nix-store --add-fixed --recursive "$hashType" "$tmpFile") + finalPath=$(nix-store --add-fixed --recursive "$hashType" "$tmpOut") if test -n "$expHash" -a "$expHash" != "$hash"; then echo "hash mismatch for URL \`$url'. Got \`$hash'; expected \`$expHash'." >&2 |
