]> git.proxmox.com Git - mirror_frr.git/blame - tools/tarsource.sh
debian: Adjust tarsource.sh to use native debian/changelog
[mirror_frr.git] / tools / tarsource.sh
CommitLineData
2013e82a
QY
1#!/bin/bash
2# 2018 by David Lamparter, placed in the Public Domain
3
4help() {
5 cat <<EOF
6FRR tarball/dsc helper, intended to run from a git checkout
7
8Usage:
9 ./tarsource.sh [-dDn] [-i GITPATH] [-o OUTDIR] [-S KEYID]
10 [-C COMMIT] [-e EXTRAVERSION] [-z gz|xz]
11
12options:
13 -i GITPATH path to git working tree or bare repository.
14 - default: parent directory containing this script
15 -o OUTDIR path to place the generated output files in.
16 - default: current directory
17 -C COMMIT build tarball for specified git commit
18 - default: current HEAD
19 -e EXTRAVERSION override automatic package extraversion
20 - default "-YYYYMMDD-NN-gGGGGGGGGGGGG", but the script
21 autodetects if a release tag is checked out
22 -z gz|xz compression format to use
23 - default: xz
24 -S KEYID sign the output with gpg key
25 -d use dirty git tree with local changes
26 -D generate Debian .dsc and .debian.tar.xz too
27 (note: output files are moved to parent directory)
28 -l remove Debian auto-build changelog entry
29 (always done for releases)
30 -V write version information to config.version and exit
31 -n allow executing from non-git source (NOT RECOMMENDED)
32 -h show this help text
33
34Note(1) that this script tries very hard to generate a deterministic,
35reproducible tarball by eliminating timestamps and similar things. However,
36since the tarball includes autoconf/automake files, the versions of these
37tools need to be _exactly_ identical to get the same tarball.
38
39Note(2) the debian ".orig" tarball is always identical to the "plain" tarball
40generated without the -D option.
41
42Note(3) if you want the tool to identify github PRs, you need to edit your
43.git/config to fetch PRs from github like this:
44
45 [remote "origin"]
46 url = git@github.com:frrouting/frr.git
47 fetch = +refs/heads/*:refs/remotes/origin/*
48ADD: fetch = +refs/pull/*/head:refs/remotes/origin/pull/*
49EOF
50}
51
52set -e
53
54options=`getopt -o 'hi:o:C:S:e:z:DdnlV' -l help -- "$@"`
55debian=false
56dirty=false
57nongit=false
58zip=xz
59adjchangelog=false
60writeversion=false
61extraset=false
62set - $options
63while test $# -gt 0; do
64 arg="$1"; shift; optarg=$1
65 case "$arg" in
66 -h|--help) help; exit 0;;
67 -d) dirty=true;;
68 -D) debian=true;;
69 -n) nongit=true;;
70 -i) eval src=$optarg; shift;;
71 -C) eval commit=$optarg; shift;;
72 -o) eval outdir=$optarg; shift;;
73 -e) eval extraver=$optarg; extraset=true; shift;;
74 -z) eval zip=$optarg; shift;;
75 -S) eval keyid=$optarg; shift;;
76 -l) adjchangelog=true;;
77 -V) writeversion=true;;
78 --) break;;
79 *) echo something went wrong with getopt >&2
80 exit 1
81 ;;
82 esac
83done
84
85cwd="`pwd`"
86outdir="${outdir:-$cwd}"
87
88if test -e "$outdir" -a \! -d "$outdir"; then
89 echo "output $outdir must be a directory" >&2
90 exit 1
91elif test \! -d "$outdir"; then
92 mkdir -p "$outdir"
93fi
94
95cd "$outdir"
96outdir="`pwd`"
97cd "$cwd"
98cd "`dirname $0`/.."
99selfdir="`pwd`"
100src="${src:-$selfdir}"
101
102if $writeversion; then
103 if $nongit; then
104 echo "The -V option cannot be used without a git tree" >&2
105 exit 1
106 fi
107 dirty=true
108fi
109
110case "$zip" in
111gz) ziptarget=dist-gzip; ziptool="gzip -n -9"; unzip="gzip -k -c";;
112xz) ziptarget=dist-xz; ziptool="xz -z -e"; unzip="xz -d -k -c";;
113*) echo "unknown compression format $zip" >&2
114 exit 1
115esac
116
117# always overwrite file ownership in tars
118taropt="--owner=root --group=root"
119
120onexit() {
121 rv="$?"
122 set +e
123 test -n "$tmpdir" -a -d "$tmpdir" && rm -rf "$tmpdir"
124
125 if test "$rv" -ne 0; then
126 echo -e "\n\033[31;1mfailed\n" >&2
127 if test "$dirty" = true; then
128 echo please try running the script without the -d option.>&2
129 fi
130 fi
131 exit $rv
132}
133trap onexit EXIT
134tmpdir="`mktemp -d -t frrtar.XXXXXX`"
135
136if test -e "$src/.git"; then
137 commit="`git -C \"$src\" rev-parse \"${commit:-HEAD}\"`"
138
139 if $dirty; then
140 cd "$src"
141 echo -e "\033[31;1mgit: using dirty worktree in $src\033[m" >&2
142 else
143 echo -e "\033[33;1mgit: preparing a clean clone of $src\033[m"
144 branch="${tmpdir##*/}"
145 cd "$tmpdir"
146
147 git -C "$src" branch "$branch" "$commit"
148 git clone --single-branch -s -b "$branch" "$src" source
149 git -C "$src" branch -D "$branch"
150 cd source
151 fi
152
153 # if we're creating a tarball from git, force the timestamps inside
154 # the tar to match the commit date - this makes the tarball itself
155 # reproducible
156 gitts="`TZ=UTC git show -s --format=%cd --date=local $commit`"
157 gitts="`TZ=UTC date -d "$gitts" '+%Y-%m-%dT%H:%M:%SZ'`"
158 taropt="--mtime=$gitts $taropt"
159
160 # check if we're on a release tag
161 gittag="`git -C \"$src\" describe --tags --match 'frr-*' --first-parent --long $commit`"
162 gittag="${gittag%-g*}"
163 gittag="${gittag%-*}"
164
165 # if there have been changes to packaging or tests, it's still the
166 # same release
167 changes="`git diff --name-only "$gittag" $commit | \
168 egrep -v '\.git|^m4/|^config|^README|^alpine/|^debian/|^pkgsrc/|^ports/|^redhat/|^snapcraft/|^solaris/|^tests/|^tools/|^gdb/|^docker/|^\.' | \
169 wc -l`"
170 if test "$changes" -eq 0; then
171 adjchangelog=true
172 echo "detected release build for tag $gittag" >&2
173 $extraset || extraver=""
174 elif ! $adjchangelog; then
175 gitdate="`TZ=UTC date -d "$gitts" '+%Y%m%d'`"
176 gitrev="`git rev-parse --short $commit`"
177 dayseq="`git rev-list --since \"${gitts%T*} 00:00:00 +0000\" $commit | wc -l`"
178 dayseq="`printf '%02d' $(( $dayseq - 1 ))`"
179
180 $extraset || extraver="-$gitdate-$dayseq-g$gitrev"
181
182 git -C "$src" remote -v | grep fetch | sed -e 's% (fetch)$%%' \
183 | egrep -i '\b(git@github\.com:frrouting/frr\.git|https://github\.com/FRRouting/frr\.git)$' \
184 | while read remote; do
185 remote="${remote%% *}"
186
187 git -C "$src" var -l | egrep "^remote.$remote.fetch=" \
188 | while read fetch; do
189 fetch="${fetch#*=}"
190 from="${fetch%:*}"
191 to="${fetch#*:}"
192 if test "$from" = "+refs/pull/*/head"; then
193 name="`git -C \"$src\" name-rev --name-only --refs \"$to\" $commit`"
194 test "$name" = "undefined" && continue
195 realname="${name%~*}"
196 realname="${realname%%^*}"
197 realname="${realname%%@*}"
198 if test "$realname" = "$name"; then
199 echo "${name##*/}" > "$tmpdir/.gitpr"
200 break
201 fi
202 fi
203 done || true
204 test -n "$gitpr" && break
205 done || true
206 test $extraset = false -a -f "$tmpdir/.gitpr" && extraver="-PR`cat \"$tmpdir/.gitpr\"`$extraver"
207 fi
208
209 debsrc="git ls-files debian/"
210else
211 if $nongit; then
212 echo -e "\033[31;1mWARNING: this script should be executed from a git tree\033[m" >&2
213 else
214 echo -e "\033[31;1mERROR: this script should be executed from a git tree\033[m" >&2
215 exit 1
216 fi
217 debsrc="echo debian"
218fi
219
220if $writeversion; then
221 pkgver="`egrep ^AC_INIT configure.ac`"
222 pkgver="${pkgver#*,}"
223 pkgver="${pkgver%,*}"
224 pkgver="`echo $pkgver`" # strip whitespace
225 pkgver="${pkgver#[}"
226 pkgver="${pkgver%]}"
227
228 echo -e "\033[32;1mwriting version ID \033[36;1mfrr-$pkgver$extraver\033[m"
229
230 cat > config.version <<EOF
231# config.version override by tarsource.sh
232EXTRAVERSION="$extraver"
233DIST_PACKAGE_VERSION="$pkgver$extraver"
234gitts="$gitts"
235taropt="$taropt"
236EOF
25785834 237
2013e82a
QY
238 exit 0
239fi
240
241echo -e "\033[33;1mpreparing source tree\033[m"
242
243# config.version will also overwrite gitts and taropt when tarsource.sh
244# was used to write the config.version file before - but configure will
245# overwrite config.version down below!
246if test -f config.version; then
247 # never executed for clean git build
248 . ./config.version
249 if $nongit; then
250 $extraset || extraver="$EXTRAVERSION"
251 fi
252fi
253if test \! -f configure; then
254 # always executed for clean git build
255 ./bootstrap.sh
256fi
257if test "$EXTRAVERSION" != "$extraver" -o \! -f config.status; then
258 # always executed for clean git build
259 # options don't matter really - we just want to make a dist tarball
260 ./configure --with-pkg-extra-version=$extraver
261fi
262
263. ./config.version
264PACKAGE_VERSION="$DIST_PACKAGE_VERSION"
265
266echo -e "\033[33;1mpacking up \033[36;1mfrr-$PACKAGE_VERSION\033[m"
267
268make GZIP_ENV="-n9" am__tar="tar -chof - $taropt \"\$\$tardir\"" $ziptarget
269mv frr-${PACKAGE_VERSION}.tar.$zip "$outdir" || true
270lsfiles="frr-${PACKAGE_VERSION}.tar.$zip"
271
272if $debian; then
25785834
OS
273 if ! $adjchangelog; then
274 GIT_DATE=$(git log --format=format:%ad -1 --date=rfc)
275 sed -e "s/@DATE@/$GIT_DATE/" \
276 < debian/changelog-auto \
277 > "$tmpdir/debian/changelog"
2013e82a 278 fi
25785834 279 cat debian/changelog >> "$tmpdir/debian/changelog"
2013e82a
QY
280 DEBVER="`dpkg-parsechangelog -l\"$tmpdir/debian/changelog\" -SVersion`"
281
282 eval $debsrc | tar -cho $taropt \
fb0b3592
QY
283 --exclude debian/changelog \
284 --exclude debian/subdir.am \
2013e82a
QY
285 -T - -f ../frr_${DEBVER}.debian.tar
286 # add specially prepared files from above
25785834 287 tar -uf ../frr_${DEBVER}.debian.tar $taropt -C "$tmpdir" debian/changelog
2013e82a
QY
288
289 test -f ../frr_${DEBVER}.debian.tar.$zip && rm -f ../frr_${DEBVER}.debian.tar.$zip
290 $ziptool ../frr_${DEBVER}.debian.tar
291
292 # pack up debian files proper
293 ln -s "$outdir/frr-${PACKAGE_VERSION}.tar.$zip" ../frr_${PACKAGE_VERSION}.orig.tar.$zip
294 dpkg-source -l"$tmpdir/debian/changelog" \
295 --format='3.0 (custom)' --target-format='3.0 (quilt)' \
296 -b . frr_${PACKAGE_VERSION}.orig.tar.$zip frr_${DEBVER}.debian.tar.$zip
297
298 dpkg-genchanges -sa -S > ../frr_${DEBVER}_source.changes
299
300 test -n "$keyid" && debsign ../frr_${DEBVER}_source.changes -k"$keyid"
301
302 mv ../frr_${DEBVER}_source.changes "$outdir" || true
303 mv ../frr_${DEBVER}.dsc "$outdir" || true
304 mv ../frr_${DEBVER}.debian.tar.$zip "$outdir" || true
305 if test -h ../frr_${PACKAGE_VERSION}.orig.tar.$zip; then
306 rm ../frr_${PACKAGE_VERSION}.orig.tar.$zip || true
307 fi
308 ln -s frr-${PACKAGE_VERSION}.tar.$zip "$outdir/frr_${PACKAGE_VERSION}.orig.tar.$zip" || true
309
310 cd "$outdir"
311
312 lsfiles="$lsfiles \
313 frr_${DEBVER}.dsc \
314 frr_${DEBVER}.debian.tar.$zip \
315 frr_${PACKAGE_VERSION}.orig.tar.$zip \
316 frr_${DEBVER}_source.changes"
317fi
318
319cd "$outdir"
320if test -n "$keyid"; then
321 $unzip frr-${PACKAGE_VERSION}.tar.$zip > frr-${PACKAGE_VERSION}.tar
322 test -f frr-${PACKAGE_VERSION}.tar.asc && rm frr-${PACKAGE_VERSION}.tar.asc
323 if gpg -a --detach-sign -u "$keyid" frr-${PACKAGE_VERSION}.tar; then
324 lsfiles="$lsfiles frr-${PACKAGE_VERSION}.tar.asc"
325 fi
326 rm frr-${PACKAGE_VERSION}.tar
327fi
328
329echo -e "\n\033[32;1mdone: \033[36;1mfrr-$PACKAGE_VERSION\033[m\n"
330ls -l $lsfiles