diff options
Diffstat (limited to 'pkgs/build-support/fetchgit/nix-prefetch-git')
| -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 259138641ea9..7f3616af92fc 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)) @@ -155,10 +157,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 } @@ -353,6 +361,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() { @@ -418,7 +443,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 @@ -456,8 +482,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 @@ -476,22 +507,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 |
