#!/bin/bash # # Build a single TDE module # # Load common code and initialization export SCRIPT_DIR=$(dirname $(readlink -f "$0")) . ${SCRIPT_DIR}/internals/_build_common.sh init_common # Timer settings _BUILDMOD_TIMER_NUM=0 _BUILDMOD_TIME="--/--:--:--:---" exec_time_start $_BUILDMOD_TIMER_NUM # Need sudo for non-root users SUDO_CMD="" if [ "`whoami`" != "root" ]; then SUDO_CMD="sudo -E" fi #---------------------------- # Parameters: # $1 - error code function do_exit() { cd "$SCRIPT_DIR" if [ $1 -eq 0 ]; then echo -e "${CGreen}#### Processing module ${CLightGreen}\"$MOD_NAME\"${CGreen} succeeded ####${CNone}" if [ "$bool_LOG_RESULT" = "y" ]; then echo "[ OK ] [$_BUILDMOD_TIME] \"$MOD_NAME\"" >>"$LOG_BUILD_RESULT_FILENAME" fi else echo -e "${CRed}#### Processing module ${CLightRed}\"$MOD_NAME\"${CRed} failed ($1) ####${CNone}" if [ "$bool_LOG_RESULT" = "y" ]; then echo "[FAILED] [$_BUILDMOD_TIME] \"$MOD_NAME\"" >>"$LOG_BUILD_RESULT_FILENAME" fi fi exit $1 } #---------------------------- # Parameters: # $1 - folder name function recreate_folder() { if [ -d "$1" ]; then $SUDO_CMD rm -R "$1" fi mkdir -p "$1" } #---------------------------- # Look for a module in the git repository or in the extra dependency folder. # Set the module name and paths if found. # Parameters: # $1 - module name function search_module() { OLDIFS=$IFS IFS="*" local LOC_MOD_NAME=$1 local LOC_MATCH MODULE_FOUND="n" # Search in GIT repository LOC_MATCH=`sed -n "s|^\[submodule \"main/\([^\"]*\)\"\]$|\1|p" <"$REPO_TDE/.gitmodules" | grep "$LOC_MOD_NAME$"` if [ "$LOC_MATCH" != "" -a "`echo $LOC_MATCH | wc -l`" = "1" ]; then # Unique module MODULE_FOUND="y" MOD_NAME=$LOC_MATCH if [ "${bool_BUILD_FROM_PATH}" = "y" ]; then MOD_GIT_PATH="$MOD_PATH" else MOD_GIT_PATH="$REPO_TDE_MAIN/$MOD_NAME" fi MOD_GIT_PKGING_PATH="$REPO_TDE_PACKAGING/$MOD_NAME/debian" MOD_BUILD_PATH="$TDE_BUILD_DIR/$MOD_NAME" else # Search for a unique folder with the same name if [ -d "${REPO_TDE_MAIN}/$LOC_MOD_NAME" ]; then # Folder found MODULE_FOUND="y" MOD_NAME=$LOC_MOD_NAME MOD_GIT_PATH="$REPO_TDE_MAIN/$MOD_NAME" MOD_GIT_PKGING_PATH="$REPO_TDE_PACKAGING/$MOD_NAME/debian" MOD_BUILD_PATH="$TDE_BUILD_DIR/$MOD_NAME" else # Search in extra dependency folder LOC_BASENAME=`echo "$LOC_MOD_NAME" | sed -r "s|^${CFG_EXTRA_DEPS_DIR}/(debian/)?||"` LOC_MATCH=`ls "$REPO_EXTRA_DEPENDENCIES/debian" | grep "^$LOC_BASENAME\$"` if [ "$LOC_MATCH" != "" -a "`echo $LOC_MATCH | wc -l`" = "1" ]; then # Unique module found MODULE_FOUND="y" bool_EXTRADEP_MOD="y" MOD_NAME="$CFG_EXTRA_DEPS_DIR/$LOC_MATCH" MOD_GIT_PATH="$REPO_EXTRA_DEPENDENCIES/debian/$LOC_BASENAME" MOD_BUILD_PATH="$TDE_BUILD_DIR/$CFG_EXTRA_DEPS_DIR/$LOC_BASENAME" else # Search in metapackages folder LOC_BASENAME=`echo "$LOC_MOD_NAME" | sed -r "s|^(metapackages/)?||"` LOC_MATCH=`ls "$REPO_TDE_MAIN/metapackages" | grep "^$LOC_BASENAME\$"` if [ "$LOC_MATCH" != "" -a "`echo $LOC_MATCH | wc -l`" = "1" ]; then # Unique module found MODULE_FOUND="y" MOD_NAME="metapackages/$LOC_MATCH" MOD_GIT_PATH="$REPO_TDE_MAIN/metapackages/$LOC_BASENAME" MOD_GIT_PKGING_PATH="$REPO_TDE_PACKAGING/$MOD_NAME/debian" MOD_BUILD_PATH="$TDE_BUILD_DIR/metapackages/$LOC_BASENAME" fi fi fi fi export MOD_BUILD_PATH MOD_BUILD_PKGING_PATH="$MOD_BUILD_PATH/debian" IFS=$OLDIFS } #---------------------------- # Check command line arguments and set options #---------------------------- MOD_NAME="" # the name of the specified module bool_BUILD_FROM_GIT="n" bool_BUILD_FROM_PATH="n" bool_BUILD_LOCALLY="n" bool_EXTRADEP_MOD="n" bool_SHOW_BUILD_LOGS="n" bool_LOG_RESULT="n" bool_SHELL_HOOK="n" bool_PREPARE_ONLY="n" bool_DEBUG_MODE="n" bool_INVALID_PARAMETERS="n" while [ $# -gt 0 ]; do case "$1" in -d) # build with Debug symbols (used in hook scripts) bool_DEBUG_MODE="y" ;; -g) # select code to build from Git repo (-g) or from local build copy bool_BUILD_FROM_GIT="y" ;; -l) # build module Locally instead of in a clean chroot environment bool_BUILD_LOCALLY="y" ;; -lr) # Log build Result to file bool_LOG_RESULT="y" ;; -p) # build from specific Path if [ -z "$MOD_NAME" ]; then shift MOD_NAME="$1" bool_BUILD_FROM_PATH="y" else bool_INVALID_PARAMETERS="y" fi ;; -po) # Prepare build folder Only but do not build bool_PREPARE_ONLY="y" ;; -sh) # install Shell Hook for failing builds (only valid if NOT building locally) bool_SHELL_HOOK="y" ;; -sl) # output the building logs to terminal (ShowLog) bool_SHOW_BUILD_LOGS="y" ;; *) # module to be built if [ -z "$MOD_NAME" ]; then MOD_NAME="$1" else bool_INVALID_PARAMETERS="y" fi esac shift done if [ "${bool_BUILD_FROM_GIT}" = "y" -a "${bool_BUILD_FROM_PATH}" = "y" ]; then bool_INVALID_PARAMETERS="y" fi if [ "$bool_INVALID_PARAMETERS" != "n" ]; then echo "Invalid arguments." MOD_NAME="N/A" do_exit 1 fi # If building from a given path, look up the module name if [ "${bool_BUILD_FROM_PATH}" = "y" ]; then if [ -d "${MOD_NAME}" ]; then cd "${MOD_NAME}" MOD_PATH=`pwd` if [ "${USE_GIT_WORKTREES}" = "y" ]; then MOD_NAME=`git rev-parse --git-dir 2>/dev/null | sed "s|.*/\([^\/]\+\)\.git.*|\1|"` else MOD_NAME=`basename "${MOD_PATH}"` fi if [ "${MOD_NAME}" != "" -a "${MOD_NAME}" != "tde" -a "${MOD_NAME}" != ".git" ]; then # Valid git module if [[ "${MOD_PATH}" =~ ${TDE_BUILD_DIR} ]]; then # Module from build folder bool_BUILD_FROM_GIT="n" else # Module from git repo bool_BUILD_FROM_GIT="y" fi else MOD_NAME="" fi else MOD_NAME="" fi fi echo -e "${CLightCyan}#### Processing module \"$MOD_NAME\" ####${CNone}" if [ "$MOD_NAME" = "" ]; then echo "Please specify the module to build" do_exit 3 fi # Shell hooks are only valid if not building locally if [ "bool_BUILD_LOCALLY" = "y" ]; then bool_SHELL_HOOK="n" fi export bool_SHELL_HOOK # Local option variables # - sign packages OPT_SIGN_PKG_LOCAL="--no-sign" # - show logs OPT_SHOW_LOGS="&>" if [ "$bool_SHOW_BUILD_LOGS" = "y" ]; then OPT_SHOW_LOGS=" | tee " fi export OPT_SHOW_LOGS # This folders must exists BASE_DIRS=("REPO_DIR" "BUILD_DIR" "SCRIPT_DIR" "REPO_TDE_MAIN" "REPO_TDE_PACKAGING" "HOOK_DIR") if [[ "$USE_PREBUILD_EXTRA_DEPS" != "y" ]]; then BASE_DIRS+=("REPO_EXTRA_DEPENDENCIES") fi for var_name in ${BASE_DIRS[@]}; do if [ ! -d "${!var_name}" ]; then echo -e "${CYellow}$var_name${CNone} folder missing (${CLightPurple}${!var_name}${CNone}). Check your config or create it." do_exit 4 fi done #---------------------------- # Build output directories #---------------------------- BUILD_DIRS=("TDE_BUILD_DIR" "TDE_DEBS_DIR") for var_name in ${BUILD_DIRS[@]}; do if [ ! -d "${!var_name}" ]; then mkdir "${!var_name}" fi done #---------------------------- # Check for module existance #---------------------------- # Check if module is an extra dependency if [[ $MOD_NAME =~ ^$CFG_EXTRA_DEPS_DIR/ ]]; then bool_EXTRADEP_MOD="y" fi # Make sure the module exists search_module $MOD_NAME if [ "$MODULE_FOUND" != "y" ]; then echo "Module \"$MOD_NAME\" not found" do_exit 5 fi if [ "$bool_BUILD_FROM_GIT" = "y" ]; then echo -e "${CYellow}> Building from GIT repo${CNone}" bool_COPY_MOD_SRC="y" bool_COPY_PKGING_FILES="y" # packaging scripts if [ "$bool_EXTRADEP_MOD" != "y" -a ! -d "$MOD_GIT_PKGING_PATH" ]; then echo "Packaging for \"$MOD_NAME\" not found in GIT" do_exit 6 fi else echo -e "${CYellow}> Building from BUILD folder${CNone}" if [ ! -d "$MOD_BUILD_PATH" ]; then echo "Build folder for \"$MOD_NAME\" not found" do_exit 7 fi bool_COPY_MOD_SRC="n" bool_COPY_PKGING_FILES="n" fi #---------------------------- # Prepare source files #---------------------------- # remove output from previous build if [ -d "$MOD_BUILD_PATH" ]; then cd "$MOD_BUILD_PATH/.." $SUDO_CMD rm *.deb *.dsc *.changes *.tar.bz2 *.tar.gz *.tar.xz *.log *.buildinfo &>/dev/null fi # calculate package version, if needed if [ "$bool_EXTRADEP_MOD" != "y" ]; then cd $MOD_GIT_PATH branch=`git symbolic-ref -q HEAD | sed "s|^refs/heads/||"` if [[ -z "$branch" ]]; then branch=`git branch --contains HEAD | egrep -v "no branch|detached" | head -n1 | cut -c 3-` fi target_tag=`git tag | grep -F "$TDE_RELEASE" | head -n1` tag=`git tag | \ sed "s|^\([^0-9]\)|\1.|" | sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr -k 5,5nr | sed "s|^\([^0-9]\)\.|\1|" | \ while read t; do \ git branch --contains $t | cut -c 3- | grep -x "$branch" >/dev/null && \ echo "$t..HEAD" && break; done` count=`git log $tag --pretty=oneline | wc -l` pkgver=$TDE_RELEASE if [[ "$count" -gt 0 ]] || [[ -z "$target_tag" ]]; then pkgver=$pkgver~pre$count+$(git rev-parse HEAD | cut -c 1-8) fi MOD_BRANCH=`git symbolic-ref -q HEAD | sed "s|^refs/heads/||"` if [[ -z "$MOD_BRANCH" ]]; then MOD_BRANCH=`git branch --contains HEAD | egrep -v "no branch|detached" | head -n1 | cut -c 3-` fi COMMIT_HASH=`git rev-parse HEAD` fi # copy main repo source files, if needed if [ "$bool_COPY_MOD_SRC" = "y" ]; then bool_COPY_PKGING_FILES="y" recreate_folder "$MOD_BUILD_PATH" if [ "$bool_EXTRADEP_MOD" != "y" ]; then # Normal module cp -R "$MOD_GIT_PATH/." "$MOD_BUILD_PATH" # Add GIT information echo "# TDE SCM module information" > "$MOD_BUILD_PATH/.tdescminfo" echo "Name: $MOD_NAME" >> "$MOD_BUILD_PATH/.tdescminfo" echo "Version: R$pkgver" >> "$MOD_BUILD_PATH/.tdescminfo" echo "Revision: $MOD_BRANCH-$COMMIT_HASH" >> "$MOD_BUILD_PATH/.tdescminfo" git log -1 --pretty=format:"DateTime: %cd%n" --date=format:"%m/%d/%Y %H:%M" >> "$MOD_BUILD_PATH/.tdescminfo" else # Extra dependency module: copy and apply patches # -- move to the correct folder cd "$MOD_GIT_PATH" if [ `ls -d */ | wc -l` == 1 ]; then cd `ls -d */` cp -R "." "$MOD_BUILD_PATH" cd $MOD_BUILD_PATH QUILT_PATCHES="debian/patches" quilt push -a >/dev/null # Make sure patches are not reapplied in future local builds. This could stop pdebuild from working. if [ -f "$MOD_BUILD_PATH/debian/patches/series" ]; then cp /dev/null "$MOD_BUILD_PATH/debian/patches/series" fi else echo "There must be one and only one module folder in \"$MOD_GIT_PATH\"" do_exit 9 fi fi fi # copying packaging scripts, if needed if [ "$bool_EXTRADEP_MOD" != "y" -a "$bool_COPY_PKGING_FILES" = "y" ]; then if [ -d "$MOD_BUILD_PKGING_PATH" ]; then $SUDO_CMD rm -R $MOD_BUILD_PKGING_PATH fi cp -R "$MOD_GIT_PKGING_PATH" "$MOD_BUILD_PKGING_PATH" # Default package name package=$(basename $PWD)-trinity-$pkgver REL=4:$TDE_RELEASE${package#*$TDE_RELEASE} REL=${REL%+*} REL=${REL/4:14.0.0/4:14.0.0-s} # Get package name and packaging release PKG_NAME=$(head -n1 $MOD_BUILD_PKGING_PATH/changelog) PKG_NAME=${PKG_NAME%% *} PKG_TAG=$(cd "$REPO_TDE_PACKAGING/$MOD_NAME" && git tag | \ sed "s|^\([^0-9]\)|\1.|" | sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr -k 5,5nr | sed "s|^\([^0-9]\)\.|\1|" | \ while read t; do \ git branch --contains $t | cut -c 3- | grep -x "$branch" >/dev/null && \ echo "$t..HEAD" && break; done) PKG_REL=$(cd "$REPO_TDE_PACKAGING/$MOD_NAME" && git log $PKG_TAG --pretty=oneline . | wc -l) if [ -n "$REL_SUFFIX" ]; then PKG_REL="${PKG_REL}${REL_SUFFIX}" fi # TODO add relative patch count ADD_REL=0 # Update changelog REPO_DATE=`git log -1 --pretty=format:"%cd%n" --date=rfc` GITUSER="$(git config --get user.name) <$(git config --get user.email)>" echo "$PKG_NAME ($REL-0$DISTRO$DISTRO_VERSION.$ADD_REL+$PKG_REL) $DISTRO_NAME; urgency=low" > "$MOD_BUILD_PKGING_PATH/changelog" echo -e "\n * Automated git build\n\n -- $GITUSER $REPO_DATE\n" >> "$MOD_BUILD_PKGING_PATH/changelog" cat "$REPO_TDE_PACKAGING/$MOD_NAME/debian/changelog" >> "$MOD_BUILD_PKGING_PATH/changelog" touch -d "$REPO_DATE" "$MOD_BUILD_PKGING_PATH/changelog" fi # prepare destination directory for building export MOD_DEB_PATH="$TDE_DEBS_DIR/$MOD_NAME" MOD_DEBSRC_PATH="$MOD_DEB_PATH/src" recreate_folder "$MOD_DEB_PATH" recreate_folder "$MOD_DEBSRC_PATH" #---------------------------- # Apply pre-build hooks if present #---------------------------- if [ -x "$HOOK_DIR/$MOD_NAME/pre_build.sh" ]; then echo -e "${CYellow}> Applying pre-build hook${CNone}" . "$HOOK_DIR/$MOD_NAME/pre_build.sh" if [ $? -eq 0 ]; then echo -e "> ${CBrown}Pre-build hook applied successfully${CNone}" else echo -e "> ${CLightBlue}Pre-build hook failed${CNone}" fi fi #---------------------------- # Switch to 3.0(quilt) format #---------------------------- # create orig tarball cd "$MOD_BUILD_PATH" MOD_BASENAME=`head -n 1 "$MOD_BUILD_PKGING_PATH/changelog" | sed -r "s/^([^ ]+).*/\1/"` MOD_MAJOR_VER=`head -n 1 "$MOD_BUILD_PKGING_PATH/changelog" | sed -r "s/^[^ ]+ \(([^:]+:)?.*/\1/"` MOD_UP_VER=`head -n 1 "$MOD_BUILD_PKGING_PATH/changelog" | sed -r "s/^[^ ]+ \(([^:]+:)?(.*+)-.*/\2/"` MOD_DEB_VER=`head -n 1 "$MOD_BUILD_PKGING_PATH/changelog" | sed -r "s/^[^ ]+ \(.*+-([^\)]+).*/\1/"` REPO_DATE=`dpkg-parsechangelog -l "$MOD_BUILD_PKGING_PATH/changelog" | sed -n -e 's|^Date: ||p'` tar cJf "../${MOD_BASENAME}_${MOD_UP_VER}.orig.tar.xz" --exclude="debian" --exclude .git --exclude .gitmodules \ --mtime "$REPO_DATE" --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime . touch -d "$REPO_DATE" "../${MOD_BASENAME}_${MOD_UP_VER}.orig.tar.xz" # switch to quilt format if [ -f "$MOD_BUILD_PKGING_PATH/source/format" ]; then grep -q "(native)" "$MOD_BUILD_PKGING_PATH/source/format" && \ sed -i "s/(native)/(quilt)/" "$MOD_BUILD_PKGING_PATH/source/format" else [ -d "$MOD_BUILD_PKGING_PATH/source" ] || mkdir -p "$MOD_BUILD_PKGING_PATH/source" echo "3.0 (quilt)" >"$MOD_BUILD_PKGING_PATH/source/format" fi # remove quilt references from rules file grep -q "^include.*/usr/share/cdbs/1/rules/patchsys-quilt\.mk" "$MOD_BUILD_PKGING_PATH/rules" && \ sed -i "s/^\(include.*\/usr\/share\/cdbs\/1\/rules\/patchsys-quilt\.mk\)/#\1/" "$MOD_BUILD_PKGING_PATH/rules" #---------------------------- # Enable debug mode if required #---------------------------- if [ "$bool_DEBUG_MODE" = "y" ]; then echo -e "${CBrown}Enable debug mode${CNone}" sed -i "s/RelWithDebInfo/Debug/" "$MOD_BUILD_PKGING_PATH/rules" fi #---------------------------- # Exit if only preparation was required #---------------------------- if [ "$bool_PREPARE_ONLY" = "y" ]; then echo -e "${CBrown}Source code prepared for building${CNone}" do_exit 0 fi #---------------------------- # Build #---------------------------- export BUILDING_LOG_FILE="$MOD_DEBSRC_PATH/__build__.log" cd "$MOD_BUILD_PATH" if [ "$bool_BUILD_LOCALLY" = "y" ]; then ## Build module locally echo -e "${CYellow}> Building locally${CNone}" eval dpkg-buildpackage -S $OPT_SIGN_PKG_LOCAL $OPT_SHOW_LOGS\"$BUILDING_LOG_FILE\" build_retval=$? if [ $build_retval -eq 0 ]; then eval dpkg-buildpackage -b $OPT_SIGN_PKG_LOCAL $OPT_SHOW_LOGS\"$BUILDING_LOG_FILE\" build_retval=$? fi else ## Build module in a clean chroot environment using pbuilder $SUDO_CMD "$SCRIPT_DIR/internals/_pbuilder.sh" build_retval=$? if [ "`whoami`" != "root" ]; then cd "$MOD_DEB_PATH" $SUDO_CMD chown -R `id -u -n`:`id -g -n` . &>/dev/null cd "$MOD_BUILD_PATH/.." $SUDO_CMD chown `id -u -n`:`id -g -n` *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.buildinfo &>/dev/null $SUDO_CMD chown `id -u -n`:`id -g -n` "$TDE_DEBS_DIR/Packages" &>/dev/null cd "$MOD_BUILD_PATH" fi fi if [ $build_retval -eq 0 ]; then echo -e "${CLightGreen}> Building completed SUCCESSFULLY${CNone}" else echo -e "${CLightRed}> Building completed WITH ERRORS${CNone}" fi #---------------------------- # Apply post-build hooks if present #---------------------------- if [ -x "$HOOK_DIR/$MOD_NAME/post_build.sh" ]; then echo -e "${CYellow}> Applying post-build hook${CNone}" . "$HOOK_DIR/$MOD_NAME/post_build.sh" if [ $? -eq 0 ]; then echo -e "${CBrown}Post-build hook applied successfully${CNone}" else echo -e "${CLightBlue}Post-build hook failed${CNone}" fi fi #---------------------------- # Move compiled module files to destination folders #---------------------------- if [ "$bool_BUILD_LOCALLY" = "y" ]; then cd "$MOD_BUILD_PATH/.." mv *.deb "$MOD_DEB_PATH" &>/dev/null mv *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.buildinfo "$MOD_DEBSRC_PATH" &>/dev/null else cd "$MOD_DEB_PATH" mv *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.buildinfo "$MOD_DEBSRC_PATH" &>/dev/null cd "$MOD_BUILD_PATH/.." mv *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.buildinfo "$MOD_DEBSRC_PATH" &>/dev/null fi #---------------------------- # Removing leftover files #---------------------------- cd "$MOD_BUILD_PATH/.." rm *.deb *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.log *.buildinfo &>/dev/null cd "$MOD_DEB_PATH" rm *.dsc *.changes *.tar.xz *.tar.bz2 *.tar.gz *.log *.buildinfo &>/dev/null #---------------------------- # Building completed #---------------------------- exec_time_stop $_BUILDMOD_TIMER_NUM "_BUILDMOD_TIME" do_exit $build_retval