summaryrefslogtreecommitdiffstats
path: root/tools/tarsource.sh
diff options
context:
space:
mode:
authorQuentin Young <qlyoung@nvidia.com>2020-11-19 23:12:38 +0100
committerQuentin Young <qlyoung@nvidia.com>2020-11-19 23:12:38 +0100
commit2013e82a89578f150b24b03e74cdff8d7675951f (patch)
treefbbf9be2efffdc56639373412f522c86ac91ea64 /tools/tarsource.sh
parentRevert "debian: Update the tools/build-debian-package.sh to be example build ... (diff)
downloadfrr-2013e82a89578f150b24b03e74cdff8d7675951f.tar.xz
frr-2013e82a89578f150b24b03e74cdff8d7675951f.zip
Revert "debian: Remove now obsolete tarsource.sh script"
This reverts commit bc304e08ea48523b4c70d1d330eaefba3b6b7a6c.
Diffstat (limited to 'tools/tarsource.sh')
-rwxr-xr-xtools/tarsource.sh329
1 files changed, 329 insertions, 0 deletions
diff --git a/tools/tarsource.sh b/tools/tarsource.sh
new file mode 100755
index 000000000..b548fb8ac
--- /dev/null
+++ b/tools/tarsource.sh
@@ -0,0 +1,329 @@
+#!/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
+
+ 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
+ if ! $adjchangelog; then
+ dch --force-bad-version \
+ --force-distribution \
+ --preserve \
+ --newversion "$DEBVER" \
+ "autoconf changelog entry -- for git autobuilds only."
+ fi
+ cat debian/changelog >> "$tmpdir/debian/changelog"
+ DEBVER="`dpkg-parsechangelog -l\"$tmpdir/debian/changelog\" -SVersion`"
+
+ eval $debsrc | tar -cho $taropt \
+ -T - -f ../frr_${DEBVER}.debian.tar
+ # add specially prepared files from above
+ tar -uf ../frr_${DEBVER}.debian.tar $taropt -C "$tmpdir" 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
+
+ dpkg-genchanges -sa -S > ../frr_${DEBVER}_source.changes
+
+ test -n "$keyid" && debsign ../frr_${DEBVER}_source.changes -k"$keyid"
+
+ mv ../frr_${DEBVER}_source.changes "$outdir" || true
+ 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"
+
+ lsfiles="$lsfiles \
+ frr_${DEBVER}.dsc \
+ frr_${DEBVER}.debian.tar.$zip \
+ frr_${PACKAGE_VERSION}.orig.tar.$zip \
+ frr_${DEBVER}_source.changes"
+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