242 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash
 | 
						|
# set -x 
 | 
						|
 | 
						|
source ./log_helpers.sh
 | 
						|
 | 
						|
GIT_SSL_NO_VERIFY=true
 | 
						|
 | 
						|
#
 | 
						|
exec_git_command () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    
 | 
						|
    log_debug "$func:${LINENO} exec-ing $1"
 | 
						|
 | 
						|
    exec {fd}< <($1)
 | 
						|
    local ps_pid=$!             # remember pid of process substitution
 | 
						|
 | 
						|
    local git_result=""
 | 
						|
    while read t <&$fd; do
 | 
						|
        if ! [ -z "$t" ]; then
 | 
						|
            git_result="${git_result}$t"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
        
 | 
						|
    exec {fd}>&-                # close fd (i.e. process substitution)
 | 
						|
    wait $ps_pid                # wait for the subshell to finish
 | 
						|
 | 
						|
    git_result=$(printf "$git_result" | tr '\n' ' ')
 | 
						|
    printf "%s\n" $git_result
 | 
						|
}
 | 
						|
 | 
						|
# 
 | 
						|
latest_commit () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    # git reflog -> 46c5896 HEAD@{0}: commit: Made update_helpers.sh executable
 | 
						|
    local c=$(git reflog | grep "HEAD@{0}" | cut -d" " -f1)
 | 
						|
    if ! [ -z "$c" ]; then
 | 
						|
        if grep -qE "^[[:xdigit:]]{6,}$" <<< $c; then
 | 
						|
            log_debug "$func: commit -> $c"
 | 
						|
            printf "%s\n" $c
 | 
						|
        else
 | 
						|
            log_crit "$func: wrong format for commit c=$c"
 | 
						|
            printf ""
 | 
						|
        fi
 | 
						|
    else 
 | 
						|
        log_crit "$func: 'git reflog' result empty"
 | 
						|
        printf ""
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
# fallback if something went wrong: revert to last valid commit
 | 
						|
revert_to_commit_before_pull () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    if ! [ -z "$commit_before_pull" ]; then
 | 
						|
        if grep -qE "^[[:xdigit:]]{6,}$" <<< $commit_before_pull; then
 | 
						|
            `git reset --hard "$commit_before_pull"`
 | 
						|
            if [ $? -eq 0 ]; then
 | 
						|
                log_info "$func: git reset --hard $commit_before_pull"
 | 
						|
                return 0
 | 
						|
            fi
 | 
						|
            log_crit "$func: 'git reset --hard $commit_before_pull' failed!"
 | 
						|
        fi
 | 
						|
        log_crit "$func: wrong format for commit_before_pull"
 | 
						|
    fi
 | 
						|
    log_crit "$func: empty commit_before_pull"
 | 
						|
    return 1
 | 
						|
}
 | 
						|
# revert_to_commit_before_pull
 | 
						|
 | 
						|
# clone the customer repository in ./UpdateController/workspace.
 | 
						|
# this is done only once.
 | 
						|
