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