diff --git a/debian/_buildscripts/local/README.txt b/debian/_buildscripts/local/README.txt index e36f5ceed..fe08e1fc1 100644 --- a/debian/_buildscripts/local/README.txt +++ b/debian/_buildscripts/local/README.txt @@ -33,16 +33,28 @@ A) Environment preparation Mainly used to apply patches automatically during the building process 4) Clone TDE git repositories - - TDE main repo - cd "$TDE_DIR/1_git" - git clone https://mirror.git.trinitydesktop.org/gitea/TDE/tde.git - git clone https://mirror.git.trinitydesktop.org/gitea/TDE/scripts.git tde/scripts - cd tde - ./scripts/switch_all_submodules_to_head_and_clean anonymous + A) without using git worktrees + A.1) Main repo: + cd "$TDE_DIR/1_git" + git clone https://mirror.git.trinitydesktop.org/gitea/TDE/tde.git + git clone https://mirror.git.trinitydesktop.org/gitea/TDE/scripts.git tde/scripts + cd tde + ./scripts/switch_all_submodules_to_head_and_clean anonymous - - If you are not using pre-built extra dependencies: - cd "$TDE_DIR/1_git" - git clone https://mirror.git.trinitydesktop.org/gitea/TDE/extra-dependencies.git edeps + A.2) If you are not using pre-built extra dependencies: + cd "$TDE_DIR/1_git" + git clone https://mirror.git.trinitydesktop.org/gitea/TDE/extra-dependencies.git edeps + + B) using git worktrees + B.1) Main repo + cd "$TDE_DIR/1_git" + git clone --bare --config "remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*" https://mirror.git.trinitydesktop.org/gitea/TDE/tde.git repos/tde.git + + B.2) If you are not using pre-built extra dependencies: + cd "$TDE_DIR/1_git" + git clone --bare --config "remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*" https://mirror.git.trinitydesktop.org/gitea/TDE/extra-dependencies.git repos/edeps.git + + B.3) run the script "update_repositories.sh" once you have completed the setup as described later in this document. 5) Add your user to the sudo group (not required if you are root) su -c "adduser sudo" @@ -126,14 +138,14 @@ When building sets of modules or the whole TDE, a global build summary is automa - scripts in 'internals' folder Scripts used intenally by other scripts. No need for invoking these directly. -- update_git_repository.sh: +- update_repositories.sh: Script used to update the local clone of the git repositories. It is possible to update multiple branches as specified by the variable UPDATE_BRANCHES in the configuration file. After the update is completed, the local repositories will be switched to the branch specified by the DEFAULT_REPO_BRANCH variable. The script can also be used to switch the local repositories to a particular branch, without performing any update. Usage: - update_git_repository.sh [options] + update_repositories.sh [options] Options: -i (Incremental) : in case the previous update was interrupted, continue from the last known updated module. (useful on slow/unstable internet connections). If the previous update had completed, diff --git a/debian/_buildscripts/local/internals/_build_common.sh b/debian/_buildscripts/local/internals/_build_common.sh index cb2c0e346..be1b520ec 100755 --- a/debian/_buildscripts/local/internals/_build_common.sh +++ b/debian/_buildscripts/local/internals/_build_common.sh @@ -42,176 +42,194 @@ set +a # $3 - if "y" create a new file. function echo_and_tee() { - if [ "$3" = "y" ]; then - echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >"$2" - else - echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >>"$2" - fi + if [ "$3" = "y" ]; then + echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >"$2" + else + echo -e "$1" | tee /dev/tty | sed -r "s|\x1b\[[0-9]+(;[0-9]+)?m||g" >>"$2" + fi } #---------------------------- function _set_path_variables() { - # Set useful path variables - set -a - - #-- get desired distribution and architecture - [[ "$DISTRO" = "" ]] && DISTRO=$(lsb_release -is | sed -e 's/\(.*\)/\L\1/') - [[ "$DISTRO_NAME" = "" ]] && DISTRO_NAME=$(lsb_release -cs | sed -e 's/\(.*\)/\L\1/') - [[ "$ARCHITECTURE" = "" ]] && ARCHITECTURE=$(dpkg --print-architecture) - - REPO_DIR="$TDE_DIR/$CFG_GIT_DIR" - REPO_TDE="$TDE_DIR/$CFG_GIT_DIR/tde" - REPO_TDE_MAIN="$REPO_TDE/main" - REPO_TDE_PACKAGING="$TDE_DIR/$CFG_GIT_DIR/tde/packaging/$DISTRO/$DISTRO_NAME" - REPO_EXTRA_DEPENDENCIES="$TDE_DIR/$CFG_GIT_DIR/$CFG_EXTRA_DEPS_DIR" - - BUILD_DIR="$TDE_DIR/$CFG_BUILD_DIR" - TDE_BUILD_DIR="$BUILD_DIR/build" - TDE_DEBS_DIR="$BUILD_DIR/debs" - - HOOK_DIR="$TDE_DIR/$CFG_GIT_DIR/$CFG_HOOKS_DIR" - + # Set useful path variables + set -a + + #-- get desired distribution and architecture + [[ "$DISTRO" = "" ]] && DISTRO=$(lsb_release -is | sed -e 's/\(.*\)/\L\1/') + [[ "$DISTRO_NAME" = "" ]] && DISTRO_NAME=$(lsb_release -cs | sed -e 's/\(.*\)/\L\1/') + [[ "$ARCHITECTURE" = "" ]] && ARCHITECTURE=$(dpkg --print-architecture) + + REPO_DIR="$TDE_DIR/$CFG_GIT_DIR" + if [ "${USE_GIT_WORKTREES}" = "y" ]; then + REPOS_DIR="$TDE_DIR/$CFG_GIT_DIR/repos" + WORKTREES_DIR="$TDE_DIR/$CFG_GIT_DIR/worktrees" + REPO_TDE="$WORKTREES_DIR/master/tde" + REPO_EXTRA_DEPENDENCIES="$WORKTREES_DIR/master/$CFG_EXTRA_DEPS_DIR" + else + REPO_TDE="$TDE_DIR/$CFG_GIT_DIR/tde" + REPO_EXTRA_DEPENDENCIES="$TDE_DIR/$CFG_GIT_DIR/$CFG_EXTRA_DEPS_DIR" + fi + REPO_TDE_MAIN="$REPO_TDE/main" + REPO_TDE_PACKAGING="$REPO_TDE/packaging/$DISTRO/$DISTRO_NAME" + + BUILD_DIR="$TDE_DIR/$CFG_BUILD_DIR" + TDE_BUILD_DIR="$BUILD_DIR/build" + TDE_DEBS_DIR="$BUILD_DIR/debs" + + HOOK_DIR="$TDE_DIR/$CFG_GIT_DIR/$CFG_HOOKS_DIR" + SCRIPT_LOG_DIR="$TDE_DIR/$CFG_SCRIPT_LOG_DIR" - LOG_BUILD_RESULT_FILENAME="$SCRIPT_LOG_DIR/build_result.log" # Common build logfile - LOG_UPDATE_REPO_FILENAME="$SCRIPT_LOG_DIR/update_repo.log" # Update repository logfile - set +a + LOG_BUILD_RESULT_FILENAME="$SCRIPT_LOG_DIR/build_result.log" # Common build logfile + LOG_UPDATE_REPO_FILENAME="$SCRIPT_LOG_DIR/update_repo.log" # Update repository logfile + + set +a } #---------------------------- function init_common() { - # Check script folder - export SCRIPT_DIR=$(dirname $(readlink -f "$0")) - - # Prevent the script to be run from TDE packaging repo - REPO_URL=$(git config --get remote.origin.url 2>/dev/null) - if [ ! -z "$REPO_URL" ] && [ -z "${REPO_URL##*tde/packaging}" ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo "This script cannot be run from the TDE packaging repository." - echo "Please follow the instructions provided, then rerun this script." - exit 1 - fi - - # Read config settings - CFG_FILE=$SCRIPT_DIR/_config.sh - if [ -f "$CFG_FILE" ]; then - . "$CFG_FILE" - _set_path_variables - else - echo -e "${CLightRed} --- NOTE ---${CNone}" - echo -e "Creating TDE build configuration file from template as ${CLightPurple}$CFG_FILE${CNone}." - echo "Please check and modify as required, then rerun this script." - cp "$SCRIPT_DIR/internals/_config_template.sh" "$CFG_FILE" - exit 2 - fi - - # Make sure we have selected a supported distribution - DISTROS_FILE="$SCRIPT_DIR/internals/distro_list.txt" - if [ ! -f "$DISTROS_FILE" ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo "Could not find the list of supported distributions." - echo -e "Please check the file ${CLightPurple}$DISTROS_FILE${CNone} exists, then rerun this script." - exit 3 - fi - # -- Need to use a "here string" otherwise if the DISTRO_FOUND value is modified - # -- inside the while loop, this would not remember after the loop. - DISTRO_FOUND="n" - OLD_IFS=$IFS && IFS=$' \t' - while read l_distro l_version l_name l_rel_suffix l_packaging_path; do - if [ "$l_distro" = "$DISTRO" -a "$l_name" = "$DISTRO_NAME" ]; then - DISTRO_FOUND="y" - l_rel_suffix=`echo "$l_rel_suffix" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"` - l_packaging_path=`echo "$l_packaging_path" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"` - export DISTRO_VERSION="$l_version" - export REL_SUFFIX="$l_rel_suffix" - if [[ ! -z "$l_packaging_path" ]]; then - REPO_TDE_PACKAGING="$TDE_DIR/$CFG_GIT_DIR/tde/packaging/$l_packaging_path" - fi - break - fi - done <<< $(sed -n "s|\(^[\s]*[^#\s]\+.*$\)|\1|p" < $DISTROS_FILE) - IFS=$OLD_IFS - if [ "$DISTRO_FOUND" != "y" ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo -e "The specified distribution (${CYellow}$DISTRO $DISTRO_NAME${CNone}) is not supported." - echo -e "Something is wrong with your configuration (${CLightPurple}$CFG_FILE${CNone})" - echo -e "or with the list of supported distributions (${CLightPurple}$DISTROS_FILE${CNone})." - echo -e "Please check the ${CLightCyan}DISTRO${CNone} and ${CLightCyan}DISTRO_NAME${CNone} variables, then rerun this script." - exit 4 - fi - - # TDE root folder must exist - if [ ! -d "$TDE_DIR" ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo "A valid TDE root folder could not be located. Something is wrong with your configuration" - echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" - echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} variable as required, then rerun this script." - exit 5 - fi - - # Search for main TDE repo - CURR_DIR="" - [ -d "$REPO_TDE_MAIN" ] && cd "$REPO_TDE_MAIN" &>/dev/null && \ - CURR_DIR=$(git rev-parse --show-toplevel 2>/dev/null) - if [ -z "$CURR_DIR" ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo "The main TDE repo could not be located. Something is wrong with your configuration" - echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" - echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} variable as required, then rerun this script." - exit 6 - fi - - # Check branch configuration - # - branch existance - UPDATE_BRANCHES="${OVERRIDE_UPDATE_BRANCHES:-$UPDATE_BRANCHES}" - cd "$REPO_TDE" - BRANCHES=() - REMOTE_BRANCHES=(`git branch --remote | grep -v "HEAD" | sed "s|origin/||g"`) - for br in $UPDATE_BRANCHES; do - branch=`echo "$br" | sed -e "s|^[[:space:]]*||" -e "s|[[:space:]]*$||"` - found=0 - for rem_br in "${REMOTE_BRANCHES[@]}"; do + # Check script folder + export SCRIPT_DIR=$(dirname $(readlink -f "$0")) + + # Prevent the script to be run from TDE packaging repo + REPO_URL=$(git config --get remote.origin.url 2>/dev/null) + if [ ! -z "$REPO_URL" ] && [ -z "${REPO_URL##*tde/packaging}" ]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo "This script cannot be run from the TDE packaging repository." + echo "Please follow the instructions provided, then rerun this script." + exit 1 + fi + + # Read config settings + CFG_FILE=$SCRIPT_DIR/_config.sh + if [ -f "$CFG_FILE" ]; then + . "$CFG_FILE" + _set_path_variables + else + echo -e "${CLightRed} --- NOTE ---${CNone}" + echo -e "Creating TDE build configuration file from template as ${CLightPurple}$CFG_FILE${CNone}." + echo "Please check and modify as required, then rerun this script." + cp "$SCRIPT_DIR/internals/_config_template.sh" "$CFG_FILE" + exit 2 + fi + + # Make sure we have selected a supported distribution + DISTROS_FILE="$SCRIPT_DIR/internals/distro_list.txt" + if [ ! -f "$DISTROS_FILE" ]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo "Could not find the list of supported distributions." + echo -e "Please check the file ${CLightPurple}$DISTROS_FILE${CNone} exists, then rerun this script." + exit 3 + fi + # -- Need to use a "here string" otherwise if the DISTRO_FOUND value is modified + # -- inside the while loop, this would not remember after the loop. + DISTRO_FOUND="n" + OLD_IFS=$IFS && IFS=$' \t' + while read l_distro l_version l_name l_rel_suffix l_packaging_path; do + if [ "$l_distro" = "$DISTRO" -a "$l_name" = "$DISTRO_NAME" ]; then + DISTRO_FOUND="y" + l_rel_suffix=`echo "$l_rel_suffix" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"` + l_packaging_path=`echo "$l_packaging_path" | perl -pe "s|^[\"-]?(.*?)[\"]?$|\1|g"` + export DISTRO_VERSION="$l_version" + export REL_SUFFIX="$l_rel_suffix" + if [[ ! -z "$l_packaging_path" ]]; then + REPO_TDE_PACKAGING="$TDE_DIR/$CFG_GIT_DIR/tde/packaging/$l_packaging_path" + fi + break + fi + done <<< $(sed -n "s|\(^[\s]*[^#\s]\+.*$\)|\1|p" < $DISTROS_FILE) + IFS=$OLD_IFS + if [ "$DISTRO_FOUND" != "y" ]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo -e "The specified distribution (${CYellow}$DISTRO $DISTRO_NAME${CNone}) is not supported." + echo -e "Something is wrong with your configuration (${CLightPurple}$CFG_FILE${CNone})" + echo -e "or with the list of supported distributions (${CLightPurple}$DISTROS_FILE${CNone})." + echo -e "Please check the ${CLightCyan}DISTRO${CNone} and ${CLightCyan}DISTRO_NAME${CNone} variables, then rerun this script." + exit 4 + fi + + # TDE root folder must exist + if [ ! -d "$TDE_DIR" ]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo "A valid TDE root folder could not be located. Something is wrong with your configuration" + echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" + echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} variable as required, then rerun this script." + exit 5 + fi + + # Search for TDE repo + found=0 + tde_config_file="" + if [ "${USE_GIT_WORKTREES}" = "y" ]; then + tde_config_file="$REPOS_DIR/tde.git/config" + else + tde_config_file="${REPO_TDE}/.git/config" + fi + [ -f "${tde_config_file}" ] && [ "`grep \"\\[core\\]\" ${tde_config_file}`" = "[core]" ] && found=1 + if [[ found -ne 1 ]]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo "The main TDE repo could not be located. Something is wrong with your configuration" + echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" + echo -e "Please check and modify the ${CLightCyan}TDE_DIR${CNone} and ${CLightCyan}USE_GIT_WORKTREES${CNone} variables as required." + echo -e "Then rerun this script." + exit 6 + fi + + # Check branch configuration + # - branch existance + UPDATE_BRANCHES="${OVERRIDE_UPDATE_BRANCHES:-$UPDATE_BRANCHES}" + if [ "${USE_GIT_WORKTREES}" = "y" ]; then + cd "$REPOS_DIR/tde.git" + else + cd "$REPO_TDE" + fi + BRANCHES=() + local REMOTE_BRANCHES=(`git branch --remote | grep -v "HEAD" | sed "s|origin/||g"`) + for br in $UPDATE_BRANCHES; do + branch=`echo "$br" | sed -e "s|^[[:space:]]*||" -e "s|[[:space:]]*$||"` + found=0 + for rem_br in "${REMOTE_BRANCHES[@]}"; do if [[ "$rem_br" == "$branch" ]]; then found=1 break fi done - if [[ found -eq 1 ]]; then - BRANCHES+=($branch) - else - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo -e "Invalid branch specified (${CYellow}$branch${CNone}). Something is wrong with your configuration" - echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" - echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script." - exit 8 - fi - done - if [ ${#BRANCHES[@]} -eq 0 ]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo -e "No valid branch was specified. Something is wrong with your configuration" - echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" - echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script." - exit 9 - fi - export BRANCHES - # - default branch - DEFAULT_REPO_BRANCH=${OVERRIDE_DEFAULT_REPO_BRANCH:-"$DEFAULT_REPO_BRANCH"} - found=0 - for branch in "${BRANCHES[@]}"; do - if [[ "$DEFAULT_REPO_BRANCH" == "$branch" ]]; then - found=1 - break - fi - done - if [[ found -ne 1 ]]; then - echo -e "${CLightRed} --- ERROR ---${CNone}" - echo -e "Invalid default repo branch specified (${CYellow}$DEFAULT_REPO_BRANCH${CNone}). Something is wrong with your configuration" - echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" - echo -e "Please check and modify the ${CLightCyan}DEFAULT_REPO_BRANCH${CNone} variable as required, then rerun this script." - exit 10 - fi - + if [[ found -eq 1 ]]; then + BRANCHES+=($branch) + else + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo -e "Invalid branch specified (${CYellow}$branch${CNone}). Something is wrong with your configuration" + echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" + echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script." + exit 8 + fi + done + if [ ${#BRANCHES[@]} -eq 0 ]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo -e "No valid branch was specified. Something is wrong with your configuration" + echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" + echo -e "Please check and modify the ${CLightCyan}UPDATE_BRANCHES${CNone} variable as required, then rerun this script." + exit 9 + fi + export BRANCHES + # - default branch + DEFAULT_REPO_BRANCH=${OVERRIDE_DEFAULT_REPO_BRANCH:-"$DEFAULT_REPO_BRANCH"} + found=0 + for branch in "${BRANCHES[@]}"; do + if [[ "$DEFAULT_REPO_BRANCH" == "$branch" ]]; then + found=1 + break + fi + done + if [[ found -ne 1 ]]; then + echo -e "${CLightRed} --- ERROR ---${CNone}" + echo -e "Invalid default repo branch specified (${CYellow}$DEFAULT_REPO_BRANCH${CNone}). Something is wrong with your configuration" + echo -e "in the config file ${CLightPurple}$CFG_FILE${CNone}" + echo -e "Please check and modify the ${CLightCyan}DEFAULT_REPO_BRANCH${CNone} variable as required, then rerun this script." + exit 10 + fi + cd "$SCRIPT_DIR" } diff --git a/debian/_buildscripts/local/update_repositories.sh b/debian/_buildscripts/local/update_repositories.sh index 7c415cc4c..934a5a1b1 100755 --- a/debian/_buildscripts/local/update_repositories.sh +++ b/debian/_buildscripts/local/update_repositories.sh @@ -85,7 +85,6 @@ function _do_update() fi ;; - "update") cd "$MOD_PATH" &>/dev/null if [ $? -eq 0 ]; then @@ -147,6 +146,172 @@ function _do_update() echo "${RESULT_STRINGS[$RESULT]} $MOD_PATH" >> "$LOG_UPDATE_REPO_FILENAME" } +#---------------------------- +# Update a given module from the upstream repo +# Parameters: +# $1 - module folder and name +# $2 - operation type +# $3 - module url (for "add_repo") +# branch name (for other operations) +# $4 - parent module path (only for check_module operation) +# $5 - module string (only for check_module operation) +function _do_worktree_update() +{ + local MOD_FULLPATH=$1 + local MOD_NAME=`echo ${MOD_FULLPATH} | sed "s|^.*/\([^/]\+\)$|\1|"` + local OP_TYPE=$2 + local MOD_REPO_PATH="${REPOS_DIR}/${MOD_NAME}.git" + local RESULT="" + local LINE_CTRL_SUFFIX="" + local LOCAL_BRANCHES + local REMOTE_BRANCHES + + case "$OP_TYPE" in + "add_repo") + if [ -z "`grep \"^${MOD_REPO_PATH} - ADD REPO$\" \"${UPDATE_LOCK_FILENAME}\"`" ]; then + RESULT="OK" + if [ ! -d "${MOD_REPO_PATH}" ]; then + RESULT="UPDATE" + local MOD_URLNAME="$3" + [ -n "${MOD_URLNAME}" ] || MOD_URLNAME="${MOD_NAME}" + eval git clone --bare --config "remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*" \ + "${ORIGIN_PATH}/${MOD_URLNAME}.git" "${MOD_REPO_PATH}" $OPT_VERBOSE_LOG || RESULT="FAIL" + fi + if [ "$RESULT" != "OK" -o "$flag_VERBOSE_LOG" = "y" ]; then + LINE_CTRL_SUFFIX="\n" + fi + echo -ne "\033[2K\r${COLOR_STRINGS[$RESULT]}${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - repo added${CNone}$LINE_CTRL_SUFFIX" + echo "${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - repo added" >> "$LOG_UPDATE_REPO_FILENAME" + # + echo "${MOD_REPO_PATH} - ADD REPO" >> "${UPDATE_LOCK_FILENAME}" + fi + ;; + + "fetch") + if [[ -z `grep "^${MOD_REPO_PATH} - FETCH$" "${UPDATE_LOCK_FILENAME}"` ]]; then + cd "${MOD_REPO_PATH}" &>/dev/null + RESULT="FAIL" + eval git fetch --all --prune $GIT_NO_RECURSE_SUBMODULES $OPT_VERBOSE_LOG && + eval git worktree prune $OPT_VERBOSE_LOG && RESULT="OK" + if [ "$RESULT" != "OK" -o "$flag_VERBOSE_LOG" = "y" ]; then + LINE_CTRL_SUFFIX="\n" + fi + echo -ne "\033[2K\r${COLOR_STRINGS[$RESULT]}${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - fetched${CNone}$LINE_CTRL_SUFFIX" + echo "${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - fetched" >> "$LOG_UPDATE_REPO_FILENAME" + # + echo "${MOD_REPO_PATH} - FETCH" >> "${UPDATE_LOCK_FILENAME}" + fi + ;; + + "check_worktree") + # Check/add worktrees + LOCAL_BRANCHES=$3 + cd "${MOD_REPO_PATH}" &>/dev/null + REMOTE_BRANCHES=(`git branch --remote | sed "s|origin/||g"`) + for LCL_BR in $LOCAL_BRANCHES; do + CURR_BR=`echo "$LCL_BR" | sed -e "s|^[[:space:]]*||" -e "s|[[:space:]]*$||"` + local WORK_PATH="${WORKTREES_DIR}/${CURR_BR}/${MOD_FULLPATH}" + for REM_BR in "${REMOTE_BRANCHES[@]}"; do + if [ "${REM_BR}" = "${CURR_BR}" -a -z "`grep \"^${MOD_FULLPATH} - ${CURR_BR} - ADD WORKTREE$\" \"${UPDATE_LOCK_FILENAME}\"`" ]; then + cd "${MOD_REPO_PATH}" &>/dev/null + if [[ -z `git worktree list | grep "\[${CURR_BR}\]"` ]]; then + RESULT="FAIL" + eval git worktree add "${WORK_PATH}" "origin/${CURR_BR}" $OPT_VERBOSE_LOG && + cd "${WORK_PATH}" &>/dev/null && + eval git checkout ${CURR_BR} $OPT_VERBOSE_LOG && + eval git branch --set-upstream-to=origin/${CURR_BR} $OPT_VERBOSE_LOG && RESULT="UPDATE" + LINE_CTRL_SUFFIX="" + [ "$RESULT" != "OK" -o "$flag_VERBOSE_LOG" = "y" ] && LINE_CTRL_SUFFIX="\n" + echo -ne "\033[2K\r${COLOR_STRINGS[$RESULT]}${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - branch ${CURR_BR} - worktree added${CNone}$LINE_CTRL_SUFFIX" + echo "${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - branch ${CURR_BR} - worktree added" >> "$LOG_UPDATE_REPO_FILENAME" + fi + # + echo "${MOD_FULLPATH} - ${CURR_BR} - ADD WORKTREE" >> "${UPDATE_LOCK_FILENAME}" + break + fi + done + done + ;; + + "check_module") + # Make sure submodules are initialized and up to date if necessary + if [ -z "`grep \"^${MOD_FULLPATH} - ${CURR_BR} - CHECK MODULE$\" \"${UPDATE_LOCK_FILENAME}\"`" ]; then + local PARENT_PATH=$4 + local SUBMOD_STR=$5 + if [ -n "$PARENT_PATH" -a -n "$SUBMOD_STR" ]; then + # Only do this on a real submodule + RESULT="OK" + cd "$PARENT_PATH" &>/dev/null + git config submodule.$SUBMOD_STR.url "$MOD_REPO_PATH" &>/dev/null + if [[ -n "`git submodule status -- ${SUBMOD_STR} | grep "^-.*"`" ]]; then + RESULT="UPDATE" + eval git submodule init -- ${SUBMOD_STR} $OPT_VERBOSE_LOG || RESULT="FAIL" + fi + if [ "$RESULT" != "FAIL" -a ! -e "${SUBMOD_STR}/.git" ]; then + RESULT="UPDATE" + eval git submodule update -- ${SUBMOD_STR} $OPT_VERBOSE_LOG || RESULT="FAIL" + fi + LINE_CTRL_SUFFIX="" + [ "$RESULT" != "OK" -o "$flag_VERBOSE_LOG" = "y" ] && LINE_CTRL_SUFFIX="\n" + echo -ne "\033[2K\r${COLOR_STRINGS[$RESULT]}${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - module checked${CNone}$LINE_CTRL_SUFFIX" + echo "${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - module checked" >> "$LOG_UPDATE_REPO_FILENAME" + fi + # + echo "${MOD_FULLPATH} - ${CURR_BR} - CHECK MODULE" >> "${UPDATE_LOCK_FILENAME}" + fi + ;; + + "update") + LOCAL_BRANCHES=$3 + REMOTE_BRANCHES=(`git branch --remote | sed "s|origin/||g"`) + for LCL_BR in $LOCAL_BRANCHES; do + CURR_BR=`echo "$LCL_BR" | sed -e "s|^[[:space:]]*||" -e "s|[[:space:]]*$||"` + for REM_BR in "${REMOTE_BRANCHES[@]}"; do + if [ "${REM_BR}" = "${CURR_BR}" -a -z "`grep \"^${MOD_FULLPATH} - ${CURR_BR} - WORKTREE UPDATED$\" \"${UPDATE_LOCK_FILENAME}\"`" ]; then + local WORK_PATH="${WORKTREES_DIR}/${CURR_BR}/${MOD_FULLPATH}" + RESULT="FAIL" + if [ -d ${WORK_PATH} ]; then + cd "${WORK_PATH}" &>/dev/null && + # Clean up any possible uncommitted changes + if [[ ! -z "`git status --porcelain $GIT_IGNORE_SUBMODULES`" ]]; then + git reset --hard HEAD &>/dev/null + git clean -dxff &>/dev/null + fi + # Make sure the local branch is a tracking branch + if [[ -z `git config branch."${CURR_BR}".remote` ]]; then + git branch -u "origin/${CURR_BR}" &>/dev/null #$ + git reset --hard "origin/${CURR_BR}" &>/dev/null + fi + # Update + eval git reset --hard HEAD $OPT_VERBOSE_LOG + eval git clean -dxff $OPT_VERBOSE_LOG + eval git checkout "${CURR_BR}" $OPT_VERBOSE_LOG + if [[ $(git rev-parse HEAD) != $(git rev-parse "origin/${CURR_BR}") ]]; then + eval git rebase $OPT_VERBOSE_LOG + if [[ `git rev-parse HEAD` == `git rev-parse "origin/${CURR_BR}"` ]]; then + RESULT="UPDATE" + fi + else + RESULT="OK" + fi + fi + LINE_CTRL_SUFFIX="" + [ "$RESULT" != "OK" -o "$flag_VERBOSE_LOG" = "y" ] && LINE_CTRL_SUFFIX="\n" + echo -ne "\033[2K\r${COLOR_STRINGS[$RESULT]}${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - branch ${CURR_BR} - worktree updated${CNone}$LINE_CTRL_SUFFIX" + echo "${RESULT_STRINGS[$RESULT]} ${MOD_NAME} - branch ${CURR_BR} - worktree updated" >> "$LOG_UPDATE_REPO_FILENAME" + echo "${MOD_FULLPATH} - ${CURR_BR} - WORKTREE UPDATED" >> "${UPDATE_LOCK_FILENAME}" + break + fi + done + done + ;; + + *) + RESULT="INV-OP" + ;; + esac +} + #---------------------------- # Update a given module and all submodules from the upstream repo # Parameters: @@ -165,19 +330,64 @@ function _update_module() local SUBMOD_LIST="$MOD_PATH/.gitmodules" if [[ -e "$SUBMOD_LIST" ]]; then sed -n "s|^\[submodule \"\([^\"]*\)\"\]$|\1|p" <$SUBMOD_LIST |\ - while read -r SUBMOD_PATH; do + while read -r SUBMOD_STRING; do cd "$MOD_PATH" &>/dev/null - if [[ -z "`git config --get submodule.$SUBMOD_PATH.url`" ]]; then - eval git submodule init -- \"$SUBMOD_PATH\" $OPT_VERBOSE_LOG + if [[ -z "`git config --get submodule.$SUBMOD_STRING.url`" ]]; then + eval git submodule init -- \"$SUBMOD_STRING\" $OPT_VERBOSE_LOG fi - if [[ ! -e "$MOD_PATH/$SUBMOD_PATH/.git" ]]; then - eval git submodule update -- \"$SUBMOD_PATH\" $OPT_VERBOSE_LOG + if [[ ! -e "$MOD_PATH/$SUBMOD_STRING/.git" ]]; then + eval git submodule update -- \"$SUBMOD_STRING\" $OPT_VERBOSE_LOG fi - _update_module "$MOD_PATH/$SUBMOD_PATH" "$OP_TYPE" "$BRANCH" + _update_module "$MOD_PATH/$SUBMOD_STRING" "$OP_TYPE" "$BRANCH" done fi } +#---------------------------- +# Update a given module and all submodules from the upstream repo +# Parameters: +# $1 - module folder and name (excluding base repo part) +# $2 - list of branches to update +# $3 - parent module path +# $4 - module substring relative to parent +function _update_worktree_module() +{ + local MOD_FULLPATH=$1 + local MOD_NAME=`echo ${MOD_FULLPATH} | sed "s|^.*/\([^/]\+\)$|\1|"` + if [ -n "${MOD_FULLPATH}" -a -n "${MOD_NAME}" ]; then + local BRANCH_LIST=$2 + [ -n "${BRANCH_LIST}" ] || BRANCH_LIST="${UPDATE_BRANCHES}" + + # Current module + _do_worktree_update "${MOD_FULLPATH}" "fetch" + _do_worktree_update "${MOD_FULLPATH}" "check_worktree" "${BRANCH_LIST[@]}" + _do_worktree_update "${MOD_FULLPATH}" "check_module" "dummy arg" "$3" "$4" + _do_worktree_update "${MOD_FULLPATH}" "update" "${BRANCH_LIST[@]}" + + # Submodules + for LCL_BR in ${BRANCH_LIST}; do + local WORK_PATH="${WORKTREES_DIR}/${LCL_BR}/${MOD_FULLPATH}" + if [ -d ${WORK_PATH} ]; then + local SUBMOD_LIST="${WORK_PATH}/.gitmodules" + if [ -e "${SUBMOD_LIST}" ]; then + sed -n "s|^\[submodule \"\([^\"]*\)\"\]$|\1|p" <${SUBMOD_LIST} |\ + while read -r SUBMOD_STRING; do + cd "${WORK_PATH}" &>/dev/null + SUBMOD_NAME=`echo ${SUBMOD_STRING} | sed "s|.*/\([^/]\+\)$|\1|"` + SUBMOD_URLNAME=`git config --file .gitmodules --get submodule.${SUBMOD_STRING}.url | \ + sed "s|.*/\([^/]\+\)$|\1|"` + _do_worktree_update "${MOD_FULLPATH}/${SUBMOD_STRING}" "add_repo" "${SUBMOD_URLNAME}" + _update_worktree_module "${MOD_FULLPATH}/${SUBMOD_STRING}" "${LCL_BR}" "${WORK_PATH}" "${SUBMOD_STRING}" + done + fi + fi + done + else + echo -ne "\033[2K\r${COLOR_STRINGS["FAIL"]}${RESULT_STRINGS["FAIL"]} Invalid module $1 passed to _update_worktree_module()${CNone}\n" + echo "${RESULT_STRINGS["FAIL"]} Invalid module $1 passed to _update_worktree_module()" >> "$LOG_UPDATE_REPO_FILENAME" + fi +} + #---------------------------- if [ "$flag_INCREMENTAL" = "y" ]; then [ ! -f "$UPDATE_LOCK_FILENAME" ] && flag_INCREMENTAL="n" @@ -206,61 +416,91 @@ if [ "$flag_INCREMENTAL" != "y" ]; then echo "TDE repositories update started" > "$UPDATE_LOCK_FILENAME" fi -_LAST_BRANCH="" -if [[ "$flag_SWITCH_ONLY" != "y" ]]; then - # Update extra dependency repository - if [[ "$USE_PREBUILD_EXTRA_DEPS" != "y" ]]; then - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" - echo_and_tee "${CLightCyan} Fetching extra dependencies ${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" +if [ "${USE_GIT_WORKTREES}" != "y" ]; then + # Not using git worktree + _LAST_BRANCH="" + if [[ "$flag_SWITCH_ONLY" != "y" ]]; then + # Update extra dependency repository + if [[ "$USE_PREBUILD_EXTRA_DEPS" != "y" ]]; then + echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" + echo_and_tee "${CLightCyan} Fetching extra dependencies ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + + # Fetch TDE extra dependency repository + _update_module "$REPO_EXTRA_DEPENDENCIES" "fetch" + _update_module "$REPO_EXTRA_DEPENDENCIES" "update" "master" + + echo -e "\033[2K" + echo "" >> "$LOG_UPDATE_REPO_FILENAME" + fi + + # Fetch all remotes first + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" + echo_and_tee "${CLightCyan} Fetching repos ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" - # Fetch TDE extra dependency repository - _update_module "$REPO_EXTRA_DEPENDENCIES" "fetch" - _update_module "$REPO_EXTRA_DEPENDENCIES" "update" "master" + # Fetch TDE main repository + _update_module "$REPO_TDE" "fetch" echo -e "\033[2K" echo "" >> "$LOG_UPDATE_REPO_FILENAME" - fi - # Fetch all remotes first - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" - echo_and_tee "${CLightCyan} Fetching remotes ${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + # Branch update + for branch in "${BRANCHES[@]}"; do + _LAST_BRANCH="$branch" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan} Updating branch ${CYellow}$branch ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + + # Update TDE main repository + _update_module "$REPO_TDE" "update" "$branch" + + echo -e "\033[2K" + echo "" >> "$LOG_UPDATE_REPO_FILENAME" + done + fi - # Fetch TDE main repository - _update_module "$REPO_TDE" "fetch" + # Switch to specified branch if necessary + if [[ "$DEFAULT_REPO_BRANCH" != "$_LAST_BRANCH" ]]; then + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "$flag_SWITCH_ONLY" + echo_and_tee "${CLightCyan} Switching to branch ${CYellow}$DEFAULT_REPO_BRANCH ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo -e "\033[2K" - echo "" >> "$LOG_UPDATE_REPO_FILENAME" + # Switch TDE main repository + _update_module "$REPO_TDE" "switch-to" "$DEFAULT_REPO_BRANCH" + fi +else + # Using git worktree - # Branch update - for branch in "${BRANCHES[@]}"; do - _LAST_BRANCH="$branch" - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo_and_tee "${CLightCyan} Updating branch ${CYellow}$branch ${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + # Get TDE origin url + cd "${REPOS_DIR}/tde.git" &>/dev/null + ORIGIN_PATH=`git config --get remote.origin.url | sed "s|\(.*\)/tde.git$|\1|"` - # Update TDE main repository - _update_module "$REPO_TDE" "update" "$branch" + if [ ! -z "{ORIGIN_PATH}" ]; then + # Update extra dependency repository + if [[ "$USE_PREBUILD_EXTRA_DEPS" != "y" ]]; then + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" + echo_and_tee "${CLightCyan} Updating extra dependencies ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" - echo -e "\033[2K" - echo "" >> "$LOG_UPDATE_REPO_FILENAME" - done -fi + _update_worktree_module "edeps" -# Switch to specified branch if necessary -if [[ "$DEFAULT_REPO_BRANCH" != "$_LAST_BRANCH" ]]; then - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "$flag_SWITCH_ONLY" - echo_and_tee "${CLightCyan} Switching to branch ${CYellow}$DEFAULT_REPO_BRANCH ${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo_and_tee "${CLightCyan}---------------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo -e "\033[2K" + echo "" >> "$LOG_UPDATE_REPO_FILENAME" + fi - # Switch TDE main repository - _update_module "$REPO_TDE" "switch-to" "$DEFAULT_REPO_BRANCH" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" "y" + echo_and_tee "${CLightCyan} Updating TDE repos ${CNone}" "$LOG_UPDATE_REPO_FILENAME" + echo_and_tee "${CLightCyan}-------------------------------${CNone}" "$LOG_UPDATE_REPO_FILENAME" - echo -e "\033[2K" - echo "" >> "$LOG_UPDATE_REPO_FILENAME" + # Main repo + _update_worktree_module "tde" + fi fi +echo -e "\033[2K" +echo "" >> "$LOG_UPDATE_REPO_FILENAME" + # Update completed [ -f "$UPDATE_LOCK_FILENAME" ] && rm "$UPDATE_LOCK_FILENAME" cd $SCRIPT_DIR