blob: 874f238b869efb4e064c63d94f6b77c2889eca8a [file] [log] [blame]
#!/bin/bash
svnfetch() {
REV="${3:-HEAD}"
echo "Fetching from ${1} to ${2} at revision ${REV}"
cd $SRC_DIR
if ! [ -f "${2}/.svn/entries" ]; then
mkdir "${2}"
cd "${2}"
svn co --non-interactive --trust-server-cert "${1}" -r "${REV}" "."
else
cd "${2}"
svn cleanup
svn up -r "${REV}"
fi
}
gitfetch() {
echo "Fetching ${2} branch/commit from ${1} to ${3} via git"
cd $SRC_DIR
if ! [ -f "${3}/.git/config" ]; then
git clone "${1}" "${3}"
cd "${3}"
git checkout "${2}"
else
cd "${3}"
git fetch
git checkout "${2}"
fi
if [ $? -ne 0 ]; then
exit
fi
}
hgfetch() {
(
echo "Fetching ${2} branch from ${1} to ${3} via mercurial"
cd src
if [ -e "${2}/.hg" ] ; then
cd ${2}
hg pull
else
hg clone "${1}" "${2}"
fi
hg up -r ${3}
)
if [ $? -ne 0 ]; then
exit
fi
}
testsmackgit() {
cd $SRC_DIR
if [ -f .used-smack-git-repo ] && [ $(cat .used-smack-git-repo) != $SMACK_REPO ] ; then
echo "Used smack repository has changed!"
echo "Old: $(cat .used-smack-git-repo) New: ${SMACK_REPO}."
echo "Deleting old local copy"
rm -rf smack
fi
echo "${SMACK_REPO}" > .used-smack-git-repo
}
fetchall() {
echo "## Step 15: fetching sources"
if $SMACK_LOCAL ; then
# always clean the local copy first
rm -rf ${SRC_DIR}/smack
mkdir ${SRC_DIR}/smack
cd $SMACK_REPO
git archive $SMACK_BRANCH | tar -x -C ${SRC_DIR}/smack
if [ $? -ne 0 ]; then
exit
fi
else
execute gitfetch "$SMACK_REPO" "$SMACK_BRANCH" "smack"
fi
if ! $UPDATE_REMOTE ; then
echo "Won't update or fetch third party resources"
wait
return
fi
execute svnfetch "http://svn.apache.org/repos/asf/qpid/trunk/qpid/java/management/common/src/main/" "qpid"
execute svnfetch "http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/auth/src/main/java/common/" "harmony"
execute svnfetch "https://dnsjava.svn.sourceforge.net/svnroot/dnsjava/trunk" "dnsjava"
execute gitfetch "git://kenai.com/jbosh~origin" "master" "jbosh"
# jldap doesn't compile with the latest version (missing deps?), therefore it's a fixed version for now
# execute gitfetch "git://git.openldap.org/openldap-jldap.git" "master" "novell-openldap-jldap"
wait
}
createVersionTag() {
# Skip this step is no version tag is given
[[ -z $VERSION_TAG ]] && return
local v
cat <<EOF > $TAG_FILE
#!/bin/bash
# This file contains the version information of the components that
# were used to build this aSmack version
declare -g -A COMPONENT_VERSIONS
EOF
for d in $(ls $SRC_DIR) ; do
cd $SRC_DIR
# Don't record the components version for static-src
for static in $(ls ${ASMACK_BASE}/static-src) ; do
# Don't record the version if it's from the static sources
[ $d == $static ] && continue
done
if [[ -d $d/.git ]] ; then
v=$(cd $d && git rev-parse HEAD)
key=$d
COMPONENT_VERSIONS["$d"]=$v
elif [[ -d $d/.svn ]] ; then
v=$(cd $d && svn info |grep Revision |cut -f 2 -d ' ')
key=$d
COMPONENT_VERSIONS["$d"]=$v
fi
done
if $SMACK_LOCAL ; then
cd $SMACK_REPO
v=$(git rev-parse HEAD)
COMPONENT_VERSIONS[smack]=$v
fi
cd ${ASMACK_BASE}
v=$(git rev-parse HEAD)
COMPONENT_VERSIONS[asmack]=$v
for i in "${!COMPONENT_VERSIONS[@]}" ; do
echo "COMPONENT_VERSIONS[$i]=${COMPONENT_VERSIONS[$i]}" >> $TAG_FILE
done
}
copyfolder() {
cd ${ASMACK_BASE}
(
cd "${1}"
tar -cSsp --exclude-vcs "${3}"
) | (
cd "${2}"
tar -xSsp
)
wait
}
createbuildsrc() {
echo "## Step 20: creating build/src"
cd "${ASMACK_BASE}"
rm -rf build/src
mkdir -p build/src/trunk
execute copyfolder "src/smack/source/" "build/src/trunk" "."
execute copyfolder "src/qpid/java" "build/src/trunk" "org/apache/qpid/management/common/sasl"
execute copyfolder "src/novell-openldap-jldap" "build/src/trunk" "."
execute copyfolder "src/dnsjava" "build/src/trunk" "org"
execute copyfolder "src/harmony" "build/src/trunk" "."
execute copyfolder "src/jbosh/src/main/java" "build/src/trunk" "."
if $BUILD_JINGLE ; then
execute copyfolder "src/smack/jingle/extension/source/" "build/src/trunk" "."
fi
wait
# custom overwrites some files from smack, so this has to be done as last
copyfolder "src/custom" "build/src/trunk" "."
}
patchsrc() {
echo "## Step 25: patch build/src"
cd ${ASMACK_BASE}/build/src/trunk/
for PATCH in `(cd "../../../${1}" ; find -maxdepth 1 -type f)|sort` ; do
echo $PATCH
if [[ $PATCH == *.sh ]]; then
"../../../${1}/$PATCH" || exit 1
elif [[ $PATCH == *.patch ]]; then
patch -p0 < "../../../${1}/$PATCH" || exit 1
fi
done
}
build() {
echo "## Step 30: compile"
buildandroid
if [ $? -ne 0 ]; then
exit 1
fi
}
buildandroid() {
local sdklocation
local version
local sdks
local minSdkVer=8
cd $ASMACK_BASE
if [ ! -f local.properties ] ; then
echo "Could not find local.properties file"
echo "See local.properties.example"
exit 1
fi
sdklocation=$(grep sdk-location local.properties| cut -d= -f2)
if [ -z "$sdklocation" ] ; then
echo "Android SDK not found. Don't build android version"
exit 1
fi
for f in ${sdklocation/\$\{user.home\}/$HOME}/platforms/* ; do
version=`basename $f`
if [[ "$version" != android-* ]] ; then
echo "$sdklocation contains no Android SDKs"
exit 1
fi
if [[ ${version#android-} -ge $minSdkVer ]] ; then
if [ -n $BUILD_ANDROID_VERSIONS ] ; then
for build_version in $BUILD_ANDROID_VERSIONS ; do
[ ${version#android-} != $build_version ] && continue 2
done
fi
echo "Building for ${version}"
sdks="${sdks} ${version}\n"
fi
done
if [ -z "${sdks}" ] ; then
echo "No SDKs of a suitable minimal API (${minSdkVer}) version found"
exit 1
fi
local asmack_suffix
if [[ -n ${VERSION_TAG} ]] && [[ -n ${1} ]] ; then
asmack_suffix="${1}-${VERSION_TAG}"
elif [[ -n ${VERSION_TAG} ]] ; then
asmack_suffix="-${VERSION_TAG}"
else
asmack_suffix="${1}"
fi
if ! echo -e ${sdks} \
| xargs -I{} -n 1 $XARGS_ARGS ant \
-Dandroid.version={} \
-Djar.suffix="${asmack_suffix}" \
compile-android ; then
exit 1
fi
}
buildcustom() {
for dir in `find patch -maxdepth 1 -mindepth 1 -type d`; do
buildsrc
patchsrc "patch"
if $BUILD_JINGLE ; then
patchsrc "jingle"
JINGLE_ARGS="-Djingle=lib/jstun.jar"
fi
patchsrc "${dir}"
local custom
custom=$(echo ${dir} | sed 's:patch/:-:')
ant -Djar.suffix="${custom}" $JINGLE_ARGS
buildandroid "${custom}"
done
}
parseopts() {
while getopts a:b:r:t:cdhjpux OPTION "$@"; do
case $OPTION in
a)
BUILD_ANDROID_VERSIONS="${OPTARG}"
;;
r)
SMACK_REPO="${OPTARG}"
;;
b)
SMACK_BRANCH="${OPTARG}"
;;
d)
set -x
XARGS_ARGS="-t"
;;
j)
BUILD_JINGLE=true
;;
u)
UPDATE_REMOTE=false
;;
c)
BUILD_CUSTOM=true
;;
p)
PARALLEL_BUILD=true
;;
t)
VERSION_TAG="${OPTARG}"
;;
x)
PUBLISH_RELEASE=true
;;
h)
echo "$0 -d -c -u -j -r <repo> -b <branch>"
echo "-d: Enable debug"
echo "-j: Build jingle code"
echo "-c: Apply custom patchs from patch directory"
echo "-u: DON'T update remote third party resources"
echo "-r <repo>: Git repository (can be local or remote) for underlying smack repository"
echo "-b <branch>: Git branch used to build aSmack from underlying smack repository"
echo "-p use parallel build where possible"
echo "-t <version>: Create a new version tag. You should build aSmack before calling this"
echo "-x: Publish the release"
echo "-a <SDK Version(s)>: Build only for the given Android SDK versions"
exit
;;
esac
done
}
prepareRelease() {
if [[ -z ${VERSION_TAG} ]]; then
echo "Version tag is not set. Not going to prepare a release"
return
fi
if [ -d $RELEASE_DIR ] ; then
rm -rf $RELEASE_DIR
fi
mkdir -p $RELEASE_DIR
mv ${ASMACK_BASE}/build/*.{jar,zip} ${RELEASE_DIR}/
cp $TAG_FILE ${RELEASE_DIR}/
cp ${ASMACK_BASE}/CHANGELOG ${RELEASE_DIR}
if [ -n $GPG_KEY ] ; then
find $RELEASE_DIR -maxdepth 1 -and \( -name '*.jar' -or -name '*.zip' \) -print0 \
| xargs -n 1 -0 $XARGS_ARGS gpg --local-user $GPG_KEY --detach-sign
fi
find $RELEASE_DIR -maxdepth 1 -and \( -name '*.jar' -or -name '*.zip' \) -print0 \
| xargs -I{} -n 1 -0 $XARGS_ARGS sh -c 'md5sum {} > {}.md5'
local release_readme
release_readme=${RELEASE_DIR}/README
sed \
-e "s/\$VERSION_TAG/${VERSION_TAG}/" \
-e "s/\$BUILD_DATE/${BUILD_DATE}/" \
README.asmack > $release_readme
# Pretty print the component versions at the end of README
# Note that there is an exclamation mark at the beginning of the
# associative array to access the keys
for i in "${!COMPONENT_VERSIONS[@]}" ; do
local tabs
if [[ ${#i} -le 6 ]] ; then
tabs="\t\t"
else
tabs="\t"
fi
echo -e "${i}:${tabs}${COMPONENT_VERSIONS[$i]}" >> $release_readme
done
}
publishRelease() {
if [[ -z ${VERSION_TAG} ]]; then
echo "Version tag is not set. Not going to prepare a release"
return
fi
if [[ -z ${PUBLISH_RELEASE} ]]; then
echo "User doesn't want to publish this release"
return
fi
if [[ -z $PUBLISH_HOST || -z $PUBLISH_DIR ]]; then
echo "WARNING: Not going to publish this release as either $PUBLISH_HOST or $PUBLISH_DIR is not set"
return
fi
cd ${ASMACK_RELEASES}
cat <<EOF | sftp $PUBLISH_HOST
rm ${PUBLISH_DIR}/${VERSION_TAG}/*
mkdir ${PUBLISH_DIR}/${VERSION_TAG}
put -r $VERSION_TAG $PUBLISH_DIR
EOF
}
islocalrepo() {
local R="^(git|ssh)"
if [[ $1 =~ $R ]]; then
return 1
else
return 0
fi
}
initialize() {
echo "## Step 00: initialize"
if ! [ -d build/src/trunk ]; then
mkdir -p build/src/trunk
fi
if [ ! -d src/ ]; then
mkdir src
fi
find build \( -name '*.jar' -or -name '*.zip' \) -print0 | xargs -0 rm -f
rm -rf src/custom
}
cleanup() {
echo "## Deleting all temporary files"
rm -rf build
rm -rf src
}
copystaticsrc() {
cp -ur static-src/* src/
}
cmdExists() {
command -v $1 &> /dev/null
return $?
}
prettyPrintSeconds() {
local ttime
if (( $1 > 59 )); then
ttime=$(printf "%dm %ds\n" $(($1/60%60)) $(($1%60)) )
else
ttime=$(printf "%ds\n" $(($1)) )
fi
echo "Execution took $ttime"
}
execute() {
if [ -n "$BACKGROUND" ]; then
"$@" &
else
"$@"
fi
}
setdefaults() {
# Default configuration, can be changed with script arguments
SMACK_REPO=git://github.com/Flowdalic/smack.git
SMACK_BRANCH=master
SMACK_LOCAL=false
UPDATE_REMOTE=true
BUILD_CUSTOM=false
BUILD_JINGLE=false
JINGLE_ARGS=""
PARALLEL_BUILD=false
VERSION_TAG=""
PUBLISH_RELEASE=""
PUBLISH_HOST=""
PUBLISH_DIR=""
BUILD_ANDROID_VERSIONS=""
# Often used variables
ASMACK_BASE=$(pwd)
ASMACK_RELEASES=${ASMACK_BASE}/releases
SRC_DIR=${ASMACK_BASE}/src
VERSION_TAG_DIR=${ASMACK_BASE}/version-tags
STARTTIME=$(date -u "+%s")
BUILD_DATE=$(date)
# Declare an associative array that is in global scope ('-g')
declare -g -A COMPONENT_VERSIONS
}
parseconfig() {
if [ -f ${ASMACK_BASE}/config ]; then
source ${ASMACK_BASE}/config
fi
}
setconfig() {
if [ ${PARALLEL_BUILD} == "true" ]; then
XARGS_ARGS="${XARGS_ARGS} -P4"
BACKGROUND="true"
else
XARGS_ARGS=""
BACKGROUND=""
fi
if islocalrepo $SMACK_REPO; then
SMACK_LOCAL=true
SMACK_REPO=`readlink -f $SMACK_REPO`
fi
if [[ -n ${VERSION_TAG} ]]; then
if ! grep ${VERSION_TAG} CHANGELOG; then
echo "Could not find the tag in the CHANGELOG file. Please write a short summary of changes"
exit 1
fi
if ! git diff --exit-code; then
echo "Unstaged changes found, please stages your changes"
exit 1
fi
if ! git diff --cached --exit-code; then
echo "Staged, but uncommited changes found, please commit"
exit 1
fi
RELEASE_DIR=${ASMACK_RELEASES}/${VERSION_TAG}
TAG_FILE=${VERSION_TAG_DIR}/${VERSION_TAG}.tag
fi
}
printconfig() {
echo "Smack git repository $SMACK_REPO with branch $SMACK_BRANCH"
echo -e "SMACK_LOCAL:$SMACK_LOCAL\tUPDATE_REMOTE:$UPDATE_REMOTE\tBUILD_CUSTOM:$BUILD_CUSTOM\tBUILD_JINGLE:$BUILD_JINGLE"
echo -e "PARALLEL_BUILD:$PARALLEL_BUILD\tBASE:$ASMACK_BASE"
}
checkPrerequisites() {
if [[ $BASH_VERSION < 4 ]] ; then
echo "aSmack's build.bash needs at least bash version 4"
exit 1
fi
if ! tar --version |grep GNU &> /dev/null ; then
echo "aSmack's build.bash needs GNU tar"
exit 1
fi
}
# Main
setdefaults
parseopts $@
checkPrerequisites
parseconfig
setconfig
printconfig
initialize
copystaticsrc
testsmackgit
fetchall
createVersionTag
createbuildsrc
patchsrc "patch"
if $BUILD_JINGLE ; then
patchsrc "jingle"
JINGLE_ARGS="-Djingle=lib/jstun.jar"
fi
build
if $BUILD_CUSTOM ; then
buildcustom
fi
if cmdExists advzip ; then
echo "advzip found, compressing files"
find build \( -name '*.jar' -or -name '*.zip' \) -print0 | xargs -n 1 -0 $XARGS_ARGS advzip -z4
else
echo "Could not find the advzip command."
echo "advzip will further reduce the size of the generated jar and zip files,"
echo "consider installing advzip"
fi
prepareRelease
publishRelease
STOPTIME=$(date -u "+%s")
RUNTIME=$(( $STOPTIME - $STARTTIME ))
prettyPrintSeconds $RUNTIME
printconfig