-
Andre Maroneze authoredAndre Maroneze authored
build-src-distrib.sh 11.21 KiB
#! /usr/bin/env bash
set -u
# Executing this script requires bash 4.0 or higher
# (special use of the 'case' construct)
if test `echo $BASH_VERSION | sed "s/\([0-9]\).*/\1/" ` -lt 4; then
echo "bash version >= 4 is required."
exit 99
fi
# git-lfs needs to be installed
if ! command -v git-lfs >/dev/null 2>/dev/null; then
echo "git-lfs is required"
exit 99
fi
# Set it to "no" in order to really execute the commands.
# Otherwise, they are only printed.
DEBUG=no
if test \! -e .git ; then
echo "ERROR: .git directory not found"
echo "This script must be run at the root of a Frama-C repository"
exit 1
fi
FRAMAC_BRANCH=`git --git-dir=.git rev-parse --abbrev-ref HEAD`
if test \! -f VERSION ; then
echo "ERROR: VERSION file not found"
echo "This script must be run at the root of a Frama-C repository"
exit 1
fi
FRAMAC_VERSION=$(cat VERSION)
FRAMAC_TAG=$(git describe --tag)
FRAMAC_VERSION_CODENAME=$(cat VERSION_CODENAME)
FRAMAC_VERSION_AND_CODENAME="${FRAMAC_VERSION}-${FRAMAC_VERSION_CODENAME}"
TARGZ_FILENAME=frama-c-${FRAMAC_VERSION_AND_CODENAME}.tar.gz
VERSION_MODIFIER=$(cat VERSION | sed -e s/[0-9.]*\\\(.*\\\)/\\1/)
if test -n "$VERSION_MODIFIER"; then FINAL_RELEASE=no; else FINAL_RELEASE=yes; fi
if test "$FRAMAC_VERSION" != "$FRAMAC_TAG"; then
echo "WARNING: The current commit is not tagged with the current version:"
echo "Frama-C Version: $FRAMAC_VERSION"
echo "Frama-C Tag : $FRAMAC_TAG"
fi
run () {
cmd=$1
echo "$cmd"
if test "$DEBUG" == "no"; then
sh -c "$cmd" || { echo "Aborting step ${STEP}."; exit "${STEP}"; }
fi
}
GITLAB_DIR=./pub-frama-c
GITLAB_GIT="git@git.frama-c.com:pub/frama-c.git"
if test ! -d $GITLAB_DIR/.git; then
echo "WARNING: $GITLAB_DIR/.git directory not found; do you want to clone it? (y/n)"
read CHOICE
case "${CHOICE}" in
"Y"|"y")
run "git clone $GITLAB_GIT $GITLAB_DIR"
;;
*)
echo "gitlab's public Frama-C project must be linked at $GITLAB_DIR \
(clone or symbolic link)"
exit 1
;&
esac
fi
GITLAB_BRANCH=$(git --git-dir=$GITLAB_DIR/.git rev-parse --abbrev-ref HEAD)
if test "$FRAMAC_BRANCH" != "$GITLAB_BRANCH"; then
echo "WARNING: switching pub-frama-c to current branch $FRAMAC_BRANCH"
run "git -C $GITLAB_DIR checkout -b $FRAMAC_BRANCH"
fi
GITLAB_WIKI_GIT="git@git.frama-c.com:pub/frama-c.wiki"
GITLAB_WIKI=./frama-c.wiki
if test ! -d $GITLAB_WIKI/.git; then
echo "WARNING: $GITLAB_WIKI/.git directory not found; do you want to clone it? (y/n)"
read CHOICE
case "${CHOICE}" in
"Y"|"y")
run "git clone $GITLAB_WIKI_GIT"
;;
*)
echo "pub/frama-c wiki must be linked at $GITLAB_WIKI \
(clone or symbolic link)"
exit 1
;&
esac
fi
GITLAB_WIKI_BRANCH=$(git --git-dir=$GITLAB_WIKI/.git rev-parse --abbrev-ref HEAD)
if test "$GITLAB_WIKI_BRANCH" != "master"; then
echo "WARNING: pub/frama-c's wiki is not on the master branch";
fi
ACSL_GIT="git@gitlab.com:acsl-language/acsl.git"
ACSL_DIR="./doc/acsl"
if test \! -d $ACSL_DIR/.git ; then
echo "WARNING: $ACSL_DIR/.git directory not found; do you want to clone it? (y/n)"
read CHOICE
case "${CHOICE}" in
"Y"|"y")
pushd "./doc"
run "git clone $ACSL_GIT"
popd
;;
*)
echo "The Github ACSL repository must be linked at $ACSL_DIR (clone or symbolic link)"
exit 1
;&
esac
fi
MANUALS_DIR="./doc/manuals"
# push on frama-c.com only for final releases
if test "$FINAL_RELEASE" = "yes"; then
WEBSITE_DIR="./website"
if test \! -d $WEBSITE_DIR/.git ; then
echo "ERROR: $WEBSITE_DIR/.git directory not found"
echo "The Frama-C website repository must be linked at $WEBSITE_DIR (clone or symbolic link)"
exit 1
fi
WEBSITE_BRANCH=`git --git-dir=$WEBSITE_DIR/.git rev-parse --abbrev-ref HEAD`
fi # FINAL_RELEASE == yes
BUILD_DIR_ROOT="/tmp/release"
BUILD_DIR="$BUILD_DIR_ROOT/frama-c"
echo "Frama-C Version : $FRAMAC_VERSION"
echo "Frama-C Branch : $FRAMAC_BRANCH"
echo "Final release : $FINAL_RELEASE"
echo "pub/frama-c dir : $GITLAB_DIR"
echo "pub/frama-c branch : $GITLAB_BRANCH"
echo "pub/frama-c wiki : $GITLAB_WIKI"
echo "Manuals Dir : $MANUALS_DIR"
if test "$FINAL_RELEASE" = "yes"; then
echo "Website Dir : $WEBSITE_DIR"
echo "Website Branch : $WEBSITE_BRANCH"
else
echo "Intermediate release: website not updated"
fi
echo "Build Dir : $BUILD_DIR"
DOWNLOAD_DIR="www/download"
step () {
STEP=$1
echo
echo "Step $1: $2"
}
export LC_CTYPE=en_US.UTF-8
echo -n "Steps are:
N) previous information is wrong, STOP the script
0) compile PDF manuals (will ERASE $MANUALS_DIR!)
1) reset local copy of target repositories
2) build the source distribution
3) build API bundle
4) build documentation companions
5) copy and stage locally the distributed manuals
Start at which step? (default is N, which cancels everything)
- If this is the first time running this script, start at 0
- Otherwise, start at the latest step before failure
"
read STEP
case "${STEP}" in
""|"N")
echo "Exiting without doing anything.";
exit 0;
;&
0)
step 0 "COMPILING PDF MANUALS"
run "rm -rf $MANUALS_DIR"
run "mkdir -p $MANUALS_DIR"
run "doc/build-manuals.sh"
;&
1)
run "git -C $GITLAB_DIR reset --hard"
run "git -C $GITLAB_WIKI reset --hard"
if test "$FINAL_RELEASE" = "yes"; then
run "git -C $WEBSITE_DIR reset --hard"
fi
;&
2)
step 2 "BUILDING THE SOURCE DISTRIBUTION"
# WARNING! MUST RUN git update-index BEFORE git diff-index!
# See: https://stackoverflow.com/questions/36367190/git-diff-files-output-changes-after-git-status
run "git update-index --refresh"
if ! git diff-index HEAD --; then
echo ""
echo "### WARNING: uncommitted git changes will be discarded when creating archive!"
echo "Proceed anyway? [y/N]"
read CHOICE
case "${CHOICE}" in
"Y"|"y")
;;
*)
echo "Stash or commit local changes, then run the script again."
exit 1
esac
fi
run "mkdir -p $BUILD_DIR_ROOT"
run "rm -rf $BUILD_DIR"
run "git worktree add -f --detach $BUILD_DIR $FRAMAC_BRANCH"
run "cd $BUILD_DIR; autoconf"
run "cd $BUILD_DIR; ./configure"
run "cd $BUILD_DIR; make -j OPEN_SOURCE=yes src-distrib"
# sanity check: markdown-report must be distributed
run "tar tf $BUILD_DIR/$TARGZ_FILENAME | grep -q src/plugins/markdown-report"
# populate release assets in wiki
run "mkdir -p $GITLAB_WIKI/downloads"
run "cp $BUILD_DIR/$TARGZ_FILENAME $GITLAB_WIKI/downloads/"
if test "$FINAL_RELEASE" = "yes"; then
SPEC_FILE="$DOWNLOAD_DIR/$TARGZ_FILENAME"
run "rm -f $WEBSITE_DIR/$SPEC_FILE"
run "cp $BUILD_DIR/$TARGZ_FILENAME $WEBSITE_DIR/$SPEC_FILE"
run "git -C $WEBSITE_DIR add $SPEC_FILE"
run "cp Changelog $WEBSITE_DIR/src/last-release/Changelog"
run "cp src/plugins/wp/Changelog $WEBSITE_DIR/src/wpChangelog"
run "cp src/plugins/wp/Changelog $WEBSITE_DIR/src/last-release/wpChangelog"
run "cp src/plugins/e-acsl/doc/Changelog $WEBSITE_DIR/src/eacslChangelog"
run "cp src/plugins/e-acsl/doc/Changelog $WEBSITE_DIR/src/last-release/eacslChangelog"
fi
;&
3)
#note: this step may fail if step 4 was performed,
# because it will erase BUILD_DIR
step 3 "BUILDING THE API BUNDLE"
if test \! -d "$BUILD_DIR" ; then
echo "ERROR: $BUILD_DIR does not exist, possibly removed by another step"
exit 1
fi
run "cd $BUILD_DIR; make -j doc-distrib"
if test "$FINAL_RELEASE" = "yes"; then
SPEC_FILE="$DOWNLOAD_DIR/frama-c-${FRAMAC_VERSION_AND_CODENAME}-api.tar.gz"
run "rm -f $WEBSITE_DIR/$SPEC_FILE"
run "cp $BUILD_DIR/frama-c-api.tar.gz $WEBSITE_DIR/$SPEC_FILE"
run "git -C $WEBSITE_DIR add $SPEC_FILE"
fi
;&
4)
step 4 "BUILDING THE DOCUMENTATION COMPANIONS"
if test \! -d "$BUILD_DIR" ; then
echo "ERROR: $BUILD_DIR does not exist, possibly removed by another step"
exit 1
fi
run "cd $BUILD_DIR; make -j doc-companions"
if test "$FINAL_RELEASE" = "yes"; then
SPEC_FILE="$DOWNLOAD_DIR/hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz"
RELE_FILE="$DOWNLOAD_DIR/hello.tar.gz"
run "rm -f $WEBSITE_DIR/$SPEC_FILE $WEBSITE_DIR/$RELE_FILE"
run "cp $BUILD_DIR/hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz $WEBSITE_DIR/$SPEC_FILE"
run "git -C $WEBSITE_DIR add $SPEC_FILE"
run "ln -s hello-${FRAMAC_VERSION_AND_CODENAME}.tar.gz $WEBSITE_DIR/$RELE_FILE";
run "git -C $WEBSITE_DIR add $RELE_FILE"
run "rm -rf $BUILD_DIR"
run "git worktree prune"
fi
;&
5)
step 5 "COPYING AND STAGING THE DISTRIBUTED MANUALS"
PAGE_NAME=Frama-C-${FRAMAC_VERSION_AND_CODENAME}.md
WIKI_PAGE=$GITLAB_WIKI/$PAGE_NAME
run "mkdir -p $GITLAB_WIKI/manuals"
run "sed -i -e '/<!-- LAST RELEASE -->/a \
- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $GITLAB_WIKI/Home.md"
if test "$FINAL_RELEASE" = "yes"; then
release_type="FINAL"
else
release_type="BETA"
fi
run "sed -i -e '/<!-- LAST ${release_type} RELEASE -->/a \
- [${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})](Frama-C-${FRAMAC_VERSION_AND_CODENAME})' $GITLAB_WIKI/_sidebar.md"
echo "# Frama-C release ${FRAMAC_VERSION} (${FRAMAC_VERSION_CODENAME})" > $WIKI_PAGE
echo "## Sources" >> $WIKI_PAGE
echo " - [$TARGZ_FILENAME](downloads/$TARGZ_FILENAME)" >> $WIKI_PAGE
echo "" >> $WIKI_PAGE
echo "## Manuals" >> $WIKI_PAGE
for fpath in $MANUALS_DIR/*; do
f=$(basename $fpath)
f_no_ext=${f%.*}
# E-ACSL-related files are stored in subdirectory e-acsl
if [[ $f_no_ext =~ ^e-acsl.*$ ]]; then
destdir="$WEBSITE_DIR/$DOWNLOAD_DIR/e-acsl"
else
destdir="$WEBSITE_DIR/$DOWNLOAD_DIR"
fi
if [[ -L $fpath ]]; then
# symbolic links are copied to the website and prepended with 'frama-c-'
# (except for acsl.pdf, which is copied as is)
if [[ $f_no_ext =~ ^(e-)?acsl$ ]]; then
ln="$f"
else
ln="frama-c-$f"
fi
run "rm -f $destdir/$ln"
run "cp -P $fpath $destdir/$ln"
run "git -C $destdir add $ln"
else
# non-symbolic links are copied as-is to the website, and also to
# the Gitlab wiki, where they are also added as links
f_no_pdf_ext="${f%.pdf}"
echo "- [${f_no_pdf_ext%-${FRAMAC_VERSION_AND_CODENAME}}](manuals/$f)" >> $WIKI_PAGE
run "cp $fpath $GITLAB_WIKI/manuals/"
run "git -C $GITLAB_WIKI add manuals/$f"
run "cp $fpath $destdir/$f"
run "git -C $destdir add $f"
fi
done
run "git -C $GITLAB_WIKI add $PAGE_NAME"
;;
*)
echo "Bad entry: ${STEP}"
echo "Exiting without doing anything.";
exit 31
;;
esac
exit 0