This repository has been archived by the owner on May 20, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
git-submodules-status
executable file
·125 lines (100 loc) · 4.18 KB
/
git-submodules-status
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash
#
# Boost Software License 1.0 (https://www.boost.org/LICENSE_1_0.txt)
# Copyright (c) 2016-2018 dunnhumby Germany GmbH.
# All rights reserved.
################################################################################
#
# Description:
# ------------
# Fetches all submodules from their respective remote repositories, and
# shows a table that lists for each submodule : the latest available
# version, the current version and a small visual cue to easily identify
# mismatches between the two.
#
# Usage:
# ------
# (first place this script in one of the directories in $PATH)
# $> cd path/to/repo
# $> git submodules-status
#
################################################################################
appendSpaces()
{
INITIAL_STR=${1}
TARGET_LENGTH=${2}
SPACES_TO_APPEND=$((TARGET_LENGTH - ${#INITIAL_STR}))
echo -n ${INITIAL_STR}
for ((i = 0; i < ${SPACES_TO_APPEND}; i++))
do
echo -n " "
done
echo ""
}
# Confirm that we are in a git repository
GIT_TOP=$(git rev-parse --show-toplevel) || exit $?
# Check if the project has any submodules in the first place
if ! [ -a "${GIT_TOP}/.gitmodules" ]; then
PROJECT_NAME=$(basename ${GIT_TOP})
echo "Project '${PROJECT_NAME}' has no submodules. Nothing to do here!"
exit 0
fi
# Save the present working directory as we'll be changing directories
# (potentially several times)
ORIG_DIR=${PWD}
# cd to the top-level git directory so that submodule paths are relative to it
cd ${GIT_TOP}
# Confirm that all the submodules have been initialised
UNINITIALISED_SUBMODS=(`git submodule status | grep "^-" | awk -F"/" '{print $NF}'`)
if [ ${#UNINITIALISED_SUBMODS[@]} -gt 0 ]; then
echo "The following submodules haven't been initialized : ${UNINITIALISED_SUBMODS[@]}"
echo "Try running this first:"
echo " git submodule update --init"
exit 2
fi
# Read the existing submodules information into an array. After this, the array
# should contain an even number of entries, with each pair of entries containing
# the path of the submodule (relative to the top-level git directory) and the
# current submodule version (within parentheses) respectively.
SUBMODS_INFO_ARR=(`git submodule status | sed 's/^\s\+//g' | cut -d" " -f2-`)
# Fetch each submodule from the remote repo so that we can get its latest tag
git submodule foreach git remote update
echo ""
# Get the length of the longest submodule name
MAX_LEN=9 # Initialize to length of the header string "Submodule"
for ((i = 0; i < ${#SUBMODS_INFO_ARR[@]}; i+=2))
do
SUBMOD_PATH=${SUBMODS_INFO_ARR[$i]}
SUBMOD_NAME=$(echo ${SUBMOD_PATH} | rev | cut -d"/" -f1 | rev)
SUBMOD_NAME_LEN=${#SUBMOD_NAME}
if [ ${SUBMOD_NAME_LEN} -gt ${MAX_LEN} ]
then
MAX_LEN=${SUBMOD_NAME_LEN}
fi
done
FIRST_COLUMN_WIDTH=$((${MAX_LEN}+4))
# For now, the width of the second column is hard-coded to 19
# i.e. length of the string "Current version" + 4
SECOND_COLUMN_WIDTH=19
# Also, the width of the third column is hard-coded to 12
# i.e. length of the string "Latest version" - 2
# so that the '✗' which indicates a difference between the two versions can
# appear as the last character of the "Latest version" column
THIRD_COLUMN_WIDTH=12
# Write the header row and its underlines
echo "$(appendSpaces "Submodule" ${FIRST_COLUMN_WIDTH}) Current version Latest version"
echo "--------- --------------- --------------"
# Write each submodule's data
for ((i = 0; i < ${#SUBMODS_INFO_ARR[@]}; i+=2))
do
SUBMOD_PATH=${SUBMODS_INFO_ARR[$i]}
SUBMOD_VERSION=$(echo ${SUBMODS_INFO_ARR[$i+1]} | sed 's/^(\(.*\))$/\1/g')
SUBMOD_NAME=$(echo ${SUBMOD_PATH} | rev | cut -d"/" -f1 | rev)
SUBMOD_FULL_PATH="${GIT_TOP}/${SUBMOD_PATH}"
cd ${SUBMOD_FULL_PATH}
LATEST_TAG=$(git tag --list "v*" --sort=v:refname | tail -1)
MISMATCH_CHARACTER=$([ "${SUBMOD_VERSION}" = "${LATEST_TAG}" ] && echo " " || echo "✗")
echo "$(appendSpaces ${SUBMOD_NAME} ${FIRST_COLUMN_WIDTH}) $(appendSpaces ${SUBMOD_VERSION} ${SECOND_COLUMN_WIDTH}) $(appendSpaces ${LATEST_TAG} ${THIRD_COLUMN_WIDTH}) ${MISMATCH_CHARACTER}"
done
# Go back to the original directory from where the script was run
cd ${ORIG_DIR}