Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

activate repos.json #398

Merged
merged 12 commits into from
Sep 23, 2024
109 changes: 80 additions & 29 deletions bin/_update-git
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,106 @@ exec 2>&1
source /etc/sysconfig/crucible

if [ -z "${CRUCIBLE_HOME}" ]; then
echo "CRUCIBLE_HOME not defined, exiting."
echo "ERROR: CRUCIBLE_HOME not defined!"
exit 1
fi

if [ ! -e "${CRUCIBLE_HOME}" ]; then
echo "Could not find ${CRUCIBLE_HOME}, exiting."
echo "ERROR: Could not find ${CRUCIBLE_HOME}!"
exit 1
fi

source "${CRUCIBLE_HOME}/bin/base"
source "${CRUCIBLE_HOME}/bin/jqlib"

REPO_FILE="${CRUCIBLE_HOME}/config/repos.json"

PROJECT=${1}
if [ -z "${PROJECT}" ]; then
echo "ERROR: You must supply a project name!"
exit 1
else
PROJECT_NAME=$(jq_query ${REPO_FILE} --arg project ${PROJECT} '.official[], .unofficial[] | select(.name == $project) | .name')
if [ "${PROJECT_NAME}" != "${PROJECT}" ]; then
echo "ERROR: You must supply a valid project name!"
exit 1
fi

PROJECT_REPOSITORY=$(jq_query ${REPO_FILE} --arg project ${PROJECT} '.official[], .unofficial[] | select(.name == $project) | .repository')
PROJECT_PRIMARY_BRANCH=$(jq_query ${REPO_FILE} --arg project ${PROJECT} '.official[], .unofficial[] | select(.name == $project) | ."primary-branch"')
PROJECT_CHECKOUT_MODE=$(jq_query ${REPO_FILE} --arg project ${PROJECT} '.official[], .unofficial[] | select(.name == $project) | .checkout.mode')
PROJECT_CHECKOUT_TARGET=$(jq_query ${REPO_FILE} --arg project ${PROJECT} '.official[], .unofficial[] | select(.name == $project) | .checkout.target')
fi

current_dir=$(pwd)
echo "Attempting to update project repo ${PROJECT_NAME} at '${current_dir}' -> '$(readlink -e ${current_dir})'"

if [ -d "./.git" ]; then
# validate that the current repository matches the expected repository
ORIGIN_REPOSITORY=$(git remote get-url origin)
if [ "${ORIGIN_REPOSITORY}" != "${PROJECT_REPOSITORY}" ]; then
echo "ERROR: Invalid state! The origin repository does not match the project repository!"
exit 1
fi

current_ref=$(git rev-parse --verify HEAD)
expected_ref=$(git rev-parse --verify ${PROJECT_CHECKOUT_TARGET})

if [ "${current_ref}" != "${expected_ref}" ]; then
echo "ERROR: Invalid state! The current checked out ref (${current_ref}) does not match the checkout target's ref (${PROJECT_CHECKOUT_TARGET} -> ${expected_ref})!"
exit 1
fi

# fetch updates from remote(s)
if ! git remote --verbose update --prune > /dev/null 2>&1; then
echo "ERROR: could not git-update"
git_fetch_cmd="git fetch --all --prune --prune-tags --tags --verbose"
echo "${git_fetch_cmd}"
if ! ${git_fetch_cmd} 2>&1; then
echo "ERROR: could not git-fetch"
exit 1
fi

git_status=$(git_get_status)
git_local_branch=$(git_get_local_branch "${git_status}")
git_tracking=$(git_get_tracking "${git_status}")
# store any local changes
stash_output=$(git stash)
if [ $? != 0 ]; then
echo "ERROR: could not git-stash"
exit 1
fi

if [ -n "${git_tracking}" -a "${git_local_branch}" != "(detached)" ]; then
# store any local changes
stash_output=$(git stash)
if [ $? != 0 ]; then
echo "ERROR: could not git-stash"
exit 1
fi
# return to the primary branch so that we can then return to the
# checkout target in case it's reference has changed (ie. an
# updated tag)
echo "Switching to primary branch to quiesce the repository state"
git checkout ${PROJECT_PRIMARY_BRANCH}