clone_customer_repository () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    current_dir=${PWD##*/}
 | 
						|
    current_dir="./${current_dir:-/}"
 | 
						|
    if [ "$current_dir" = "./UpdateController" ]; then
 | 
						|
        if ! [[ -d ./workspace ]]; then
 | 
						|
            { mkdir -p ./workspace; }
 | 
						|
        fi
 | 
						|
        # check if the directory is empty. If so, clone the
 | 
						|
        # customer repository
 | 
						|
        if ! find ./workspace -mindepth 1 -maxdepth 1 | read; then
 | 
						|
            log_debug "$func: cloning ${1} ..."
 | 
						|
            ( cd ./workspace && git clone "$1" ; )
 | 
						|
            if [ $? -eq 0 ]; then
 | 
						|
                log_debug "$func: cloning ${1} done"
 | 
						|
                return 0
 | 
						|
            fi
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
# clone_customer_repository ->
 | 
						|
# https://git.mimbach49.de/GerhardHoffmann/customer_281.git
 | 
						|
 | 
						|
cd_customer_repository () {
 | 
						|
    # has to be called in ./UpdateController
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    current_dir=${PWD##*/}
 | 
						|
    current_dir="./${current_dir:-/}"
 | 
						|
    if [ "$current_dir" = "./UpdateController" ]; then
 | 
						|
        repository_dir="./workspace/${customer_id}"
 | 
						|
        if ! [[ -d "$repository_dir" ]]; then
 | 
						|
            log_crit "$func:${LINENO}: $repository_dir does not exist!"
 | 
						|
            return 1
 | 
						|
        fi
 | 
						|
        
 | 
						|
        if ! cd $repository_dir; then
 | 
						|
            log_crit "$func:${LINENO}: cannot change to $repository_dir!"
 | 
						|
            return 1
 | 
						|
        fi
 | 
						|
 | 
						|
        log_debug "$func:${LINENO}: cd to $repository_dir!"
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
 | 
						|
cd_home () {
 | 
						|
    if cd - &>/dev/null ; then
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    return 1
 | 
						|
}
 | 
						|
 | 
						|
pull_customer_repository () {
 | 
						|
    # has to be called in ./UpdateController
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
 | 
						|
    if ! cd_customer_repository ; then
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    local commit_before_pull=$(latest_commit)
 | 
						|
    if [ -z $commit_before_pull ]; then
 | 
						|
        cd_home ; return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    log_debug "$func:${LINENO}: commit_before_pull=$commit_before_pull"
 | 
						|
 | 
						|
    exec {fd}< <(git pull)
 | 
						|
    local ps_pid=$!             # remember pid of process substitution
 | 
						|
 | 
						|
    local git_result=""
 | 
						|
    while read t <&$fd; do
 | 
						|
        if ! [ -z "$t" ]; then
 | 
						|
            git_result="${git_result}$t"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
        
 | 
						|
    exec {fd}>&-                # close fd (i.e. process substitution)
 | 
						|
    wait $ps_pid                # wait for the subshell to finish
 | 
						|
 | 
						|
    if [ -z "$git_result" ]; then
 | 
						|
        log_warn "$func:${LINENO}: git result empty" ; cd_home;
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    log_debug "$func:${LINENO} git-pull-result=${git_result}"
 | 
						|
 | 
						|
    if [ "$git_result" = "Already up to date." ]; then
 | 
						|
        log_warn "$func:${LINENO}: $PWD already up to date."
 | 
						|
        cd_home ; return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    local commit_after_pull=$(latest_commit)
 | 
						|
    if [ -z $commit_after_pull ]; then
 | 
						|
        cd_home ; return 1
 | 
						|
    fi
 | 
						|
        
 | 
						|
    log_debug "$func:${LINENO}: commit_after_pull=$commit_after_pull"
 | 
						|
 | 
						|
    # Note: # 'git pull' is a 'git fetch' followed by a 'git merge'.
 | 
						|
    # Here's the fetch portion:
 | 
						|
    #
 | 
						|
    # remote: Counting objects: 11, done.
 | 
						|
    # remote: Compressing objects: 100% (5/5), done.
 | 
						|
    # remote: Total 7 (delta 2), reused 0 (delta 0)
 | 
						|
    #
 | 
						|
    # At this point, you've told the remote what you want.
 | 
						|
    # It finds all the objects it needs to give you,
 | 
						|
    # compresses them for faster transfer over the network,
 | 
						|
    # and then reports what it's sending you.
 | 
						|
    # 
 | 
						|
    # Unpacking objects: 100% (7/7), done.
 | 
						|
    # 
 | 
						|
    # You receive the pack (set of compressed objects) and unpack it.
 | 
						|
    #
 | 
						|
    # From ssh://my.remote.host.com/~/git/myproject
 | 
						|
    # * branch            master     -> FETCH_HEAD
 | 
						|
 | 
						|
    # You've fetched the branch 'master' from the given remote;
 | 
						|
    # the ref FETCH_HEAD now points to it.
 | 
						|
    # Now we move on to the merge - precisely, git will merge
 | 
						|
    # FETCH_HEAD (the remote's master branch) into your current branch
 | 
						|
    # (presumably master).
 | 
						|
    #
 | 
						|
    #######################################################################
 | 
						|
    # here starts "message"
 | 
						|
    # 
 | 
						|
    # Updating 9d447d2..f74fb21
 | 
						|
    # Fast forward
 | 
						|
    #
 | 
						|
    # It turns out that you haven't diverged from the remote's master branch,
 | 
						|
    # so the merge is a fast-forward (a trivial merge where it simply moves
 | 
						|
    # you forward in the history).
 | 
						|
    #
 | 
						|
    # Git notes the original position of your master branch (9d447d2)
 | 
						|
    # and the new position (f74fb21) it's been fast-forwarded to.
 | 
						|
    # If you had diverged from the remote's master branch,
 | 
						|
    # you'd see the output of a recursive merge here - Merge made
 | 
						|
    # by recursive, possibly along with some Auto-merged <file>
 | 
						|
    # and (oh no!) merge conflicts!
 | 
						|
    #
 | 
						|
    # szeged/1/1/etc/psa_config/device.conf | 13 +++++++------
 | 
						|
    # szeged/update.conf                    |  2 +-
 | 
						|
    # 2 files changed, 8 insertions(+), 7 deletions(-)
 | 
						|
    #  
 | 
						|
    # Finally, it shows you the diffstat between the original and post-merge
 | 
						|
    # position of your master branch;
 | 
						|
    # this is basically what you'd get from
 | 
						|
    #
 | 
						|
    # git diff --stat master@{1} master.
 | 
						|
    # 
 | 
						|
 | 
						|
    update_commit="${commit_before_pull}..${commit_after_pull}"
 | 
						|
    if ! grep -qE ".*Updating\s+${update_commit}.*?" <<< $git_result; then
 | 
						|
        log_crit "$func:${LINENO}: no $update_commit in [ $git_result ]"
 | 
						|
        cd_home ; return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    return 0
 | 
						|
}
 | 
						|
# pull_customer_repository customer_281
 | 
						|
 | 
						|
changed_files () {
 | 
						|
    local func="${FUNCNAME[0]}"
 | 
						|
    if  cd_customer_repository ; then
 | 
						|
        printf "%s\n" $(exec_git_command 'git diff --stat master@{1} master')
 | 
						|
        cd_home
 | 
						|
    fi
 | 
						|
}
 |