You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcpcfg/scripts/clean

376 lines
8.7 KiB

#!/bin/bash
# Purpose: clean ngcpcfg config/templates
################################################################################
set -e
set -u
# support testsuite
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
SCRIPTS="${SCRIPTS:-/usr/share/ngcp-ngcpcfg/scripts/}"
if ! [ -r "${FUNCTIONS}"/main ] ; then
printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}" >&2
exit 1
fi
# shellcheck disable=SC1090
. "${FUNCTIONS}"/main
cd "${NGCPCTL_MAIN}"
## functions {{{
clean_help() {
export TIME_FORMAT=''
log_info "Sample:"
log_info " ngcpcfg clean [--all] [--branches] [--force] [--help] [--reset-master] [--stashes] [--tracked-files] [--untracked-files]"
log_info ""
log_info "Run 'man ngcpcfg' for more information."
}
request_confirmation() {
if "${force:-false}" ; then
log_info "Forcing action due to option '--force'"
return 0
fi
if ! tty -s; then
log_warn "Cannot request confirmation (no tty). Hint: use option '--force'."
return 1
fi
log_info_n "Please confirm 'yes' or 'no': "
# clearing STDIN
while read -r -t 0; do read -r; done
while true ; do
read -r a
case "${a,,}" in
yes) return 0 ;;
no) return 1 ;;
*) log_info_n "Please answer 'yes' or 'no': " ;;
esac
unset a
done
}
clean_ensure_branch_master () {
log_info "Ensure local branch is 'master':"
local current_branch
log_debug "Call: compare_active_branch 'master'"
current_branch=$(compare_active_branch 'master')
if [ "${current_branch}" = 'master' ] ; then
log_info "OK: branch master active"
else
log_debug "git checkout master"
if git checkout master ; then
log_info "OK: checked out branch master "
else
log_error "Cannot checkout branch 'master'"
return 1
fi
fi
return 0
}
clean_tracked() {
log_info "Removing all local changes (if any):"
if is_git_clean ; then
log_info "OK: no local changes found, nothing to clean here."
return 0
fi
log_info "Found local changes in '${NGCPCTL_MAIN}':"
log_debug "git status -s -uall"
git status -s -uall
log_info "Should we remove changes above?"
if ! request_confirmation ; then
log_info "Skipping cleanup of local changes as requested."
return 0
fi
log_debug "git reset --hard HEAD"
if git reset --hard HEAD ; then
log_info "OK: Done"
else
log_error "Cannot reset local changes"
return 1
fi
return 0
}
clean_untracked() {
log_info "Removing all untracked files (if any):"
local tmp
tmp=$(mktemp -t ngcpcfg-clean-untracked.XXXXXXXXXX)
log_debug "git clean -n -f -d -x -e sites/current"
if ! git clean -n -f -d -x -e sites/current > "${tmp}" ; then
log_error "Failed to collect list of untracked files"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No untracked files found, nothing to clean here."
return 0
fi
log_info "Found untracked files in '${NGCPCTL_MAIN}':"
cat "${tmp}"
log_info "Should we remove untracked files above?"
if ! request_confirmation ; then
log_info "Skipping cleanup of untracked files as requested."
return 0
fi
log_debug "git clean -f -d -x -e sites/current"
if ! git clean -f -d -x -e sites/current ; then
log_error "Failed to clean list of untracked files"
return 1
fi
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_stash() {
log_info "Removing all stashes (if any):"
local tmp
tmp=$(mktemp -t ngcpcfg-clean-stash.XXXXXXXXXX)
log_debug "git stash list"
if ! git stash list > "${tmp}" ; then
log_error "Failed to collect list of stashes"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No stashes found, nothing to clean here."
return 0
fi
log_info "Found stashes in '${NGCPCTL_MAIN}':"
cat "${tmp}"
log_info "Should we remove the stashes above?"
if ! request_confirmation ; then
log_info "Skipping stash cleanup as requested."
return 0
fi
log_debug "git stash clear"
if ! git stash clear ; then
log_error "Failed to clean git stashes"
return 1
fi
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_old_local_branches() {
log_info "Removing all old branches (if any):"
local tmp
tmp=$(mktemp -t ngcpcfg-clean-oldbranch.XXXXXXXXXX)
log_debug "git branch"
if ! git branch > "${tmp}" ; then
log_error "Failed to collect list of available branches"
return 1
fi
# do not propose to delete active branch and branch 'master'
sed -i -r '/^\* /d' "${tmp}"
sed -i -r '/ master$/d' "${tmp}"
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No branches to delete found, nothing to clean here."
return 0
fi
log_info "Found branches to be removed:"
cat "${tmp}"
log_info "Should we remove the branches above?"
if ! request_confirmation ; then
log_info "Skipping branches cleanup as requested."
return 0
fi
while read -r branch ; do
log_debug "git branch -D '${branch}'"
if ! git branch -D "${branch}" ; then
log_error "Failed to delete local branch '${branch}'"
return 1
fi
done < "${tmp}"
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_reset_master() {
log_debug "checking 'origin' availability using: git remote show origin"
if ! git remote show origin >/dev/null 2>&1 ; then
log_error "Missing git origin 'origin'. Aborting"
return 1
fi
local tmp
tmp=$(mktemp -t ngcpcfg-clean-reset.XXXXXXXXXX)
log_debug "git diff origin/master..master"
if ! git diff origin/master..master > "${tmp}" ; then
log_error "Failed to collect diff of 'origin/master' and 'master' branches"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No committed and push pending changes found, nothing to clean here."
return 0
fi
log_info "Found committed local changes to be removed:"
cat "${tmp}"
log_info "Should we restore branch 'master' from origin to remove local commit?"
if ! request_confirmation ; then
log_info "Skipping restore branch 'master' from origin as requested."
return 0
fi
log_info "Restoring branch 'master' from origin:"
local new_branch
new_branch="ngcpcfg_backup_$(date +%s)"
log_debug "git branch -m '${new_branch}'"
if ! git branch -m "${new_branch}" ; then
log_error "Cannot rename current branch to '${new_branch}'. Aborting"
return 1
fi
log_info "OK: renamed current branch to '${new_branch}'. Feel free to clean it."
log_debug "git checkout -b master --track origin/master"
if ! git checkout -b master --track origin/master ; then
log_error "Cannot checkout branch 'master'"
return 1
fi
log_info "OK: created local branch 'master' to track 'origin/master'"
return 0
}
## }}}
RC=0
branches=false
force=false
help=false
reset_master=false
stashes=false
tracked_files=false
untracked_files=false
clean_options="all,branches,force,help,reset-master,stashes,tracked-files,untracked-files"
if ! _opt_temp=$(getopt --name "$0" -o +h --long ${clean_options} -- "$@") ; then
log_error "Try 'ngcpcfg clean --help' for more information."
exit 1
fi
eval set -- "${_opt_temp}"
[ "$1" = "--" ] && help=true
while : ; do
case "$1" in
--all)
branches=true
reset_master=true
stashes=true
tracked_files=true
untracked_files=true
;;
--branches) branches=true ;;
--force) force=true ;;
--help) help=true ;;
--reset-master) reset_master=true ;;
--stashes) stashes=true ;;
--tracked-files) tracked_files=true ;;
--untracked-files) untracked_files=true ;;
--) shift ; break ;;
*) log_error "Unknown option '$1'" ; exit 1 ;;
esac
shift
done
if ${help} ; then
clean_help
exit 0
fi
if [ ! -f "${FUNCTIONS}/ha_features" ] ; then
log_debug "Skip function 'clean_reset_master'. It is for HA installation only."
reset_master=false
fi
if ! clean_ensure_branch_master ; then
exit 1
fi
if ${tracked_files} ; then
clean_tracked || RC=$((RC + $?))
fi
if ${untracked_files} ; then
clean_untracked || RC=$((RC + $?))
fi
if ${stashes} ; then
clean_stash || RC=$((RC + $?))
fi
if ${reset_master} ; then
clean_reset_master || RC=$((RC + $?))
fi
if ${branches} ; then
clean_old_local_branches || RC=$((RC + $?))
fi
if [ "${RC}" = "0" ] ; then
log_info "All operations were finished successfully. Good to be clean!"
else
log_error "Some operations finished with an error, see details above."
fi
exit "${RC}"
## END OF FILE #################################################################