Create a gist now

Instantly share code, notes, and snippets.

@smoser /README.md
Last active Oct 28, 2016

What would you like to do?
get-orig-tarball: download orig tarball for a package as read from debian/changelog

get-orig-tarball

Simply, this reads a debian/changelog file and downloads the orig tarball for that version. It allows building a package with debuild if you do not have the original source tarball. Such a case would likely occur if you had used git clone of a debian tree.

Usage

Usage: get-orig-tarball [ options ] [changelog [dir]]

   changelog: the changelog to parse.
   dir: place to put orig tarball. 
        default: dirname(changelog)/../../

   options:
      -O | --overwrite: overwrite an existing file 
#!/bin/bash
VERBOSITY=0
TEMP_D=""
FORMATS=".tar.gz .tar.xz .tar.bz2"
DSC_BASE_URL="http://launchpad.net/ubuntu/+archive/primary/+files"
error() { echo "$@" 1>&2; }
fail() { [ $# -eq 0 ] || error "$@"; exit 1; }
Usage() {
cat <<EOF
Usage: ${0##*/} [ options ] [changelog [dir]]
changelog: the changelog to parse.
dir: place to put orig tarball.
default: dirname(changelog)/../../
options:
-O | --overwrite: overwrite an existing file
EOF
}
for_Usage() {
cat <<EOF
Usage: ${0##*/} for [ options ] pkg pkg-version
package: the source package
version: the version of the package
dir: place to put orig tarball. default: .
options:
-O | --overwrite: overwrite an existing file
EOF
}
for_bad_Usage() { for_Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
cleanup() {
[ -z "${TEMP_D}" -o ! -d "${TEMP_D}" ] || rm -Rf "${TEMP_D}"
}
debug() {
local level=${1}; shift;
[ "${level}" -gt "${VERBOSITY}" ] && return
error "${@}"
}
get_field() {
local clog="$1" field="$2" offset="$3" ret=""
local out=""
out=$(dpkg-parsechangelog \
${offset:+"--offset=$offset"} --show-field "$field" --count=1) || {
ret=$?
error "failed reading '$field' from '$clog'"
return $ret
}
_RET="$out"
}
is_released() {
[ "$1" != "UNRELEASED" -a "$1" != "unreleased" ]
}
get_dsc_url() {
_RET="${DSC_BASE_URL}/${1}_${2}.dsc"
}
dir_has_orig() {
local dir="$1" src="$2" ver="$3" n="" ext=""
for ext in $FORMATS; do
n="${src}_${ver}.orig${ext}"
[ -f "$dir/$n" ] && _RET="$dir/$n" && return 0
done
return 1
}
for_main() {
local short_opts="hOv"
local long_opts="help,overwrite,verbose"
local getopt_out=""
getopt_out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
eval set -- "${getopt_out}" ||
{ bad_Usage; return; }
local cur="" next="" overwrite=false orig="" sdir="$PWD"
local odir="."
while [ $# -ne 0 ]; do
cur="$1"; next="$2";
case "$cur" in
-h|--help) Usage ; exit 0;;
-O|--overwrite) overwrite=true;;
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
--) shift; break;;
esac
shift;
done
local src="$1" ver="$2"
[ $# -eq 2 -o $# -eq 3 ] || {
for_bad_Usage "expected 2 or 3 args, got $#: $*";
return
}
if [ $# -ge 3 ]; then
odir="$3"
[ -d "$odir" ] || { error "$odir: not a directory"; return 1; }
else
odir=$PWD
fi
local pver=""
case "$ver" in
upstream-*) ver="${ver#upstream-}"; uver=$ver; pver="not-provided";;
*-*)
uver=${ver%-*}
pver=${ver##*-};;
*) uver="$ver"; pver="not-provided";;
esac
if [ "$pver" = "not-provided" ]; then
debug 1 "downloading without a dsc, poking for $src and $ver"
local ext="" name="" tname=""
for ext in ${FORMATS}; do
name="${src}_${ver}.orig$ext"
tname="$name.tmp.$$"
wget "${DSC_BASE_URL}/$name" -O "$odir/$tname" &&
mv "$tname" "$odir/$name" &&
{ error "wrote ${name} to $odir"; return 0; } ||
rm -f "$tname"
done
error "failed download of $src at $ver. tried orig formats $FORMATS"
return 1
else
debug 1 "src=$src ver=$ver uver=$uver pver=$pver"
dl_to_dir "$src" "$ver" "$odir" "$overwrite"
fi
}
main() {
local short_opts="hOv"
local long_opts="help,overwrite,verbose"
local getopt_out=""
getopt_out=$(getopt --name "${0##*/}" \
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
eval set -- "${getopt_out}" ||
{ bad_Usage; return; }
local cur="" next="" overwrite=false orig="" sdir="$PWD"
local changelog="debian/changelog" odir="" use_unreleased=false
while [ $# -ne 0 ]; do
cur="$1"; next="$2";
case "$cur" in
-h|--help) Usage ; exit 0;;
-O|--overwrite) overwrite=true;;
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
--) shift; break;;
esac
shift;
done
[ $# -lt 3 ] || {
bad_Usage "expected < 0, 1 or 2 args, got $#: $*";
}
if [ $# -ge 1 ]; then
changelog="$1"
fi
if [ $# -ge 2 ]; then
odir="$2"
[ -d "$odir" ] || { error "$odir: not a directory"; return 1; }
else
odir=$(dirname "$changelog") &&
odir=$(cd "$odir/../.." && pwd) ||
{ error "failed dirname for '$changelog'"; return 1; }
fi
local uver="" ver="" dist="UNRELEASED"
while :; do
get_field "$changelog" Version $offset && ver="$_RET" || return
get_field "$changelog" Distribution $offset && dist="$_RET" || return
get_field "$changelog" Source $offset && src="$_RET" || return
uver=${ver%-*}
pver=${ver##*-}
[ "$unreleased" = "true" ] && break
is_released "$dist" && break
offset=$(($offset+1))
done
debug 1 "src=$src ver=$ver uver=$uver pver=$pver offset=$offset"
dl_to_dir "$src" "$ver" "$odir" "$overwrite"
}
dl_to_dir() {
local src="$1" ver="$2" odir="$3" overwrite=${4:-false} orig=""
if dir_has_orig "$odir" "$src" "$uver"; then
orig=${_RET}
if ! $overwrite; then
error "orig tarball existed at $orig. --overwrite to overwrite."
return 0;
fi
fi
get_dsc_url "$src" "$ver" || return
dsc_url=$_RET
debug 1 "dsc_url=$dsc_url"
TEMP_D=$(mktemp -d "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") ||
fail "failed to make tempdir"
trap cleanup EXIT
cd "$TEMP_D"
local vflag="--quiet"
if [ "$VERBOSITY" -ge 1 ]; then
vflag=""
fi
# unauthenticated is fine because we use https to launchpad
dget $vflag --allow-unauthenticated --download-only "$dsc_url" ||
fail "failed: dget --download-only $dsc_url"
dir_has_orig "$TEMP_D" "$src" "$uver" || {
error "dget succeeded, but no orig tarball found."
cat "$TEMP_D/${src}_${ver}.dsc" 1>&2
ls $TEMP_D 1>&2;
return 1
}
orig="$_RET"
cd "$sdir"
mv "$_RET" "$odir/"
_RET="${odir}/${orig##*/}"
error "wrote $odir/${orig##*/}"
}
if [ "$1" = "for" ]; then
shift
for_main "$@"
else
main "$@"
fi
# vi: ts=4 expandtab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment