Skip to content

Commit 1041cef

Browse files
jhlegarretahjmjohnson
authored andcommitted
ENH: Add a script to apply another script to all remotes
Add a script to apply another script to all remotes. This script is intended to ease the extension of toolkit-wide changes that are applied through a bash script to the remote modules that dwell in/are referenced from the toolkit's `Modules/Remote` module.
1 parent aec9519 commit 1041cef

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/bin/bash
2+
3+
#==========================================================================
4+
#
5+
# Copyright Insight Software Consortium
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0.txt
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
#
19+
#==========================================================================*/
20+
21+
22+
# This script, given a path to another script, applies this to the source
23+
# code of the remote modules in the ITK source tree whose CI status shows
24+
# a successful build.
25+
#
26+
# The script clones the successful remote modules to the ITK source tree,
27+
# creates a feature branch on each module, applies the provided script to the
28+
# source code of each module, adds the modified files to the git stage area,
29+
# commits them using the provided commit message, and pushes the commit to the
30+
# remote module repository.
31+
#
32+
# Please, review the commit message directives at:
33+
# https://github.com/InsightSoftwareConsortium/ITK/blob/master/CONTRIBUTING.md
34+
35+
36+
# Utility functions
37+
usage() {
38+
cat << EOF
39+
Usage: $0 <script_filename> <feature_branch> <commit_message>
40+
41+
Use this script to apply another script to the source code of the remote
42+
remote modules in the ITK source tree whose CI status shows a successful
43+
build.
44+
45+
The script clones the successful remote modules to the ITK source tree,
46+
creates a feature branch on each module, applies the provided script to the
47+
source code of each module, adds the modified files to the git stage area,
48+
commits them using the provided commit message, and pushes the commit to the
49+
remote module repository.
50+
51+
Please, review the commit message directives at:
52+
https://github.com/InsightSoftwareConsortium/ITK/blob/master/CONTRIBUTING.md
53+
EOF
54+
}
55+
56+
die() {
57+
echo "$@" 1>&2; exit 1
58+
}
59+
60+
# Parse arguments
61+
help=false
62+
script=""
63+
feature_branch=""
64+
commit_message=""
65+
while test $# -gt 0;
66+
do
67+
opt="$1";
68+
case "$opt" in
69+
"-h"|"--help")
70+
shift;
71+
help=true
72+
break;;
73+
*)
74+
break;;
75+
esac
76+
done
77+
78+
script="$1"
79+
feature_branch="$2"
80+
commit_message="$3"
81+
82+
if test "${script}" = "" || "${feature_branch}" = "" || "${commit_message}" = "" || $help; then
83+
usage
84+
exit 1
85+
fi
86+
87+
# Make sure we are inside the repository
88+
cd "${BASH_SOURCE%/*}" &&
89+
90+
remote_modules_path='../../Modules/Remote'
91+
92+
# Ask for GitHub username and password once
93+
echo "Please provide your GitHub (https://github.com)"
94+
read -p "username: " username
95+
read -p "password: " -s password
96+
97+
remotes=()
98+
99+
function list_candidate_remotes() {
100+
if [ $# -ge 1 ] && [ $1 = "-ongreen" ]; then
101+
ongreen=1
102+
failing=()
103+
else
104+
ongreen=0
105+
fi
106+
107+
# Loop over the remote modules' CMake files
108+
for filename in ${remote_modules_path}/*.cmake; do
109+
echo -n "."
110+
111+
# Get the current module name
112+
module_name=$(grep -v "\s*#" $filename | grep -m 1 -o "itk_fetch_module(\(\w\|\.\|\-\|_\)*")
113+
module_name=${module_name/*itk_fetch_module(/}
114+
115+
# Get the current commit hash
116+
curr_commit=$(grep -v "\s*#" $filename | grep -m 1 -o "GIT_TAG \(\w\|\.\|\-\|_\)*")
117+
curr_commit=${curr_commit/*GIT_TAG /}
118+
119+
# Read the git repository information
120+
repository=$(grep -v "\s*#" $filename | grep -m 1 -o "GIT_REPOSITORY \${git_protocol}://github.com/\(\w\|\-\|_\|/\)*")
121+
repository=${repository/*GIT_REPOSITORY \${git_protocol\}:\/\/github.com\//}
122+
123+
# Get the latest git commit hash of the remote module.
124+
# Remotes will usually not be tagged.
125+
latest_commit=$(git ls-remote git://github.com/$repository refs/heads/master)
126+
latest_commit=${latest_commit/[[:space:]]refs\/heads\/master/}
127+
128+
# Skip remotes whose current commit in ITK differs from the latest
129+
if [ $curr_commit != $latest_commit ]; then
130+
continue
131+
fi
132+
133+
# Get the remotes' build status
134+
if [ $ongreen -eq 1 ]; then
135+
# Get the repository status
136+
# Be careful of rate limiting (https://developer.github.com/v3/#rate-limiting)
137+
# alternatively using Azure: https://docs.microsoft.com/en-us/azure/data-factory/monitor-programmatically#rest-api
138+
status=$(curl -s https://api.github.com/repos/$repository/commits/$latest_commit/status | grep -m 1 -o "\"state\": \"\w*\"")
139+
if [ "$status" != "\"state\": \"success\"" ]; then
140+
continue
141+
fi
142+
fi
143+
144+
remotes+=($module_name)
145+
146+
done
147+
}
148+
149+
function configure_itk_remotes() {
150+
mkdir ../../../ITK-build
151+
cd ../../../ITK-build
152+
153+
cmake_remote_flags=()
154+
155+
# Switch on all remotes that have a success build status
156+
for remote in ${remotes[@]}; do
157+
cmake_remote_flags+=(-D'Module_'$remote':BOOL=ON' )
158+
done
159+
160+
cmake ${cmake_remote_flags[@]} ../ITK
161+
}
162+
163+
function apply_script_and_push_remotes() {
164+
cd ../ITK/Modules/Remote
165+
166+
# Loop over remotes and apply the changes
167+
for remote in ${remotes[@]}; do
168+
echo -e $remote
169+
170+
cd $remote
171+
172+
repository_basename=$(basename -s .git `git config --get remote.origin.url`)
173+
174+
git checkout master
175+
git checkout -b $feature_branch origin/master
176+
$script
177+
178+
# Add the files, adding filters if necessary
179+
git add -u *.txt ./*.cmake ./*.rst ./*.py ./*.yml ./*.c ./*.cxx ./*.h ./*.hxx ./*.wrap
180+
181+
# Commit and push to the feature branch
182+
git commit -m $commit_message
183+
git push --quiet https://$username:$password@github.com/$username/$repository_basename $feature_branch
184+
185+
cd ..
186+
done
187+
}
188+
189+
echo -e "\nChecking remote modules build status..."
190+
list_candidate_remotes
191+
echo -e "\nDone checking remote modules build status."
192+
193+
echo -e "Configuring ITK with succeeding remote modules..."
194+
configure_itk_remotes
195+
echo -e "Done configuring ITK with succeeding remote modules."
196+
197+
echo -e "Applying script to remotes..."
198+
apply_script_and_push_remotes
199+
echo -e "Done applying script to remotes."
200+
201+
rm -r ../../../ITK-build
202+
203+
echo -e "Visit the remote repositories and open the corresponding pull requests."

0 commit comments

Comments
 (0)