148 lines
3.5 KiB
Plaintext
148 lines
3.5 KiB
Plaintext
|
#! /bin/sh -e
|
||
|
|
||
|
usage(){
|
||
|
echo >&2 "syntax: nix-prefetch-zip [options]
|
||
|
|
||
|
Options:
|
||
|
--url name The url of the archive to fetch.
|
||
|
--name name The name to use for the store path (defaults to \`basename \$url\`).
|
||
|
--hash name The hash of unpacked archive.
|
||
|
--hash-type hash Use the specified cryptographic hash algorithm, which can be one of md5, sha1, and sha256.
|
||
|
--base32 Print/accept the hash in a base-32 representation rather than hexadecimal.
|
||
|
--leave-root Keep the root directory of the archive.
|
||
|
--help Show this help text.
|
||
|
"
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
|
||
|
argi=0
|
||
|
argfun=""
|
||
|
for arg; do
|
||
|
if test -z "$argfun"; then
|
||
|
case $arg in
|
||
|
--url) argfun=set_url;;
|
||
|
--name) argfun=set_name;;
|
||
|
--hash) argfun=set_expHash;;
|
||
|
--hash-type) argfun=set_hashType;;
|
||
|
--base32) hashFormat="--base32";;
|
||
|
--leave-root) leaveRoot=true;;
|
||
|
--help) usage;;
|
||
|
*)
|
||
|
echo "Unexpected argument: $arg" >&2
|
||
|
usage
|
||
|
;;
|
||
|
esac
|
||
|
else
|
||
|
case $argfun in
|
||
|
set_*)
|
||
|
var=$(echo $argfun | sed 's,^set_,,')
|
||
|
eval "$var=\$arg"
|
||
|
;;
|
||
|
esac
|
||
|
argfun=""
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
if [ -z "$url" ]; then
|
||
|
echo "Error: No --url flag given" >&2
|
||
|
usage
|
||
|
fi
|
||
|
|
||
|
if [ -z "$name" ]; then
|
||
|
name=$(basename "$url")
|
||
|
fi
|
||
|
|
||
|
if test -z "$hashType"; then
|
||
|
hashType=sha256
|
||
|
fi
|
||
|
|
||
|
tmp=$(mktemp -d 2>/dev/null || mktemp -d -t "$$")
|
||
|
trap "rm -rf \"\$tmp\"" EXIT
|
||
|
|
||
|
TMPDIR=$tmp/unpacked/$name
|
||
|
mkdir -p $TMPDIR
|
||
|
downloadedFile=$tmp/$name
|
||
|
|
||
|
unpackFile() {
|
||
|
local curSrc="$1"
|
||
|
|
||
|
case "$curSrc" in
|
||
|
*.tar.xz | *.tar.lzma)
|
||
|
# Don't rely on tar knowing about .xz.
|
||
|
xz -d < $curSrc | tar xf -
|
||
|
;;
|
||
|
*.tar | *.tar.* | *.tgz | *.tbz2)
|
||
|
# GNU tar can automatically select the decompression method
|
||
|
# (info "(tar) gzip").
|
||
|
tar xf $curSrc
|
||
|
;;
|
||
|
*.zip)
|
||
|
unzip -qq $curSrc
|
||
|
;;
|
||
|
*)
|
||
|
echo "source archive $curSrc has unknown type" >&2
|
||
|
exit 1
|
||
|
;;
|
||
|
esac
|
||
|
}
|
||
|
|
||
|
# 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" "$name")
|
||
|
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
|
||
|
curl="curl \
|
||
|
--location --max-redirs 20 \
|
||
|
--disable-epsv \
|
||
|
--insecure"
|
||
|
|
||
|
if ! $curl --fail "$url" --output "$downloadedFile"; then
|
||
|
echo "error: could not download $url" >&2
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
cd $TMPDIR
|
||
|
unpackFile "$downloadedFile"
|
||
|
|
||
|
# FIXME: handle zip files that contain a single regular file.
|
||
|
if [ -z "$leaveRoot" ]; then
|
||
|
shopt -s dotglob
|
||
|
if [ $(ls -d $TMPDIR/* | wc -l) != 1 ]; then
|
||
|
echo "error: zip file must contain a single directory."
|
||
|
exit 1
|
||
|
fi
|
||
|
fn=$(cd "$TMPDIR" && echo *)
|
||
|
mv $TMPDIR/$fn/* "$TMPDIR/"
|
||
|
rmdir "$TMPDIR/$fn"
|
||
|
fi
|
||
|
|
||
|
# Compute the hash.
|
||
|
hash=$(nix-hash --type $hashType $hashFormat $TMPDIR)
|
||
|
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" $TMPDIR)
|
||
|
|
||
|
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
|