1#!/bin/bash
2
3# cvs-debrelease: Call dupload/dput to upload package built with
4#                 cvs-buildpackage or cvs-debuild
5#
6# Based on debrelease; see it for copyright information
7# Based on cvs-buildpackage, copyright 1997 Manoj Srivastava
8# (CVS Id: cvs-buildpackage,v 1.58 2003/08/22 17:24:29 srivasta Exp)
9# This code is copyright 2003, Julian Gilbey <jdg@debian.org>
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <https://www.gnu.org/licenses/>.
23
24set -e
25
26PROGNAME=`basename $0 .sh`  # .sh for debugging purposes
27
28usage () {
29    echo \
30"Usage: $PROGNAME [cvs-debrelease options] [--dopts [dupload/dput options]]
31  Upload the .changes file(s) just created by cvs-buildpackage or
32  cvs-debuild, as listed in the .changes file generated on that run.
33
34  Note that unlike cvs-buildpackage, the only way to specify the
35  source package name is with the -P option; you cannot simply have it
36  as the last parameter.
37
38  Also uses the cvs-buildpackage configuration files to determine the
39  location of the build tree, as described in its manpage.
40
41  Available cvs-debrelease options:
42    -M<module>        CVS module name
43    -P<package>       Package name
44    -V<version>       Package version
45    -T<tag>           CVS tag to use
46    -R<root dir>      Root directory
47    -W<work dir>      Working directory
48    -x<prefix>        CVS default module prefix
49    -a<arch>          Search for .changes file made for Debian build <arch>
50    -t<target>        Search for .changes file made for GNU <target> arch
51    --dupload         Use dupload to upload files (default)
52    --dput            Use dput to upload files
53    --no-conf, --noconf
54                      Don't read devscripts config files;
55                      must be the first option given
56    --dopts           The remaining options are for dupload/dput
57    --help            Show this message
58    --version         Show version and copyright information
59  Other cvs-buildpackage options will be silently ignored.
60
61Default settings modified by devscripts configuration files:
62  (no configuration files are read by $PROGNAME)
63For information on default debrelease settings modified by the
64configuration files, run:  debrelease --help"
65}
66
67
68version () { echo \
69"This is $PROGNAME, from the Debian devscripts package, version ###VERSION###
70This code is copyright 2003, Julian Gilbey <jdg@debian.org>,
71all rights reserved.
72Based on original code by Christoph Lameter and Manoj Srivastava.
73This program comes with ABSOLUTELY NO WARRANTY.
74You are free to redistribute this code under the terms of
75the GNU General Public License, version 2 or later."
76}
77
78setq() {
79    # Variable Value Doc string
80    if [ "x$2" = "x" ]; then
81	echo >&2 "$progname: Unable to determine $3"
82	exit 1;
83    else
84	if [ ! "x$Verbose" = "x" ]; then
85	    echo "$progname: $3 is $2";
86	fi
87	eval "$1=\"\$2\"";
88    fi
89}
90
91# Is cvs-buildpackage installed?
92if ! command -v cvs-buildpackage >/dev/null 2>&1; then
93    echo "$PROGNAME: need the cvs-buildpackage package installed to run this" >&2
94    exit 1
95fi
96
97# Long term variables, which may be set in the cvsdeb config file or the
98# environment:
99# rootdir workdir (if all original sources are kept in one dir)
100
101TEMPDIR=$(mktemp -dt cvs-debrelease.XXXXXXXX) || {
102    echo "$PROGNAME: Unable to create temporary directory" >&2
103    echo "Aborting...." >&2
104    exit 1
105}
106TEMPFILE=$TEMPDIR/cl-tmp
107trap 'rm -f "$TEMPFILE"; rmdir "$TEMPDIR"' EXIT
108
109TAGOPT=
110
111# Command line
112# Start by pulling off all options up to --dopts
113declare -a cvsopts debreleaseopts
114if [ "$1" = --no-conf -o "$1" = --noconf ]; then
115    debreleaseopts=("$1")
116    shift
117fi
118
119debreleaseopts=("${debreleaseopts[@]}" "--check-dirname-level=0")
120
121while [ $# -gt 0 ]; do
122    if [ "$1" = "--dopts" ]; then
123	shift
124	break
125    fi
126    cvsopts=("${cvsopts[@]}" "$1")
127    shift
128done
129
130# This will bomb out if there is an unrecognised option
131TEMP=$(getopt -a -s bash \
132       -o hC:EH:G:M:P:R:T:U:V:W:Ff:dcnr:x:Bp:Dk:a:Sv:m:e:i:I:t: \
133       --long help,version,ctp,tC,sgpg,spgp,us,uc,op \
134       --long si,sa,sd,ap,sp,su,sk,sr,sA,sP,sU,sK,sR,ss,sn \
135       --long dupload,dput,no-conf,noconf \
136       --long check-dirname-level:,check-dirname-regex: \
137       -n "$PROGNAME" -- "${cvsopts[@]}")
138
139eval set -- $TEMP
140
141while true ; do
142    case "$1" in
143        -h|--help)   usage;   exit 0  ; shift   ;;
144        --version)   version; exit 0  ; shift   ;;
145	-M) opt_cvsmodule="$2"        ; shift 2 ;;
146	-P) opt_package="$2"          ; shift 2 ;;
147	-R) opt_rootdir="$2"          ; shift 2 ;;
148	-T) opt_tag="$2"              ; shift 2 ;;
149	-V) opt_version="$2"          ; shift 2 ;;
150	-W) opt_workdir="$2"          ; shift 2 ;;
151	-x) opt_prefix="$2"           ; shift 2 ;;
152        -a) debreleaseopts=("${debreleaseopts[@]}" "$1" "$2")
153	    targetarch="$2"           ; shift 2 ;;
154        -t) if [ "$2" != "C" ]; then
155	        debreleaseopts=("${debreleaseopts[@]}" "$1" "$2")
156		targetgnusystem="$2"
157	    fi
158	    shift 2 ;;
159	--dupload|--dput)
160	    debreleaseopts=("${debreleaseopts[@]}" "$1");  shift ;;
161	--no-conf|--noconf)
162	    echo "$PROGNAME: $1 is only acceptable as the first command-line option!" >&2
163	    exit 1 ;;
164	--check-dirname-level|--check-dirname-regex)
165	    debreleaseopts=("${debreleaseopts[@]}" "$1" "$2");  shift 2 ;;
166
167	# everything else is silently ignored
168	-[CHfGUr])                      shift 2 ;;
169	-[FnE])                         shift   ;;
170       --ctp|--op|--tC)                 shift   ;;
171	-[dDBbS])                       shift   ;;
172        -p)                             shift 2 ;;
173       --us|--uc|--sgpg|--spgp)         shift   ;;
174       --s[idapukrAPUKRns])             shift   ;;
175       --ap)                            shift   ;;
176        -[kvmeiI])                      shift 2 ;;
177
178        --) shift ; break ;;
179         *) echo >&2 "Internal error! ($1)"
180            usage; exit 1 ;;
181    esac
182done
183
184if [ "x$opt_cvsmodule" = "x" -a "x$opt_package" = "x" -a \
185      ! -e 'debian/changelog' ] ; then
186    echo >&2 "$progname should be run in the top working directory of"
187    echo >&2 "a Debian Package, or an explicit package (or CVS module) name"
188    echo >&2 "should be given."
189    exit 1
190fi
191
192if [ "x$opt_tag" != "x" ]; then
193    TAGOPT=-r$opt_tag
194fi
195
196# Command line, env variable, config file, or default
197# This anomalous position is in case we need to check out the changelog
198# below (anomalous since we have not loaded the config file yet)
199if [ ! "x$opt_prefix" = "x" ]; then
200    prefix="$opt_prefix"
201elif [ ! "x$CVSDEB_PREFIX" = "x" ]; then
202    prefix="$CVSDEB_PREFIX"
203elif [ ! "x$conf_prefix" = "x" ]; then
204    prefix="$conf_prefix"
205else
206    prefix=""
207fi
208
209# put a slash at the end of the prefix
210if [ "X$prefix" != "X" ]; then
211    prefix="$prefix/";
212    prefix=`echo $prefix | sed 's://:/:g'`;
213fi
214
215if [ ! -f CVS/Root ]; then
216    if [ "X$CVSROOT" = "X" ]; then
217	echo "no CVS/Root file found, and CVSROOT var is empty" >&2
218	exit 1
219    fi
220else
221    CVSROOT=$(cat CVS/Root)
222    export CVSROOT
223fi
224
225if [ "x$opt_package" = "x" ]; then
226    # Get the official package name and version.
227    if [ -f debian/changelog ]; then
228	# Ok, changelog exists
229	 setq "package" \
230	    "`dpkg-parsechangelog -SSource`" \
231		"source package"
232	setq "version" \
233	    "`dpkg-parsechangelog -SVersion`" \
234		"source version"
235    elif [ "x$opt_cvsmodule" != "x" ]; then
236	# Hmm. Well, see if we can checkout the changelog file
237	rm -f $TEMPFILE
238	cvs -q co -p $TAGOPT $opt_cvsmodule/debian/changelog > $TEMPFILE
239        setq "package" \
240	    "`dpkg-parsechangelog -l$TEMPFILE -SSource`" \
241          "source package"
242        setq "version" \
243          "`dpkg-parsechangelog -l$TEMPFILE -SVersion`" \
244          "source version"
245        rm -f "$TEMPFILE"
246    else
247	# Well. We don't know what this package is.
248	echo >&2 " This does not appear be a Debian source tree, since"
249	echo >&2 " there is no debian/changelog, and there was no"
250	echo >&2 " package name or cvs module given on the command line"
251	echo >&2 " it is hard to figure out what the package name "
252	echo >&2 " should be. I give up."
253	exit 1
254    fi
255else
256    # The user knows best; package name is provided
257    setq "package" "$opt_package" "source package"
258
259    # Now, the version number
260    if [ "x$opt_version" != "x" ]; then
261	# All hail the user provided value
262	setq "version" "$opt_version" "source package"
263    elif [ -f debian/changelog ]; then
264	# Fine, see what the changelog says
265	setq "version" \
266	    "`dpkg-parsechangelog -SVersion`" \
267		"source version"
268    elif [ "x$opt_cvsmodule" != "x" ]; then
269	# Hmm. The CVS module name is known, so lets us try exporting changelog
270	rm -f $TEMPFILE
271	cvs -q co -p $TAGOPT $opt_cvsmodule/debian/changelog > $TEMPFILE
272        setq "version" \
273          "`dpkg-parsechangelog -l$TEMPFILE -SVersion`" \
274          "source version"
275        rm -f "$TEMPFILE"
276    else
277	# Ok, try exporting the package name
278	rm -f $TEMPFILE
279	cvsmodule="${prefix}$package"
280	cvs -q co -p $TAGOPT $cvsmodule/debian/changelog > $TEMPFILE
281        setq "version" \
282          "`dpkg-parsechangelog -l$TEMPFILE -SVersion`" \
283          "source version"
284        rm -f "$TEMPFILE"
285    fi
286fi
287
288rm -f $TEMPFILE
289rmdir $TEMPDIR
290trap "" 0 1 2 3 7 10 13 15
291
292
293non_epoch_version=$(echo -n "$version" | perl -pe 's/^\d+://')
294upstream_version=$(echo -n "$non_epoch_version" | sed  -e 's/-[^-]*$//')
295debian_version=$(echo -n $non_epoch_version |  perl -nle 'm/-([^-]*)$/ && print $1')
296
297# The default
298if [ "X$opt_rootdir" != "X" ]; then
299    rootdir="$opt_rootdir"
300else
301    rootdir='/usr/local/src/Packages'
302fi
303
304if [ "X$opt_workdir" != "X" ]; then
305    workdir="$opt_workdir"
306else
307    workdir="$rootdir/$package"
308fi
309
310# Load site defaults and over rides.
311if [ -f /etc/cvsdeb.conf ]; then
312    . /etc/cvsdeb.conf
313fi
314
315# Load user defaults and over rides.
316if [ -f ~/.cvsdeb.conf ]; then
317    . ~/.cvsdeb.conf
318fi
319
320# Command line, env variable, config file, or default
321if [ ! "x$opt_rootdir" = "x" ]; then
322    rootdir="$opt_rootdir"
323elif [ ! "x$CVSDEB_ROOTDIR" = "x" ]; then
324    rootdir="$CVSDEB_ROOTDIR"
325elif [ ! "x$conf_rootdir" = "x" ]; then
326    rootdir="$conf_rootdir"
327fi
328
329# Command line, env variable, config file, or default
330if [ ! "x$opt_workdir" = "x" ]; then
331    workdir="$opt_workdir"
332elif [ ! "x$CVSDEB_WORKDIR" = "x" ]; then
333    workdir="$CVSDEB_WORKDIR"
334elif [ ! "x$conf_workdir" = "x" ]; then
335    workdir="$conf_workdir"
336else
337    workdir="$rootdir/$package"
338fi
339
340if [ ! -d "$workdir" ]; then
341    echo >&2 "The working directory, $workdir, does not exist. Aborting"
342    if [ ! -d "$rootdir" ]; then
343	echo >&2 "The root directory, $rootdir, does not exist either."
344    fi
345    exit 1;
346fi
347
348pkgdir="$workdir/$package-$upstream_version"
349
350if [ ! -d "$pkgdir" ]; then
351    echo "The build directory $pkgdir does not exist!" >&2
352    echo "Have you built the package yet?" >&2
353    exit 1
354fi
355
356if [ -n "$targetarch" ] && [ -n "$targetgnusystem" ]; then
357    setq arch "$(dpkg-architecture "-a${targetarch}" "-t${targetgnusystem}" -qDEB_HOST_ARCH)" "build architecture"
358elif [ -n "$targetarch" ]; then
359    setq arch "$(dpkg-architecture "-a${targetarch}" -qDEB_HOST_ARCH)" "build architecture"
360elif [ -n "$targetgnusystem" ]; then
361    setq arch "$(dpkg-architecture "-t${targetgnusystem}" -qDEB_HOST_ARCH)" "build architecture"
362else
363    setq arch "$(dpkg-architecture -qDEB_HOST_ARCH)" "build architecture"
364fi
365
366pva="${package}_${non_epoch_version}_${arch}"
367changes="$pva.changes"
368
369if [ ! -f "$workdir/$changes" ]; then
370    echo "Can't find $workdir/$changes!" >&2
371    echo "Have you built the package yet?" >&2
372    exit 1
373fi
374
375
376cd $pkgdir || {
377    echo "Couldn't cd $pkgdir.  Aborting" >&2
378    exit 1
379}
380
381# Just call debrelease, now that we are in the correct directory
382
383SUBPROG=${PROGNAME#cvs-}
384
385exec $SUBPROG "${debreleaseopts[@]}" "$@"
386