# merge any changes from the remote branch
if ! git pull --verbose --ff-only 2> /dev/null; then
echo "ERROR: could not git-pull"
exit 1
fi
# return to the checkout target if it is not the primary branch
if [ "${PROJECT_PRIMARY_BRANCH}" != "${PROJECT_CHECKOUT_TARGET}" ]; then
echo "Returning to the checkout target"
git -c advice.detachedHead=false checkout ${PROJECT_CHECKOUT_TARGET}
fi

if ! echo "${stash_output}" | grep -q "No local changes to save"; then
# reapply local changes
if ! git stash pop > /dev/null; then
echo -e "${stash_output}"
echo "ERROR: could not git-stash pop"
if [ "${PROJECT_CHECKOUT_MODE}" == "locked" ]; then
# return to the previous ref if is supposed to be locked there
echo "Returning to the previously checked out ref since I am in locked mode"
git checkout ${current_ref}
k-rister marked this conversation as resolved.
Show resolved Hide resolved
elif [ "${PROJECT_CHECKOUT_MODE}" == "follow" ]; then
if [ "${PROJECT_CHECKOUT_TARGET}" == "HEAD" ]; then
echo "Detected CI environment, skipping merge of changes from the remote branch (because they do not exist)"
else
# merge any changes from the remote branch
echo "Merging any available upstream changes because I am in follow mode"
if ! git pull --verbose --ff-only 2> /dev/null; then
echo "ERROR: could not git-pull"
exit 1
fi
fi
else
if [ "${git_local_branch}" == "(detached)" ]; then
echo "WARNING: This git repo is in a detached state, not modifying the active contents"
else
echo "ERROR: This git repo is in an unknown state"
fi

if ! echo "${stash_output}" | grep -q "No local changes to save"; then
# reapply local changes
echo "Reapplying stashed local changes"
if ! git stash pop > /dev/null; then
echo -e "${stash_output}"
echo "ERROR: could not git-stash pop"
exit 1
fi
fi
Expand Down
14 changes: 14 additions & 0 deletions bin/base
Original file line number Diff line number Diff line change
Expand Up @@ -944,3 +944,17 @@ function git_get_remote_name() {
function git_get_remote_branch() {
echo "${1}" | awk -F'/' '{ print $2 }'
}

# map a project type to it's actual on disk directory name
function get_project_type_dir() {
local TYPE
TYPE=$1

case "${TYPE}" in
benchmark|tool|doc)
echo "${TYPE}s"
;;
*)
echo "${TYPE}"
esac
}
65 changes: 40 additions & 25 deletions bin/update
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ if [ ! -e $CRUCIBLE_HOME ]; then
exit 1
fi

. $CRUCIBLE_HOME/bin/base
source ${CRUCIBLE_HOME}/bin/base
source ${CRUCIBLE_HOME}/bin/jqlib

REPO_FILE=${CRUCIBLE_HOME}/config/repos.json

help_column_width=25

Expand All @@ -30,12 +33,9 @@ function help() {
printf "%-${help_column_width}s | Update the main crucible repository\n" "crucible"
printf "%-${help_column_width}s | Update the controller container image\n" "controller-image"
echo
if pushd $CRUCIBLE_HOME/subprojects > /dev/null; then
for repo in $(find . -type l | sed 'sX./XX'); do
printf "%-${help_column_width}s | Update the %s repository\n" "${repo}" "${repo}"
done
popd > /dev/null
fi
for project in $(jq_query ${REPO_FILE} '.official[], .unofficial[] | select(.name != "crucible") | .name'); do
printf "%-${help_column_width}s | Update the %s repository\n" "${project}" "${project}"
done
echo
}

