• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env bash
2
3##############################################################################
4##
5##  GitHub Upload+Update Script (V2, combined) for DevPlat Samples
6##
7##############################################################################
8
9update=true
10upload=true
11deleteTemp=true
12useAllSamples=true
13allSamples=()
14token=
15
16## Generates a random 32 character alphaneumeric string to use as a post script
17##   for the temporary code folder (folder will be deleted at end)
18folderPS=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
19
20#utility function to print to stderr
21echoerr() { echo "$@" 1>&2; }
22
23display_usage() {
24echo -e "\e[90mUsage:
25
26      -t | --token [github_auth_token]
27         Input an auth token to access the googlesamples GitHub org
28         (if this is not present, you will be prompted for one later)
29
30      -s | --samples [sample1 sample2 sample3 ... sampleN]
31         If you don't want to check the entire samples folder,
32         you can specify which samples to use with this option.
33
34      --upload-only
35          Only uploads new samples - samples with existing
36          repos will be ignored
37
38      --update-only
39          Only updates samples with existing repos - new
40          samples will be ignored
41
42      --keep-temp-files
43          Will not delete the temporary directory used to pull/push
44          to Github. (normally deleted upon exit) Preserves logs.
45
46  This script can be run with no options - it will check the entire
47  ./prebuilts/gradle folder and prompt for an auth token when needed.\e[0m\n"
48}
49
50##############################################################################
51##  Make sure we delete the temporary folder (if it gets created) before exiting
52finish() {
53  if $deleteTemp; then
54    if [ -d "../github-temp$folderPS" ]; then
55     cd ..
56     rm -rf ./github-temp$folderPS
57    elif [ -d "github-temp$folderPS" ]; then
58     rm -rf ./github-temp$folderPS
59    fi
60  fi
61}
62# this ensures finish() will always be called no matter how the script ends
63trap finish EXIT
64
65
66##############################################################################
67##  Process input parameters. (see above for usage)
68
69## How this works:
70##  $# is the number of parameters passed in
71##  $1 is the first parameter, $2 the second, and so on. (space delimited)
72##  shift basically left shifts the params array - $1 goes away, $2 becomes $1, etc
73##  Thus, this while loop iterates through all command line parameters
74while [[ $# > 0 ]]; do
75case "$1" in
76
77  -t|--token)
78    if [[ $2 != -* ]] && [[ $2 ]]; then
79      token="$2"; shift
80    else
81      echoerr -e "Option $1 requires an argument. Cancelling script.\nUse --help to display usage."
82      exit 1
83    fi;;
84
85  --update-only) upload=false;;
86
87  --upload-only) update=false;;
88
89  --keep-temp-files) deleteTemp=false;;
90
91  -s|--samples)
92    useAllSamples=false
93    while [[ $2 != -* ]] && [[ $2 ]]; do
94      #if true; then ##for testing
95      if [ -d "./prebuilts/gradle/$2" ]; then
96        allSamples+=("$2")
97        shift
98      else
99        echoerr -e "Sample \"$2\" does not exist in ./prebuilts/gradle. Cancelling script.\n"
100        exit 1
101      fi
102    done;;
103
104  -h|--help)
105      display_usage
106      exit 1;;
107
108  *)
109    echoerr -e "Unknown Option: $1\nUse --help to display usage."
110    exit 1;;
111
112esac
113shift
114done #ends options while loop
115
116if ! $upload && ! $update; then
117  echoerr -e "Do not use both --update-only and --upload-only, no samples will be processed.
118  If you want to do both updates and uploads, no flags are needed.
119  Use --help to display usage."
120  exit 1
121fi
122
123##############################################################################
124##  Get all folders in prebuilts and stick 'em in an array
125
126if $useAllSamples; then
127  allSamples=($(ls ./prebuilts/gradle))
128fi
129
130# [@] returns all items in an array, ${#...} counts them
131numSamples=${#allSamples[@]}
132echo "Running script for $numSamples samples"
133
134##############################################################################
135##  Iterate through all the samples and see if there's
136##  a repo for them on GitHub already - save results so we only do it once
137
138toUpdate=()
139toUpload=()
140problemSamples=()
141curSample=0
142
143echo -ne "Checking for existence of repos... ($curSample/$numSamples)\r"
144for i in ${allSamples[@]};
145do
146 #echo "$i"
147 URL=https://github.com/googlesamples/android-$i
148 result=$(curl -o /dev/null --silent --head --write-out '%{http_code}' "$URL")
149 #echo "$result $URL"
150 if [ "$result" -eq "404" ]; then
151   toUpload+=("$i")
152 elif [ "$result" -eq "200" ]; then
153   toUpdate+=("$i")
154 else
155   problemSamples+=("$i")
156 fi
157 curSample=$(($curSample+1))
158 echo -ne "Checking for existence of repos... ($curSample/$numSamples)\r"
159done #close for loop for existence check
160echo ""
161
162
163##############################################################################
164##  For every sample that has a repo already, clone it and diff it against
165##  the sample code in our git to see if it needs updating.
166
167if $update; then
168
169needsUpdate=()
170curSample=0
171numUpdates=${#toUpdate[@]}
172
173##make temporary dir to pull code into - will be deleted upon exit.
174mkdir github-temp$folderPS
175cd github-temp$folderPS
176
177echo -ne "Checking for out-of-date repos... ($curSample/$numUpdates)\r"
178for i in ${toUpdate[@]};
179do
180 URL=https://github.com/googlesamples/android-$i
181 git clone $URL.git &> /dev/null
182 if [ -d "android-$i" ]; then
183   diffResult=$(diff -r --exclude '*.git' ../prebuilts/gradle/$i/ ./android-$i/)
184   #for testing (will show diff in every repo)
185   #diffResult=$(diff -r ../prebuilts/gradle/$i/ ./android-$i/)`
186   #echo $diffResult
187   if [ -n "$diffResult" ]; then
188     needsUpdate+=("$i")
189   fi
190 else
191   echoerr "Something went wrong when cloning $i - result directory does not exist.
192   Leaving temp files in place for further examination."
193   deleteTemp=false;
194 fi
195 curSample=$(($curSample+1))
196 echo -ne "Checking for out-of-date repos... ($curSample/$numUpdates)\r"
197done #end of for loop when checking which repos actually need updating
198echo ""
199fi
200
201echo ""
202
203##############################################################################
204##  Display the detected changes to be made and get user confirmation
205
206if $upload; then
207  if [ ${#toUpload[@]} -ne 0 ]; then
208    echo -e "\n\e[1mNew samples that will be uploaded:\e[0m"
209    for i in ${toUpload[@]}; do
210     echo -e "\e[32m$i\e[0m"
211    done
212  else
213    upload=false
214    echo "Nothing new to upload."
215  fi
216else
217  echo "No uploads - check skipped on user request"
218fi
219
220if $update; then
221  if [ ${#needsUpdate[@]} -ne 0 ]; then
222    echo -e "\n\e[1mSamples that will be updated:\e[0m"
223    for i in ${needsUpdate[@]}; do
224      echo -e "\e[34m$i\e[0m"
225    done
226  else
227    update=false
228    echo "Nothing to update."
229  fi
230else
231  echo "No updates - check skipped on user request"
232fi
233
234if [ ${#problemSamples[@]} -ne 0 ]; then
235 echoerr "
236These repos returned something other than a 404 or 200 result code:"
237 for i in ${problemSamples[@]};
238 do
239  echoerr "$i"
240 done
241fi
242
243if ! $upload && ! $update; then
244 echo -e "\e[1mLooks like everything's up-to-date.\e[0m\n"
245else
246
247read -p "
248Do you want to continue? [y/n]: " -n 1 -r
249echo
250# if they type anything but an upper or lower case y, don't proceed.
251if [[ $REPLY =~ ^[Yy]$ ]]
252then
253   #echo "Commencing Github updates"
254
255##############################################################################
256##  If the user hasn't supplied a token via parameter, ask now
257
258if ! [ -n "$token" ]
259then
260 read -p "
261Input a valid googlesamples GitHub access token to continue: " -r
262 token=$REPLY
263fi
264
265##############################################################################
266##  Test that token
267
268tokenTest=$(curl -o /dev/null --silent \
269  -H "Authorization: token $token" \
270  --write-out '%{http_code}' "https://api.github.com/orgs/googlesamples/repos")
271
272if [ "$tokenTest" -eq "200" ]; then
273
274
275##############################################################################
276##  If there's something to update, do the updates
277if [ ${#needsUpdate[@]} -ne 0 ] && $update; then
278 for i in ${needsUpdate[@]}; do
279   echo -e "\nUpdating $i"
280   if [ -d "android-$i" ]; then
281     rsync -az --delete --exclude '*.git' ../prebuilts/gradle/$i/ ./android-$i/
282
283     cd ./android-$i/
284
285     git config user.name "google-automerger"
286     git config user.email automerger@google.com
287
288     git add .
289     git status
290     git commit -m "Auto-update"
291
292     git remote set-url origin "https://$token@github.com/googlesamples/android-$i.git"
293     git push origin master
294
295     #overwrite remote url to not contain auth token
296     git remote set-url origin "http://github.com/googlesamples/android-$i.git"
297
298     cd ..
299   else
300     echoerr "Something went wrong when cloning $i - result directory does not exist.
301Leaving temp files in place for further examination."
302   deleteTemp=false;
303  fi
304 done
305fi
306
307#moves out of the temp folder, if we're in it.
308if [ -d "../github-temp$folderPS" ]; then
309   cd ..
310fi
311
312##############################################################################
313##  If there's something new to upload, do the uploads
314if [ ${#toUpload[@]} -ne 0 ] && $upload; then
315 for i in ${toUpload[@]}; do
316   echo -e "\nUploading $i"
317
318   repoName="googlesamples/android-$i"
319
320   CREATE="curl -H 'Authorization: token '$TOKEN \
321     -d '{\"name\":\"android-'$i'\", \"team_id\":889859}' \
322     https://api.github.com/orgs/googlesamples/repos"
323   eval $CREATE
324
325   #add secondary team permissions (robots)
326   ADDTEAM="curl -X PUT \
327     -H 'Authorization: token '$TOKEN \
328     -H 'Content-Length: 0' \
329     https://api.github.com/teams/889856/repos/$repoName"
330
331   eval $ADDTEAM
332
333   URL="https://$token@github.com/$repoName"
334
335   cd $i
336   git init
337    #overrides .gitconfig just for this project - does not alter your global settings.
338   git config user.name "google-automerger"
339   git config user.email automerger@google.com
340   git add .
341   git commit -m "Initial Commit"
342   git remote add origin $URL
343   git push origin master
344   cd ..
345
346
347 done
348fi
349
350else
351  echoerr "That token doesn't work. A test returned the code: $tokenTest"
352fi
353
354else
355   echo "User cancelled Github update."
356fi
357
358fi #end of "is there something to do?" if statement