-
Notifications
You must be signed in to change notification settings - Fork 26
/
git-cms-addpkg
executable file
·289 lines (266 loc) · 8.62 KB
/
git-cms-addpkg
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
#! /bin/bash -e
# Mimics addpkg behavior in git.
case `uname` in
Darwin)
ECHO="echo" ;;
*)
ECHO="echo -e" ;;
esac
usage () {
COMMAND_NAME=$1
$ECHO "git $COMMAND_NAME [options] Subsystem/Package [Subsystem/Package ...] "
$ECHO "git $COMMAND_NAME [options] -f FILE"
$ECHO
$ECHO "Options:"
$ECHO "-h, --help \tthis help message"
$ECHO
$ECHO "-d, --debug \tenable debug output"
$ECHO "-f, --file FILE \tread the list of packages to be checked out from FILE"
$ECHO "-q, --quiet, -z \tdo not print out progress"
if [ "$COMMAND_NAME" == "cms-addpkg" ]; then
$ECHO " --https \tuse https, rather than ssh to access your personal repository"
$ECHO " --ssh \tuse ssh, rather than https to access the official repository"
$ECHO "-y, --yes \tassume yes to all questions"
elif [ "$COMMAND_NAME" == "cms-rmpkg" ]; then
$ECHO "-o, --force \tforce removal of packages even if modified or containing untracked files"
fi
exit $2
}
COMMAND_NAME=$(basename $0 | sed -e's/^git-//')
ACTION="Checking out"
if [ "$COMMAND_NAME" = "cms-rmpkg" ]; then
RMPKG=true
ACTION="Removing"
fi
DEBUG=0
VERBOSE=1
INITOPTIONS="" # options passed to git cms-init
PACKAGES=
INPUT_FILE=
FORCE=
# colors and formatting
RED='\033[31m'
NORMAL='\033[0m'
verbose () {
if [ "X$VERBOSE" = X1 ]; then
$ECHO "$@"
fi
}
while [ "$#" != 0 ]; do
case "$1" in
-h | --help )
usage $COMMAND_NAME 0;;
-d | --debug )
INITOPTIONS="$INITOPTIONS $1"
shift; set -x; DEBUG=1 ;;
-f | --file )
OPTION=$1; shift
INPUT_FILE="$1"; shift
if [ ! "$INPUT_FILE" ]; then
$ECHO "git cms-addpkg: option $OPTION requires an argument"
$ECHO
usage 1
elif [ ! -r "$INPUT_FILE" ]; then
$ECHO "git cms-addpkg: file $INPUT_FILE does not exist or is not readable"
$ECHO
usage $COMMAND_NAME 1
fi
unset OPTION
;;
-q | --quiet | -z )
INITOPTIONS="$INITOPTIONS $1"
shift; set +x; DEBUG=0; VERBOSE=0 ;;
-y | --yes )
INITOPTIONS="$INITOPTIONS $1"
shift;;
--https )
INITOPTIONS="$INITOPTIONS $1"
shift;;
--ssh )
INITOPTIONS="$INITOPTIONS $1"
shift;;
-o | --force )
FORCE=true
shift;;
-*)
$ECHO "git cms-addpkg: unknown option $1"; $ECHO; usage $COMMAND_NAME 1;;
*)
if [ "$INPUT_FILE" == "" ]; then
# check out a list of packages
PACKAGES="$PACKAGES $1"
shift
else
# check out a list of packages via -f / --file FILE
$ECHO "git $COMMAND_NAME: you cannot specify a package and input from file at the same time."
$ECHO
usage $COMMAND_NAME 1
fi
;;
esac
done
if [ "$PACKAGES" == "" ] && [ "$INPUT_FILE" == "" ] ; then
$ECHO "git $COMMAND_NAME: you need to specify at least one package or input file."
$ECHO
usage $COMMAND_NAME 1
fi
checkPkgs () {
PACKAGES="$1"
CURRENT_BRANCH="$2"
for PKG_NAME in $PACKAGES; do
if [ ! -d "$CMSSW_BASE/src/$PKG_NAME" ]; then
[ "$HEADER" ] || { $ECHO "\nThese packages do not exist in branch $CURRENT_BRANCH"; HEADER=done; }
echo $PKG_NAME
fi
done
if [ "$COMMAND_NAME" == "cms-rmpkg" ]; then
for PKG_NAME in $PACKAGES; do
UNTK=`git clean -xdn $CMSSW_BASE/src/$PKG_NAME`
if [ -n "$UNTK" ]; then
[ "$HEADER2" ] || { $ECHO "\nThese packages contain untracked files"; HEADER2=done; }
echo $PKG_NAME
if [ -n "$FORCE" ]; then
git clean -xdf $CMSSW_BASE/src/$PKG_NAME > /dev/null 2>&1
fi
fi
done
MODPKG=`git diff --name-only $CMSSW_VERSION..HEAD | cut -d'/' -f1-2 | sort -u`
for PKG_NAME in $PACKAGES; do
if [[ "$MODPKG" =~ "$PKG_NAME" ]]; then
[ "$HEADER3" ] || { $ECHO "\nThese packages have been modified from the base release"; HEADER3=done; }
echo $PKG_NAME
fi
done
fi
if [ "$HEADER" ] || (([ "$HEADER2" ] || [ "$HEADER3" ]) && [ -z "$FORCE" ]); then
exit 1
fi
}
BASH_FULL_VERSION=$((${BASH_VERSINFO[0]} * 10000 + ${BASH_VERSINFO[1]} * 100 + ${BASH_VERSINFO[2]}))
if (( BASH_FULL_VERSION >= 40100 )); then
# bash 4.1 or newer
if [ $VERBOSE == 0 ]; then
# send verbose messages to /dev/null
exec {verbose}> /dev/null
else
# send debug messages to stderr
exec {verbose}>&2
fi
if [ $DEBUG == 0 ]; then
# send debug messages to /dev/null
exec {debug}> /dev/null
else
# send debug messages to stderr
exec {debug}>&2
fi
else
# bash 4.0 or older
verbose=11
if [ $VERBOSE == 0 ]; then
# send verbose messages to /dev/null
exec 11> /dev/null
else
# send debug messages to stderr
exec 11>&2
fi
debug=12
if [ $DEBUG == 0 ]; then
# send debug messages to /dev/null
exec 12> /dev/null
else
# send debug messages to stderr
exec 12>&2
fi
fi
if [ "$INPUT_FILE" ]; then
# make it into a standard package list
PACKAGES=`cat "$INPUT_FILE" | sed -e's|\s*#.*||' | grep -v '^\s*$'`
# check the syntax of the input file
INVALID=`echo $PACKAGES | tr " " "\n" | grep -v -E '^/*\w+(/\w+)?/*$' || true`
if [ -n "$INVALID" ]; then
$ECHO "Some lines of $INPUT_FILE are not in a valid format:"
$ECHO "$RED$INVALID$NORMAL"
exit 1
fi
unset INVALID
fi
# initialize the local repository
if [ -z "$CMSSW_BASE" ]; then
$ECHO "CMSSW environment not setup, please run 'cmsenv' before 'git $COMMAND_NAME'."
exit 1
fi
if ! [ -d $CMSSW_BASE/src/.git ]; then
if [ "$COMMAND_NAME" == "cms-rmpkg" ]; then
$ECHO "git $COMMAND_NAME : nothing to do."
exit 1
else
git cms-init $INITOPTIONS
fi
fi
cd $CMSSW_BASE/src
case `git --version` in
git\ version\ 1.7*)
# git 1.7.x does not support a leading slash in .gitignore and .git/info/sparse-checkout
LEADING_SLASH=
;;
*)
LEADING_SLASH=/
;;
esac
# check if using a reference repository
if [ "$CMSSW_GIT_REFERENCE" == "" ] && [ -f $CMSSW_BASE/src/.git/objects/info/alternates ]; then
CMSSW_GIT_REFERENCE=`cat $CMSSW_BASE/src/.git/objects/info/alternates | head -n1`
fi
if [ "$(git status --porcelain --untracked=no | grep '^[ACDMRU]')" ]; then
$ECHO "${RED}Error:${NORMAL} there are staged but not committed changes on your working tree, please commit or stash them."
exit 1
fi
CURRENT_BRANCH=`git symbolic-ref --short HEAD`
# check if requested packages are present to be removed
if [ "$COMMAND_NAME" == "cms-rmpkg" ]; then
checkPkgs "$PACKAGES" "$CURRENT_BRANCH"
fi
# create temporary sparse checkout file
touch $CMSSW_BASE/src/.git/info/sparse-checkout-tmp
# add the requested package(s) to the temporary file
verbose "\n$ACTION packages"
for PKG_NAME in $PACKAGES; do
verbose $PKG_NAME
echo $PKG_NAME | sed -e "s|[/]*$|/|;s|^/*|${LEADING_SLASH}|" >> $CMSSW_BASE/src/.git/info/sparse-checkout-tmp
done
# add or remove from the real sparse checkout file
if [ "$COMMAND_NAME" == "cms-addpkg" ]; then
cat $CMSSW_BASE/src/.git/info/sparse-checkout-tmp | while read LINE; do
# remove any exclusion line(s)
grep -v "^\!$LINE" $CMSSW_BASE/src/.git/info/sparse-checkout > $CMSSW_BASE/src/.git/info/sparse-checkout-new
mv $CMSSW_BASE/src/.git/info/sparse-checkout-new $CMSSW_BASE/src/.git/info/sparse-checkout
# if addition line not present, append it
if ! grep -q -x "$LINE" $CMSSW_BASE/src/.git/info/sparse-checkout; then
echo "$LINE" >> $CMSSW_BASE/src/.git/info/sparse-checkout
fi
done
else
cat $CMSSW_BASE/src/.git/info/sparse-checkout-tmp | while read LINE; do
# remove any addition line(s)
grep -v "^$LINE" $CMSSW_BASE/src/.git/info/sparse-checkout > $CMSSW_BASE/src/.git/info/sparse-checkout-new
mv $CMSSW_BASE/src/.git/info/sparse-checkout-new $CMSSW_BASE/src/.git/info/sparse-checkout
# special case: append exclusion line for package (if whole subsystem previously added)
if echo $LINE | grep -q "${LEADING_SLASH}.*/.*/"; then
SUBSYSTEM=${LINE%/*/}/
if grep -q -x "$SUBSYSTEM" $CMSSW_BASE/src/.git/info/sparse-checkout; then
echo "!$LINE" >> $CMSSW_BASE/src/.git/info/sparse-checkout
fi
fi
done
fi
rm -f $CMSSW_BASE/src/.git/info/sparse-checkout-tmp
# sort, keep exclusion lines at end
grep -v "^\!" $CMSSW_BASE/src/.git/info/sparse-checkout | sort -u > $CMSSW_BASE/src/.git/info/sparse-checkout-new
grep "^\!" $CMSSW_BASE/src/.git/info/sparse-checkout | sort -u >> $CMSSW_BASE/src/.git/info/sparse-checkout-new
mv $CMSSW_BASE/src/.git/info/sparse-checkout-new $CMSSW_BASE/src/.git/info/sparse-checkout
# update the working area
git read-tree -mu HEAD
# check if requested packages were successfully added
if [ "$COMMAND_NAME" == "cms-addpkg" ]; then
checkPkgs "$PACKAGES" "$CURRENT_BRANCH"
exit 0
fi