diff --git a/src/script/nix-prefetch-bzr b/src/script/nix-prefetch-bzr new file mode 100755 index 00000000..167892fb --- /dev/null +++ b/src/script/nix-prefetch-bzr @@ -0,0 +1,79 @@ +#! /bin/sh -e + +url=$1 +rev=$2 +expHash=$3 + +hashType=$NIX_HASH_ALGO +if test -z "$hashType"; then + hashType=sha256 +fi +if test -z "$hashFormat"; then + hashFormat=--base32 +fi + +if test -z "$url"; then + echo "syntax: nix-prefetch-bzr URL [REVISION [EXPECTED-HASH]]" >&2 + exit 1 +fi + +revarg="-r $rev" +test -n "$rev" || revarg="" + +repoName=$(echo $url | sed ' + s,.*/\([^/]\+\)/trunk/*$,\1,;t + s,.*/\([^/]\+\)/branches/\([^/]\+\)/*$,\1-\2,;t + s,.*/\([^/]\+\)/tags/\([^/]\+\)/*$,\1-\2,;t + s,.*/\([^/]\+\)/*$,\1,;t +') +dstFile=$repoName-r$rev +test -n "$rev" || dstFile=$repoName + +# If the hash was given, a file with that hash may already be in the +# store. +if test -n "$expHash"; then + finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" $dstFile) + if ! nix-store --check-validity "$finalPath" 2> /dev/null; then + finalPath= + fi + hash=$expHash +fi + + +# 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 + tmpPath=/tmp/bzr-checkout-tmp-$$ + tmpFile=$tmpPath/$dstFile + mkdir $tmpPath + + trap "rm -rf $tmpPath" EXIT + + # Perform the checkout. + if test "$NIX_PREFETCH_BZR_LEAVE_DOT_BZR" != 1 + then + bzr export $revarg "$tmpFile" "$url" >&2 + else + bzr checkout --lightweight $revarg "$url" "$tmpFile" >&2 + fi + + # Compute the hash. + hash=$(nix-hash --type $hashType $hashFormat $tmpFile) + if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi + + # Add the downloaded file to the Nix store. + finalPath=$(nix-store --add-fixed --recursive "$hashType" $tmpFile) + + if test -n "$expHash" -a "$expHash" != "$hash"; then + echo "hash mismatch for URL \`$url'" + exit 1 + fi +fi + +if ! test -n "$QUIET"; then echo "path is $finalPath" >&2; fi + +echo $hash + +if test -n "$PRINT_PATH"; then + echo $finalPath +fi diff --git a/src/script/nix-prefetch-git b/src/script/nix-prefetch-git new file mode 100755 index 00000000..979aa531 --- /dev/null +++ b/src/script/nix-prefetch-git @@ -0,0 +1,269 @@ +#! /bin/sh -e + +url=$1 +rev=$2 +expHash=$3 +hashType=$NIX_HASH_ALGO +deepClone=$NIX_PREFETCH_GIT_DEEP_CLONE +leaveDotGit=$NIX_PREFETCH_GIT_LEAVE_DOT_GIT +builder= + +if test -n "$deepClone"; then + deepClone=true +else + deepClone=false +fi + +if test "$leaveDotGit" != 1; then + leaveDotGit= +else + leaveDotGit=true +fi + + +argi=0 +argfun="" +for arg; do + if test -z "$argfun"; then + case $arg in + --out) argfun=set_out;; + --url) argfun=set_url;; + --rev) argfun=set_rev;; + --hash) argfun=set_hashType;; + --deepClone) deepClone=true;; + --no-deepClone) deepClone=false;; + --leave-dotGit) leaveDotGit=true;; + --builder) builder=true;; + *) + argi=$(($argi + 1)) + case $argi in + 1) url=$arg;; + 2) rev=$arg;; + 3) expHash=$arg;; + *) exit 1;; + esac + ;; + esac + else + case $argfun in + set_*) + var=$(echo $argfun | sed 's,^set_,,') + eval $var=$arg + ;; + esac + argfun="" + fi +done + +usage(){ + echo >&2 "syntax: nix-prefetch-git [options] [URL [REVISION [EXPECTED-HASH]]] + +Options: + --out path Path where the output would be stored. + --url url Any url understand by 'git clone'. + --rev ref Any sha1 or references (such as refs/heads/master) + --hash h Expected hash. + --deepClone Clone submodules recursively. + --no-deepClone Do not clone submodules. + --leave-dotGit Keep the .git directories. + --builder Clone as fetchgit does, but url, rev, and out option are mandatory. +" + exit 1 +} + +if test -z "$url"; then + usage +fi + + +init_remote(){ + local url=$1; + git init; + git remote add origin $url; +} + +# Return the reference of an hash if it exists on the remote repository. +ref_from_hash(){ + local hash=$1; + git ls-remote origin | sed -n "\,$hash\t, { s,\(.*\)\t\(.*\),\2,; p; q}" +} + +# Return the hash of a reference if it exists on the remote repository. +hash_from_ref(){ + local ref=$1 + git ls-remote origin | sed -n "\,\t$ref, { s,\(.*\)\t\(.*\),\1,; p; q}" +} + +# Fetch everything and checkout the right sha1 +checkout_hash(){ + local hash="$1"; + local ref="$2"; + + if test -z "$hash"; then + hash=$(hash_from_ref $ref); + fi; + + git fetch ${builder:+--progress} origin || return 1 + git checkout -b fetchgit $hash || return 1 +} + +# Fetch only a branch/tag and checkout it. +checkout_ref(){ + local hash="$1"; + local ref="$2"; + + if "$deepClone"; then + # The caller explicitly asked for a deep clone. Deep clones + # allow "git describe" and similar tools to work. See + # http://thread.gmane.org/gmane.linux.distributions.nixos/3569 + # for a discussion. + return 1 + fi + + if test -z "$ref"; then + ref=$(ref_from_hash $hash); + fi; + + if test -n "$ref"; then + # --depth option is ignored on http repository. + git fetch ${builder:+--progress} --depth 1 origin +"$ref" || return 1 + git checkout -b fetchgit FETCH_HEAD || return 1 + else + return 1; + fi; +} + +# Update submodules +init_submodules(){ + # Add urls into .git/config file + git submodule init + + # list submodule directories and their hashes + git submodule status | + while read l; do + # checkout each submodule + local hash=$(echo $l | sed 's,^-\([0-9a-f]*\) \(.*\)$,\1,'); + local dir=$(echo $l | sed 's,^-\([0-9a-f]*\) \(.*\)$,\2,'); + local url=$(sed -n "\,$dir, { :loop; n; s,^.*url = ,,; T loop; p; q }" .git/config); + + clone "$dir" "$url" "$hash" ""; + done; +} + +clone(){ + local top=$(pwd) + local dir="$1" + local url="$2" + local hash="$3" + local ref="$4" + + cd $dir; + + # Initialize the repository. + init_remote "$url"; + + # Download data from the repository. + checkout_ref "$hash" "$ref" || + checkout_hash "$hash" "$ref" || ( + echo 1>&2 "Unable to checkout $hash$ref from $url."; + exit 1; + ) + + # Checkout linked sources. + init_submodules; + + if [ -z "$builder" -a -f .topdeps ]; then + if tg help 2>&1 > /dev/null + then + echo "populating TopGit branches..." + tg remote --populate origin + else + echo "WARNING: would populate TopGit branches but TopGit is not available" >&2 + echo "WARNING: install TopGit to fix the problem" >&2 + fi + fi + + cd $top; +} + +clone_user_rev() { + local dir="$1" + local url="$2" + local rev="$3" + + # Perform the checkout. + case "$rev" in + HEAD|refs/*) + clone "$dir" "$url" "" "$rev" 1>&2;; + [0-9a-f]*) + if test -z "$(echo $rev | tr -d 0123456789abcdef)"; then + clone "$dir" "$url" "$rev" "" 1>&2; + else + echo 1>&2 "Bad commit hash or bad reference."; + exit 1; + fi;; + "") + clone "$dir" "$url" "" "HEAD" 1>&2;; + esac + + # Allow doing additional processing before .git removal + eval "$NIX_PREFETCH_GIT_CHECKOUT_HOOK" + if test -z "$leaveDotGit"; then + echo "removing \`.git'..." >&2 + find $dir -name .git\* | xargs rm -rf + fi +} + +if test -n "$builder"; then + test -n "$out" -a -n "$url" -a -n "$rev" || usage + mkdir $out + clone_user_rev "$out" "$url" "$rev" +else + if test -z "$hashType"; then + hashType=sha256 + fi + + # If the hash was given, a file with that hash may already be in the + # store. + if test -n "$expHash"; then + finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" git-export) + if ! nix-store --check-validity "$finalPath" 2> /dev/null; then + finalPath= + fi + hash=$expHash + fi + + # 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 + + tmpPath=/tmp/git-checkout-tmp-$$ + tmpFile=$tmpPath/git-export + mkdir $tmpPath $tmpFile + + trap "rm -rf $tmpPath" EXIT + + # Perform the checkout. + clone_user_rev "$tmpFile" "$url" "$rev" + + # Compute the hash. + hash=$(nix-hash --type $hashType $hashFormat $tmpFile) + if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi + + # Add the downloaded file to the Nix store. + finalPath=$(nix-store --add-fixed --recursive "$hashType" $tmpFile) + + if test -n "$expHash" -a "$expHash" != "$hash"; then + echo "hash mismatch for URL \`$url'" + exit 1 + fi + fi + + if ! test -n "$QUIET"; then echo "path is $finalPath" >&2; fi + + echo $hash + + if test -n "$PRINT_PATH"; then + echo $finalPath + fi +fi diff --git a/src/script/nix-prefetch-hg b/src/script/nix-prefetch-hg new file mode 100755 index 00000000..55501f41 --- /dev/null +++ b/src/script/nix-prefetch-hg @@ -0,0 +1,75 @@ +#! /bin/sh -e + +url=$1 +rev=$2 +expHash=$3 + +hashType=$NIX_HASH_ALGO +if test -z "$hashType"; then + hashType=sha256 +fi +if test -z "$hashFormat"; then + hashFormat=--base32 +fi + +if test -z "$url"; then + echo "syntax: nix-prefetch-hg URL [rev [EXPECTED-HASH]]" >&2 + exit 1 +fi + +test -n "$rev" || rev="tip" + + +# If the hash was given, a file with that hash may already be in the +# store. +if test -n "$expHash"; then + finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" hg-archive) + if ! nix-store --check-validity "$finalPath" 2> /dev/null; then + finalPath= + fi + hash=$expHash +fi + + +# 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 + + tmpPath=/tmp/hg-checkout-tmp-$$ + tmpArchive=$tmpPath/hg-archive + mkdir $tmpPath + + trap "rm -rf $tmpPath" EXIT + + # Perform the checkout. + if [[ $url != /* ]]; then + tmpClone=$tmpPath/hg-clone + hg clone -q -y -U "$url" $tmpClone >&2 + else + tmpClone=$url + fi + hg archive -q -y -r "$rev" --cwd $tmpClone $tmpArchive + + + # Compute the hash. + hash=$(nix-hash --type $hashType $hashFormat $tmpArchive) + if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi + + # Add the downloaded file to the Nix store. + finalPath=$(nix-store --add-fixed --recursive "$hashType" $tmpArchive) + + if test -n "$expHash" -a "$expHash" != "$hash"; then + echo "hash mismatch for URL \`$url'" + exit 1 + fi + + +fi + +if ! test -n "$QUIET"; then echo "path is $finalPath" >&2; fi + +echo $hash + +if test -n "$PRINT_PATH"; then + echo $finalPath +fi diff --git a/src/script/nix-prefetch-svn b/src/script/nix-prefetch-svn new file mode 100755 index 00000000..2858a0b0 --- /dev/null +++ b/src/script/nix-prefetch-svn @@ -0,0 +1,79 @@ +#! /bin/sh -e + +url=$1 +rev=$2 +expHash=$3 + +hashType=$NIX_HASH_ALGO +if test -z "$hashType"; then + hashType=sha256 +fi +if test -z "$hashFormat"; then + hashFormat=--base32 +fi + +if test -z "$url"; then + echo "syntax: nix-prefetch-svn URL [REVISION [EXPECTED-HASH]]" >&2 + exit 1 +fi + +test -n "$rev" || rev="HEAD" + +repoName=$(echo $url | sed ' + s,.*/\([^/]\+\)/trunk/*$,\1,;t + s,.*/\([^/]\+\)/branches/\([^/]\+\)/*$,\1-\2,;t + s,.*/\([^/]\+\)/tags/\([^/]\+\)/*$,\1-\2,;t + s,.*/\([^/]\+\)/*$,\1,;t +') +dstFile=$repoName-r$rev + +# If the hash was given, a file with that hash may already be in the +# store. +if test -n "$expHash"; then + finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" $dstFile) + if ! nix-store --check-validity "$finalPath" 2> /dev/null; then + finalPath= + fi + hash=$expHash +fi + + +# 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 + tmpPath=/tmp/svn-checkout-tmp-$$ + tmpFile=$tmpPath/$dstFile + mkdir $tmpPath + + trap "rm -rf $tmpPath" EXIT + + # Perform the checkout. + if test "$NIX_PREFETCH_SVN_LEAVE_DOT_SVN" != 1 + then + command="export" + else + command="checkout" + fi + + echo p | svn "$command" --quiet -r "$rev" "$url" "$tmpFile" >&2 + + # Compute the hash. + hash=$(nix-hash --type $hashType $hashFormat $tmpFile) + if ! test -n "$QUIET"; then echo "hash is $hash" >&2; fi + + # Add the downloaded file to the Nix store. + finalPath=$(nix-store --add-fixed --recursive "$hashType" $tmpFile) + + if test -n "$expHash" -a "$expHash" != "$hash"; then + echo "hash mismatch for URL \`$url'" + exit 1 + fi +fi + +if ! test -n "$QUIET"; then echo "path is $finalPath" >&2; fi + +echo $hash + +if test -n "$PRINT_PATH"; then + echo $finalPath +fi