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.
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user