Expand Down Expand Up @@ -82,7 +82,7 @@ case "${repo}" in
echo "rm ${TMP_SCRIPT}" >> ${TMP_SCRIPT}
echo "exec ${CRUCIBLE_HOME}/bin/update __${repo}" >> ${TMP_SCRIPT}

exec ${TMP_SCRIPT}
exec ${TMP_SCRIPT} crucible
else
echo "ERROR: failed to pushd to ${CRUCIBLE_HOME}"
exit 1
Expand Down Expand Up @@ -116,48 +116,61 @@ case "${repo}" in
fi
;;
*)
repo_dir=$(find ${CRUCIBLE_HOME}/subprojects -maxdepth 2 -mindepth 2 -name ${repo} -type l)
if [ -n "${repo_dir}" ]; then
PROJECT_NAME=$(jq_query ${REPO_FILE} --arg project ${repo} '.official[], .unofficial[] | select(.name == $project) | .name')
if [ "${PROJECT_NAME}" != "${repo}" ]; then
echo "ERROR: You must supply a valid project name!"
exit 1
fi
PROJECT_TYPE=$(jq_query ${REPO_FILE} --arg project ${repo} '.official[], .unofficial[] | select(.name == $project) | .type')

repo_dir=${CRUCIBLE_HOME}/subprojects/$(get_project_type_dir ${PROJECT_TYPE})/${PROJECT_NAME}
if [ -n "${repo_dir}" -a -L "${repo_dir}" ]; then
echo
echo "Updating ${repo}:"
echo "Updating ${PROJECT_NAME}:"
echo

if pushd "${repo_dir}" > /dev/null; then
if $CRUCIBLE_HOME/bin/_update-git; then
if $CRUCIBLE_HOME/bin/_update-git ${PROJECT_NAME}; then
exit 0
else
exit 1
fi
else
echo "Could not pushd to ${repo_dir}"
echo "ERROR: Could not pushd to ${repo_dir}!"
exit 1
fi
else
echo "Invalid repo '${repo}'."
echo "ERROR: Invalid project directory '${repo_dir}'!"
exit 1
fi
;;
esac

if [ "${repo}" == "____all" ]; then
if pushd ${CRUCIBLE_HOME}/subprojects > /dev/null; then
for tmp_repo in $(find . -maxdepth 2 -mindepth 2 -type l | sed 'sX./XX'); do
for project in $(jq_query ${REPO_FILE} '.official[], .unofficial[] | select(.name != "crucible") | .name'); do
PROJECT_NAME=$(jq_query ${REPO_FILE} --arg project ${project} '.official[], .unofficial[] | select(.name == $project) | .name')
PROJECT_TYPE=$(jq_query ${REPO_FILE} --arg project ${project} '.official[], .unofficial[] | select(.name == $project) | .type')

repo_dir=${CRUCIBLE_HOME}/subprojects/$(get_project_type_dir ${PROJECT_TYPE})/${PROJECT_NAME}
if [ -n "${repo_dir}" -a -L "${repo_dir}" ]; then
echo
echo "Updating ${tmp_repo}:"
echo "Updating ${PROJECT_NAME}:"
echo

if pushd ${tmp_repo} > /dev/null; then
if ! $CRUCIBLE_HOME/bin/_update-git; then
if pushd ${repo_dir} > /dev/null; then
if ! $CRUCIBLE_HOME/bin/_update-git ${PROJECT_NAME}; then
RC=1
fi
popd > /dev/null
else
echo "ERROR: Could not pushd to ${repo_dir}!"
RC=1
fi
done
popd > /dev/null
else
echo "Could not pushd to ${CRUCIBLE_HOME}/subprojects"
exit 1
fi
else
echo "ERROR: Invalid project directory '${repo_dir}'!"
RC=1
fi
done
fi

case "${repo}" in
Expand All @@ -177,5 +190,7 @@ esac

echo
${CRUCIBLE_HOME}/bin/repo info
echo
${CRUCIBLE_HOME}/bin/repo config show

exit ${RC}