Author: schoenfeld Date: 2009-01-09 21:51:46 +0000 (Fri, 09 Jan 2009) New Revision: 1781
Added: trunk/scripts/debsnap.1 trunk/scripts/debsnap.sh Modified: trunk/README trunk/conf.default.in trunk/debian/changelog trunk/debian/control trunk/debian/postinst Log: debsnap: Added new script from Ron Lee and David Paleino, which grabs source packages from snapshot.debian.net. (Closes: #511345) Modified: trunk/README =================================================================== --- trunk/README 2009-01-05 19:23:44 UTC (rev 1780) +++ trunk/README 2009-01-09 21:51:46 UTC (rev 1781) @@ -119,6 +119,8 @@ .changes and .dsc files from a remote machine. [gnupg, debian-keyring, ssh-client] +- debsnap: Grabs packages from http://snapshot.debian.net [wget] + - debuild: A wrapper for building a package (i.e., dpkg-buildpackage) to avoid problems with insufficient permissions and wrong paths etc. Debuild will set up the proper environment for building a package. Modified: trunk/conf.default.in =================================================================== --- trunk/conf.default.in 2009-01-05 19:23:44 UTC (rev 1780) +++ trunk/conf.default.in 2009-01-09 21:51:46 UTC (rev 1781) @@ -293,6 +293,27 @@ # GPG keyid to use (-k option) # DEBSIGN_KEYID= +##### debsnap +# +# Where to put the directory named <prefix>-<package>/ +# default: source-$package_name if unset +# DEBSNAP_DESTDIR= +# +# Verbosely show messages (yes/no) +# default: no +# DEBSNAP_VERBOSE=no +# +# The base URL of the archive to download from +# DEBSNAP_BASE_URL=http://snapshot.debian.net/archive +# +# A sed regexp to transform pool/<component>/f/foo into the desired layout +# default: make the directory from pool/<component>/f/foo to pool/f/foo +# DEBSNAP_CLEAN_REGEX="s...@\([^/]*\)/[^/]*/\(.*\)@\1/\2@" +# +# Where the Sources.gz lives, subdirectory of DEBSNAP_BASE_URL/<clean dir>/ +# default: DEBSNAP_BASE_URL/<clean dir>/source/Sources.gz +# DEBSNAP_SOURCES_GZ_PATH=source/Sources.gz + ##### debuild # # Do we preserve the whole environment except for PATH? Modified: trunk/debian/changelog =================================================================== --- trunk/debian/changelog 2009-01-05 19:23:44 UTC (rev 1780) +++ trunk/debian/changelog 2009-01-09 21:51:46 UTC (rev 1781) @@ -1,9 +1,15 @@ devscripts (2.10.45) UNRELEASED; urgency=low + [ Adam D. Barratt ] * NOT RELEASED YET - -- Adam D. Barratt <[email protected]> Mon, 05 Jan 2009 19:23:14 +0000 + [ Patrick Schoenfeld ] + * debsnap: Added new script from Ron Lee and David Paleino, + which grabs source packages from snapshot.debian.net. + (Closes: #511345) + -- Patrick Schoenfeld <[email protected]> Fri, 09 Jan 2009 22:44:01 +0100 + devscripts (2.10.44) unstable; urgency=low [ Adam D. Barratt ] Modified: trunk/debian/control =================================================================== --- trunk/debian/control 2009-01-05 19:23:44 UTC (rev 1780) +++ trunk/debian/control 2009-01-09 21:51:46 UTC (rev 1781) @@ -69,6 +69,7 @@ the rest of the package to be present; can sign the pair remotely or fetch the pair from a remote machine for signing [gnupg, debian-keyring, ssh-client] + - debsnap: grab packages from http://snapshot.debian.net [wget] - debuild: wrapper to build a package without having to su or worry about how to invoke dpkg to build using fakeroot. Also deals with common environment problems, umask etc. [fakeroot, Modified: trunk/debian/postinst =================================================================== --- trunk/debian/postinst 2009-01-05 19:23:44 UTC (rev 1780) +++ trunk/debian/postinst 2009-01-09 21:51:46 UTC (rev 1781) @@ -616,6 +616,33 @@ EOF fi + + if dpkg --compare-versions "$2" lt 2.10.45 + then + cat >> /etc/devscripts.conf << EOF +##### debsnap +# +# Where to put the directory named <prefix>-<package>/ +# default: source-$package_name if unset +# DEBSNAP_DESTDIR= +# +# Verbosely show messages (yes/no) +# default: no +# DEBSNAP_VERBOSE=no +# +# The base URL of the archive to download from +# DEBSNAP_BASE_URL=http://snapshot.debian.net/archive +# +# A sed regexp to transform pool/<component>/f/foo into the desired layout +# default: make the directory from pool/<component>/f/foo to pool/f/foo +# DEBSNAP_CLEAN_REGEX="s...@\([^/]*\)/[^/]*/\(.*\)@\1/\2@" +# +# Where the Sources.gz lives, subdirectory of DEBSNAP_BASE_URL/<clean dir>/ +# default: DEBSNAP_BASE_URL/<clean dir>/source/Sources.gz +# DEBSNAP_SOURCES_GZ_PATH=source/Sources.gz + +EOF + fi fi fi Added: trunk/scripts/debsnap.1 =================================================================== --- trunk/scripts/debsnap.1 (rev 0) +++ trunk/scripts/debsnap.1 2009-01-09 21:51:46 UTC (rev 1781) @@ -0,0 +1,288 @@ +.\" for manpage-specific macros, see man(7) +.TH DEBSNAP 1 "January 8, 2009" "Debian devscripts" "DebSnap User Manual" +.SH NAME +debsnap \- retrieve old snapshots of Debian packages + +.SH SYNOPSIS +.B debsnap +.RI [ options ] " package " [ version ] + +.B debsnap +.RB [ -h " | " \-\-help ] " " [ \-\-version ] + + +.SH DESCRIPTION +\fBdebsnap\fP is a tool to help with retrieving snapshots of old packages from +a daily archive repository. + +The only publicly available snapshot archive is currently located at +\fIhttp://snapshot.debian.net\fP + +By default, debsnap will download all the available versions for \fIpackage\fP +that are found in the snapshot archive. If a \fIversion\fP is specified, only +that particular version will be downloaded, if available. + + +.SH OPTIONS +The following options are available: + +.TP +.BI -d " destination\fR,\fP " \-\-destdir " destination" +Directory to place retrieved packages. + +.TP +.BR \-f ", " \-\-force +Force overwriting an existing \fIdestination\fP. By default \fBdebsnap\fP will +insist the destination directory does not exist yet unless it is explicitly +specified to be '.' (the current working directory). This is to avoid files +being accidentally overwritten by what is fetched from the archive and to +provide a guarantee for other scripts that only the files fetched will be +present there upon completion. Note that this option will remove the +\fIdestination\fP directory and all of its contents prior to beginning the +download. + +.TP +.BR \-v ", " \-\-verbose +Report on the \fBdebsnap\fP configuration being used and progress during the +download operation. Please always use this option when reporting bugs. + +.TP +.BR \-h ", " \-\-help +Show a summary of these options. + +.TP +.B \-\-version +Show the version of \fBdebsnap\fP. + + +.SH CONFIGURATION OPTIONS +\fBdebsnap\fP may also be configured through the use of the following options +in the devscripts configuration files: + +.TP +.B DEBSNAP_VERBOSE +Same as the command line option \fB\-\-verbose\fP. Set to "yes" to enable. + +.TP +.B DEBSNAP_DESTDIR +Set a default path for the destination directory. If unset +\fI./source\-<package_name>\fP will be used. The command line option +\fB\-\-destdir\fP will override this. + +.TP +.B DEBSNAP_BASE_URL +The base url for the snapshots archive. This is the root of a directory tree +such as \fIpool/<initial>/<package>/\fP under which a \fISources.gz\fP may be +found, and the root for the location of the packages specified in the +\fISources.gz\fP file found there. + +If unset this defaults to \fIhttp://snapshot.debian.net/archive/\fP + +.TP +.B DEBSNAP_CLEAN_REGEX +A sed regular expression to transform the directory returned by +`\fBapt\-cache showsrc\fP \fIpackage\fP \fB| grep ^Directory\fP` to a suitable +path to be put between \fBDEBSNAP_BASE_URL\fP and \fBDEBSNAP_SOURCES_GZ_PATH\fP. + +If unset it will default to s...@\e([^/]*\e)/[^/]*/\e(\&.*\e)@\e1/\e2@ +.br +i.e. it transforms \fIpool/<component>/<initial>/<package>\fP into +\fIpool/<initial>/<package>\fP + +.TP +.B DEBSNAP_SOURCES_GZ_PATH +The final path to the \fISources.gz\fP file. This is appended after the +\fBDEBSNAP_BASE_URL\fP and the path modified by \fBDEBSNAP_CLEAN_REGEX\fP to +locate the \fISources.gz\fP file for the package to download. + +If unset it will default to \fIsource/Sources.gz\fP + + +.SH EXIT STATUS +\fBdebsnap\fP will return an exit status of 0 if all operations succeeded, +1 if a fatal error occurred, and 2 if some packages failed to be downloaded +but operations otherwise succeeded as expected. In some cases packages may +fail to be downloaded because they are no longer available on the snapshot +mirror, so any caller should expect this may occur in normal use. + + +.SH FILES +.TP +.I /etc/devscripts.conf +Global devscripts configuration options. Will override hardcoded defaults. +.TP +.I ~/.devscripts +Per\-user configuration options. Will override any global configuration. + + +.SH SEE ALSO +.BR devscripts (1), +.BR devscripts.conf (5), +.BR git-debimport (1) + + +.SH AUTHORS +David Paleino <[email protected]> +.br +Ron Lee <[email protected]> + +.SH COPYRIGHT +Copyright \(co 2009 David Paleino, Ron Lee + +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 3 or (at your option) +any later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public License can +be found in \fI/usr/share/common\-licenses/GPL\fP. + + +.SH BUGS +.SS Reporting bugs +The program is part of the devscripts package. Please report bugs using +`\fBreportbug devscripts\fP` + +.\" for manpage-specific macros, see man(7) +.TH DEBSNAP 1 "January 8, 2009" "Debian devscripts" "DebSnap User Manual" +.SH NAME +debsnap \- retrieve old snapshots of Debian packages + +.SH SYNOPSIS +.B debsnap +.RI [ options ] " package " [ version ] + +.B debsnap +.RB [ -h " | " \-\-help ] " " [ \-\-version ] + + +.SH DESCRIPTION +\fBdebsnap\fP is a tool to help with retrieving snapshots of old packages from +a daily archive repository. + +The only publicly available snapshot archive is currently located at +\fIhttp://snapshot.debian.net\fP + +By default, debsnap will download all the available versions for \fIpackage\fP +that are found in the snapshot archive. If a \fIversion\fP is specified, only +that particular version will be downloaded, if available. + + +.SH OPTIONS +The following options are available: + +.TP +.BI -d " destination\fR,\fP " \-\-destdir " destination" +Directory to place retrieved packages. + +.TP +.BR \-f ", " \-\-force +Force overwriting an existing \fIdestination\fP. By default \fBdebsnap\fP will +insist the destination directory does not exist yet unless it is explicitly +specified to be '.' (the current working directory). This is to avoid files +being accidentally overwritten by what is fetched from the archive and to +provide a guarantee for other scripts that only the files fetched will be +present there upon completion. Note that this option will remove the +\fIdestination\fP directory and all of its contents prior to beginning the +download. + +.TP +.BR \-v ", " \-\-verbose +Report on the \fBdebsnap\fP configuration being used and progress during the +download operation. Please always use this option when reporting bugs. + +.TP +.BR \-h ", " \-\-help +Show a summary of these options. + +.TP +.B \-\-version +Show the version of \fBdebsnap\fP. + + +.SH CONFIGURATION OPTIONS +\fBdebsnap\fP may also be configured through the use of the following options +in the devscripts configuration files: + +.TP +.B DEBSNAP_VERBOSE +Same as the command line option \fB\-\-verbose\fP. Set to "yes" to enable. + +.TP +.B DEBSNAP_DESTDIR +Set a default path for the destination directory. If unset +\fI./source\-<package_name>\fP will be used. The command line option +\fB\-\-destdir\fP will override this. + +.TP +.B DEBSNAP_BASE_URL +The base url for the snapshots archive. This is the root of a directory tree +such as \fIpool/<initial>/<package>/\fP under which a \fISources.gz\fP may be +found, and the root for the location of the packages specified in the +\fISources.gz\fP file found there. + +If unset this defaults to \fIhttp://snapshot.debian.net/archive/\fP + +.TP +.B DEBSNAP_CLEAN_REGEX +A sed regular expression to transform the directory returned by +`\fBapt\-cache showsrc\fP \fIpackage\fP \fB| grep ^Directory\fP` to a suitable +path to be put between \fBDEBSNAP_BASE_URL\fP and \fBDEBSNAP_SOURCES_GZ_PATH\fP. + +If unset it will default to s...@\e([^/]*\e)/[^/]*/\e(\&.*\e)@\e1/\e2@ +.br +i.e. it transforms \fIpool/<component>/<initial>/<package>\fP into +\fIpool/<initial>/<package>\fP + +.TP +.B DEBSNAP_SOURCES_GZ_PATH +The final path to the \fISources.gz\fP file. This is appended after the +\fBDEBSNAP_BASE_URL\fP and the path modified by \fBDEBSNAP_CLEAN_REGEX\fP to +locate the \fISources.gz\fP file for the package to download. + +If unset it will default to \fIsource/Sources.gz\fP + + +.SH EXIT STATUS +\fBdebsnap\fP will return an exit status of 0 if all operations succeeded, +1 if a fatal error occurred, and 2 if some packages failed to be downloaded +but operations otherwise succeeded as expected. In some cases packages may +fail to be downloaded because they are no longer available on the snapshot +mirror, so any caller should expect this may occur in normal use. + + +.SH FILES +.TP +.I /etc/devscripts.conf +Global devscripts configuration options. Will override hardcoded defaults. +.TP +.I ~/.devscripts +Per\-user configuration options. Will override any global configuration. + + +.SH SEE ALSO +.BR devscripts (1), +.BR devscripts.conf (5), +.BR git-debimport (1) + + +.SH AUTHORS +David Paleino <[email protected]> +.br +Ron Lee <[email protected]> + +.SH COPYRIGHT +Copyright \(co 2009 David Paleino, Ron Lee + +Permission is granted to copy, distribute and/or modify this document under +the terms of the GNU General Public License, Version 3 or (at your option) +any later version published by the Free Software Foundation. + +On Debian systems, the complete text of the GNU General Public License can +be found in \fI/usr/share/common\-licenses/GPL\fP. + + +.SH BUGS +.SS Reporting bugs +The program is part of the devscripts package. Please report bugs using +`\fBreportbug devscripts\fP` + Added: trunk/scripts/debsnap.sh =================================================================== --- trunk/scripts/debsnap.sh (rev 0) +++ trunk/scripts/debsnap.sh 2009-01-09 21:51:46 UTC (rev 1781) @@ -0,0 +1,648 @@ +#!/bin/bash + +# Copyright © 2009, David Paleino <[email protected]>, +# Ron <[email protected]> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Thanks to Ron Lee and Patrick Schoenfeld for helping during +# the development process! :) + +#set -x +set -e + +## +# Rationale for variables naming: +# DEBSNAP_FOO : means it directly comes from the config file, which can be edited by the user +# foo : means we assigned it, also combining data coming from the user +## + +OPTS=$(getopt -ao d:fvh --long destdir:,force,verbose,version,help -n $0 -- "$@") +if [ $? -ne 0 ]; then + echo "Terminating." >&2 + exit 1 +fi +eval set -- "$OPTS" + +PROGNAME="$(basename $0)" + +version() { + echo \ +"This is $PROGNAME, from the Debian devscripts package, version ###VERSION### +This code is copyright 2009 by David Paleino <[email protected]> and +Ron <[email protected]> -- all rights reserved. +This program comes with ABSOLUTELY NO WARRANTY. +You are free to redistribute this code under the terms of the GNU +General Public License v3 or, at your option, any later version." + exit 0 +} + +usage() { + cat 1>&2 <<EOF +$PROGNAME [options] <package name> [package version] + + Automatically downloads packages from snapshot.debian.net + + The following options are supported: + -h, --help Shows this help message + --version Shows information about version + -v, --verbose Be verbose + -d <destination directory>, + --destdir <destination directory> Directory for retrieved packages + Default is ./source-<package name> + -f, --force Force overwriting an existing + destdir + +EOF + exit 0 +} + +debug() { + if [ "$DEBSNAP_VERBOSE" = "yes" ]; then + echo "$@" + fi +} + +start_download() { + quiet="$1" + destdir="$2" + package="$3" + version="$4" + directory="$5" + suffix="$6" + + dsc="$DEBSNAP_BASE_URL/$directory/${package}_$version.dsc" + diff="$DEBSNAP_BASE_URL/$directory/${package}_$version.diff.gz" + orig="$DEBSNAP_BASE_URL/$directory/${package}_$upversion.$suffix" + + printf "Downloading %s... " $version + [ -n "$quiet" ] || echo + + # I don't really like dget's output with missing files :) +# ( cd sources / ; \ +# dget -d --quiet $base_url/$directory/${package}_$version.dsc ) + + # the "continue" annidated here mean "go to the next stanza of Sources.gz" + if ! wget $quiet -P "$destdir" -nH -nc "$dsc"; then + echo "missing .dsc." + debug "Url: $dsc" + return 1 + else + if ! wget $quiet -P "$destdir" -nH -nc "$orig"; then + echo "missing .$suffix." + debug "Url: $orig" + return 1 + else + if [ "$suffix" = "orig.tar.gz" ]; then + if ! wget $quiet -P "$destdir" -nH -nc "$diff"; then + echo "missing .diff.gz." + debug "Url: $diff" + return 1 + else + echo "done." + fi + else + echo "done." + fi + fi + fi +} + +# these are our defaults +DEFAULT_DEBSNAP_VERBOSE=no +DEFAULT_DEBSNAP_DESTDIR= +DEFAULT_DEBSNAP_BASE_URL=http://snapshot.debian.net/archive +DEFAULT_DEBSNAP_CLEAN_REGEX="s...@\([^/]*\)/[^/]*/\(.*\)@\1/\2@" +DEFAULT_DEBSNAP_SOURCES_GZ_PATH=source/Sources.gz +VARS="DEBSNAP_VERBOSE DEBSNAP_DESTDIR DEBSNAP_BASE_URL DEBSNAP_CLEAN_REGEX DEBSNAP_SOURCES_GZ_PATH" + +# read configuration from devscripts +eval $( + set +e + for var in $VARS; do + eval "$var=\$DEFAULT_$var" + done + [ -r "/etc/devscripts.conf" ] && . /etc/devscripts.conf + [ -r "~/.devscripts" ] && . ~/.devscripts + set | egrep "^(DEBSNAP|DEVSCRIPTS)_" +) + +# sanitize variables +case "$DEBSNAP_VERBOSE" in + yes|no) ;; + *) DEBSNAP_VERBOSE=no ;; +esac + +while true; do + case "$1" in + -v|--verbose) + DEBSNAP_VERBOSE=yes + shift + ;; + -d|--destdir) + DEBSNAP_DESTDIR="$2" + shift 2 + ;; + -f|--force) + force_overwrite=yes + shift + ;; + --version) + version + shift + ;; + -h|--help) + usage + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error in option parsing." >&2 + ;; + esac +done + +package="$1" +_version="${2//*:/}" # remove the Epoch + +if [ -z "$package" ]; then + usage +fi + +if [ "$DEBSNAP_VERBOSE" = "yes" ]; then + echo "Using these values:" + for var in $VARS; do + eval "echo $var=\$$var" + done + echo "Requested package: $package" + if [ -z "$_version" ]; then + echo "Requested version: all" + else + echo "Requested version: $_version" + fi +else + quiet="--quiet" +fi + +source_pkg=$(apt-cache showsrc $package | grep -m1 ^Package | cut -f2 -d\ ) +cache_dir=$(apt-cache showsrc $package | grep -m1 ^Directory | cut -f2 -d\ ) + +# make it pool/f/foo from pool/<section>/f/foo +clean_dir=$(echo "$cache_dir" | sed -e "$DEBSNAP_CLEAN_REGEX") + +[ -n "$DEBSNAP_DESTDIR" ] || DEBSNAP_DESTDIR="source-$source_pkg" +if [ "$DEBSNAP_DESTDIR" != "." ]; then + if [ -d "$DEBSNAP_DESTDIR" ]; then + if [ -z "$force_overwrite" ]; then + echo "Destination dir $DEBSNAP_DESTDIR already exists." + echo "Please (re)move it first, or use --force to overwrite." + exit 1 + fi + echo "Removing exiting destination dir $DEBSNAP_DESTDIR as requested." + rm -rf "$DEBSNAP_DESTDIR" + fi + mkdir -p "$DEBSNAP_DESTDIR" +fi + + +# download the Sources.gz +tmpdir=$(mktemp -d /tmp/$PROGNAME.XXXX) +trap "rm -rf \"$tmpdir\"; exit 1" 0 SIGHUP SIGINT SIGTERM +sources_url="$DEBSNAP_BASE_URL/$clean_dir/$DEBSNAP_SOURCES_GZ_PATH" +sources_path="$tmpdir/Sources.gz" + +echo -n "Downloading Sources.gz... " +[ -n "$quiet" ] || echo + +if ! wget $quiet "$sources_url" -O "$sources_path"; then + echo "failed." + debug "Url: $sources_url" + exit 1 +else + echo "done." +fi + +while read field value +do + case $field in + Package:) + if [ "$value" != "$source_pkg" ]; then + echo "Source package names not matching! Exiting." + exit 1 + fi + have_package=yes + ;; + Version:) + if [ -n "$version" ]; then + echo "Version already set. Exiting." + exit 1 + else + # remove the Epoch + version=${value//*:/} + # remove everything after a - + upversion=${version%-*} + if [ "$upversion" = "$version" ]; then + # this is a native package, so the original tarball has + # just "tar.gz" as suffix. + suffix="tar.gz" + else + # this is not a native package, use "orig.tar.gz" + suffix="orig.tar.gz" + fi + fi + ;; + Directory:) + if [ -n "$directory" ]; then + echo "Directory already set. Exiting." + exit 1 + else + directory=$value + fi + ;; + "") + # the blank line always comes last (unless it comes first) + # bail out with errors if directory and version are not set, + # (but only if we have seen a Package line already). + if [ -z "$have_package" ]; then + echo "No Package name before empty Sources.gz line. Skipping stanza." + elif [ -z "$version" ] || [ -z "$directory" ]; then + echo "Couldn't parse version/directory. Skipping stanza." + debug "Version: $version" + debug "Directory: $directory" +# exit 1 + else + # if the user requested a specific version, + # skip the download step until we find it, + # then break from the loop and let the outer + # call deal with this case for us. + if [ -z "$_version" ]; then + if ! start_download "$quiet" "$DEBSNAP_DESTDIR" \ + "$package" "$version" \ + "$directory" "$suffix"; then + # Keep trying if some files were missing, + # but report that to the caller at exit. + missing_package=yes + fi + elif [ "$_version" = "$version" ]; then + break + fi + fi + have_package= + version= + directory= + ;; + esac +done < <(zcat "$sources_path") + +# We need this if there isn't an empty line following the last (or only) stanza +# and we also perform the download here if just a single version was requested. +if [ -n "$version" ] && [ -n "$directory" ]; then + if ! start_download "$quiet" "$DEBSNAP_DESTDIR" "$package" \ + "$version" "$directory" "$suffix"; then + missing_package=yes + fi +fi + +# Disable the trap on exit so we can take back control of the exit code +trap - 0 +rm -rf "$tmpdir" + +[ -z "$missing_package" ] || exit 2 +#!/bin/bash + +# Copyright © 2009, David Paleino <[email protected]>, +# Ron <[email protected]> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Thanks to Ron Lee and Patrick Schoenfeld for helping during +# the development process! :) + +#set -x +set -e + +## +# Rationale for variables naming: +# DEBSNAP_FOO : means it directly comes from the config file, which can be edited by the user +# foo : means we assigned it, also combining data coming from the user +## + +OPTS=$(getopt -ao d:fvh --long destdir:,force,verbose,version,help -n $0 -- "$@") +if [ $? -ne 0 ]; then + echo "Terminating." >&2 + exit 1 +fi +eval set -- "$OPTS" + +PROGNAME="$(basename $0)" + +version() { + echo \ +"This is $PROGNAME, from the Debian devscripts package, version ###VERSION### +This code is copyright 2009 by David Paleino <[email protected]> and +Ron <[email protected]> -- all rights reserved. +This program comes with ABSOLUTELY NO WARRANTY. +You are free to redistribute this code under the terms of the GNU +General Public License v3 or, at your option, any later version." + exit 0 +} + +usage() { + cat 1>&2 <<EOF +$PROGNAME [options] <package name> [package version] + + Automatically downloads packages from snapshot.debian.net + + The following options are supported: + -h, --help Shows this help message + --version Shows information about version + -v, --verbose Be verbose + -d <destination directory>, + --destdir <destination directory> Directory for retrieved packages + Default is ./source-<package name> + -f, --force Force overwriting an existing + destdir + +EOF + exit 0 +} + +debug() { + if [ "$DEBSNAP_VERBOSE" = "yes" ]; then + echo "$@" + fi +} + +start_download() { + quiet="$1" + destdir="$2" + package="$3" + version="$4" + directory="$5" + suffix="$6" + + dsc="$DEBSNAP_BASE_URL/$directory/${package}_$version.dsc" + diff="$DEBSNAP_BASE_URL/$directory/${package}_$version.diff.gz" + orig="$DEBSNAP_BASE_URL/$directory/${package}_$upversion.$suffix" + + printf "Downloading %s... " $version + [ -n "$quiet" ] || echo + + # I don't really like dget's output with missing files :) +# ( cd sources / ; \ +# dget -d --quiet $base_url/$directory/${package}_$version.dsc ) + + # the "continue" annidated here mean "go to the next stanza of Sources.gz" + if ! wget $quiet -P "$destdir" -nH -nc "$dsc"; then + echo "missing .dsc." + debug "Url: $dsc" + return 1 + else + if ! wget $quiet -P "$destdir" -nH -nc "$orig"; then + echo "missing .$suffix." + debug "Url: $orig" + return 1 + else + if [ "$suffix" = "orig.tar.gz" ]; then + if ! wget $quiet -P "$destdir" -nH -nc "$diff"; then + echo "missing .diff.gz." + debug "Url: $diff" + return 1 + else + echo "done." + fi + else + echo "done." + fi + fi + fi +} + +# these are our defaults +DEFAULT_DEBSNAP_VERBOSE=no +DEFAULT_DEBSNAP_DESTDIR= +DEFAULT_DEBSNAP_BASE_URL=http://snapshot.debian.net/archive +DEFAULT_DEBSNAP_CLEAN_REGEX="s...@\([^/]*\)/[^/]*/\(.*\)@\1/\2@" +DEFAULT_DEBSNAP_SOURCES_GZ_PATH=source/Sources.gz +VARS="DEBSNAP_VERBOSE DEBSNAP_DESTDIR DEBSNAP_BASE_URL DEBSNAP_CLEAN_REGEX DEBSNAP_SOURCES_GZ_PATH" + +# read configuration from devscripts +eval $( + set +e + for var in $VARS; do + eval "$var=\$DEFAULT_$var" + done + [ -r "/etc/devscripts.conf" ] && . /etc/devscripts.conf + [ -r "~/.devscripts" ] && . ~/.devscripts + set | egrep "^(DEBSNAP|DEVSCRIPTS)_" +) + +# sanitize variables +case "$DEBSNAP_VERBOSE" in + yes|no) ;; + *) DEBSNAP_VERBOSE=no ;; +esac + +while true; do + case "$1" in + -v|--verbose) + DEBSNAP_VERBOSE=yes + shift + ;; + -d|--destdir) + DEBSNAP_DESTDIR="$2" + shift 2 + ;; + -f|--force) + force_overwrite=yes + shift + ;; + --version) + version + shift + ;; + -h|--help) + usage + shift + ;; + --) + shift + break + ;; + *) + echo "Internal error in option parsing." >&2 + ;; + esac +done + +package="$1" +_version="${2//*:/}" # remove the Epoch + +if [ -z "$package" ]; then + usage +fi + +if [ "$DEBSNAP_VERBOSE" = "yes" ]; then + echo "Using these values:" + for var in $VARS; do + eval "echo $var=\$$var" + done + echo "Requested package: $package" + if [ -z "$_version" ]; then + echo "Requested version: all" + else + echo "Requested version: $_version" + fi +else + quiet="--quiet" +fi + +source_pkg=$(apt-cache showsrc $package | grep -m1 ^Package | cut -f2 -d\ ) +cache_dir=$(apt-cache showsrc $package | grep -m1 ^Directory | cut -f2 -d\ ) + +# make it pool/f/foo from pool/<section>/f/foo +clean_dir=$(echo "$cache_dir" | sed -e "$DEBSNAP_CLEAN_REGEX") + +[ -n "$DEBSNAP_DESTDIR" ] || DEBSNAP_DESTDIR="source-$source_pkg" +if [ "$DEBSNAP_DESTDIR" != "." ]; then + if [ -d "$DEBSNAP_DESTDIR" ]; then + if [ -z "$force_overwrite" ]; then + echo "Destination dir $DEBSNAP_DESTDIR already exists." + echo "Please (re)move it first, or use --force to overwrite." + exit 1 + fi + echo "Removing exiting destination dir $DEBSNAP_DESTDIR as requested." + rm -rf "$DEBSNAP_DESTDIR" + fi + mkdir -p "$DEBSNAP_DESTDIR" +fi + + +# download the Sources.gz +tmpdir=$(mktemp -d /tmp/$PROGNAME.XXXX) +trap "rm -rf \"$tmpdir\"; exit 1" 0 SIGHUP SIGINT SIGTERM +sources_url="$DEBSNAP_BASE_URL/$clean_dir/$DEBSNAP_SOURCES_GZ_PATH" +sources_path="$tmpdir/Sources.gz" + +echo -n "Downloading Sources.gz... " +[ -n "$quiet" ] || echo + +if ! wget $quiet "$sources_url" -O "$sources_path"; then + echo "failed." + debug "Url: $sources_url" + exit 1 +else + echo "done." +fi + +while read field value +do + case $field in + Package:) + if [ "$value" != "$source_pkg" ]; then + echo "Source package names not matching! Exiting." + exit 1 + fi + have_package=yes + ;; + Version:) + if [ -n "$version" ]; then + echo "Version already set. Exiting." + exit 1 + else + # remove the Epoch + version=${value//*:/} + # remove everything after a - + upversion=${version%-*} + if [ "$upversion" = "$version" ]; then + # this is a native package, so the original tarball has + # just "tar.gz" as suffix. + suffix="tar.gz" + else + # this is not a native package, use "orig.tar.gz" + suffix="orig.tar.gz" + fi + fi + ;; + Directory:) + if [ -n "$directory" ]; then + echo "Directory already set. Exiting." + exit 1 + else + directory=$value + fi + ;; + "") + # the blank line always comes last (unless it comes first) + # bail out with errors if directory and version are not set, + # (but only if we have seen a Package line already). + if [ -z "$have_package" ]; then + echo "No Package name before empty Sources.gz line. Skipping stanza." + elif [ -z "$version" ] || [ -z "$directory" ]; then + echo "Couldn't parse version/directory. Skipping stanza." + debug "Version: $version" + debug "Directory: $directory" +# exit 1 + else + # if the user requested a specific version, + # skip the download step until we find it, + # then break from the loop and let the outer + # call deal with this case for us. + if [ -z "$_version" ]; then + if ! start_download "$quiet" "$DEBSNAP_DESTDIR" \ + "$package" "$version" \ + "$directory" "$suffix"; then + # Keep trying if some files were missing, + # but report that to the caller at exit. + missing_package=yes + fi + elif [ "$_version" = "$version" ]; then + break + fi + fi + have_package= + version= + directory= + ;; + esac +done < <(zcat "$sources_path") + +# We need this if there isn't an empty line following the last (or only) stanza +# and we also perform the download here if just a single version was requested. +if [ -n "$version" ] && [ -n "$directory" ]; then + if ! start_download "$quiet" "$DEBSNAP_DESTDIR" "$package" \ + "$version" "$directory" "$suffix"; then + missing_package=yes + fi +fi + +# Disable the trap on exit so we can take back control of the exit code +trap - 0 +rm -rf "$tmpdir" + +[ -z "$missing_package" ] || exit 2 -- To unsubscribe, send mail to [email protected].
