Issue-ID: DOC-686
[doc.git] / tools / checkdocs.sh
1 #!/bin/bash
2 #set -x # uncomment for bash script debugging
3
4 ### ============================================================================
5 ### Licensed under the Apache License, Version 2.0 (the "License");
6 ### you may not use this file except in compliance with the License.
7 ### You may obtain a copy of the License at
8 ###
9 ###       http://www.apache.org/licenses/LICENSE-2.0
10 ###
11 ### Unless required by applicable law or agreed to in writing, software
12 ### distributed under the License is distributed on an "AS IS" BASIS,
13 ### WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ### See the License for the specific language governing permissions and
15 ### limitations under the License.
16 ### ============LICENSE_END=====================================================
17
18 ###
19 ### checkdocs.sh
20 ###
21 ### AUTHOR(S):
22 ### Thomas Kulik, Deutsche Telekom AG, 2020
23 ###
24 ### DESCRIPTION:
25 ### Retrieves a full list of ONAP repos from gerrit inluding their state.
26 ### Clones all active repos of the ONAP master branch plus other requested ONAP
27 ### branches. Then the script does some docs related analyses depending on the
28 ### clone results. It creates logfiles containing filtered results. In addition
29 ### a table.csv is created which can be used to import it in a spreadsheed.
30 ### Also a zip-file is created which contains all the results.
31 ###
32 ### IMPORTANT:
33 ### - in the output, repo names are shown in square brackets for readability
34 ###   e.g [aai/aai-common]/docs/release-notes.rst
35 ### - in the table.csv file you see data for the requested branch if available.
36 ###   if not available, data is retrieved from the master branch. it will be
37 ###   denoted in round brackets, e.g. (3) (tox.ini)
38 ###
39 ### REQUIREMENTS:
40 ### curl
41 ### jq
42 ###
43
44 ###
45 ### SOME HELPING COMMANDS TO PROCESS LOG FILES:
46 ### create repo list
47 ### curl -s https://git.onap.org/ | grep "^<tr><td class='toplevel-repo'><a title='" | sed -r "s:^<tr><td class='toplevel-repo'><a title='::" | sed -r "s:'.*::"
48 ###
49 ### remove branchname from the line
50 ### cat frankfurt_gerritclone.log | sed 's:frankfurt|::'
51 ###
52 ### list only image names
53 ### cat master_dockerimagesfull.log | grep image | sed -r 's:image\:::' | sed -r 's:^ +::' | sed '/^[[:space:]]*$/d'
54 ###
55 ### more interesting stuff ...
56 ### curl https://gerrit.onap.org/r/projects/?d
57 ### LONG:  curl -s 'https://gerrit.onap.org/r/projects/?d' | awk '{if(NR>1)print}' | jq -c '.[] | {id, state}' | sed -r 's:%2F:/:g' | sed -r 's:["{}]::g' | sed -r 's:id\:::' | sed -r 's:,state\::|:' | sed '/All-Projects/d' | sed '/All-Users/d'
58 ### SHORT: curl -s 'https://gerrit.onap.org/r/projects/?d' | awk '{if(NR>1)print}' | jq -c '.[] | {id, state}' | sed -r 's:%2F:/:g; s:["{}]::g; s:id\:::; s:,state\::|:; /All-Projects/d; /All-Users/d'
59 ###
60
61 script_version="1.1 (2020-11-17)"
62
63 # save command for the restart with logging enabled
64 command=$0
65 arguments=$@
66 fullcommand="${command} ${arguments}"
67
68 ###
69 ### functions
70 ###
71
72 # print usage
73 function usage() {
74   echo "                                                           "
75   echo " USAGE:                                                    "
76   echo "  ./checkdocs.sh                                           "
77   echo "                                                           "
78   echo " ARGUMENTS:                                                "
79   echo "  -u|--user username                                       "
80   echo "  linux foundation username used to clone ONAP Gerrit repos"
81   echo "                                                           "
82   echo "  -b|--branches branch1,branch2,branch3                    "
83   echo "  list of branches to be cloned. master is automatically   "
84   echo "  added to the list. do not add manually!                  "
85   echo "                                                           "
86   echo "  -d|--dev                                                 "
87   echo "  development-mode - limits number of repos to be cloned   "
88   echo "                                                           "
89 }
90
91 # draw a simple line
92 function drawline {
93   echo "*******************************************************************************"
94 }
95
96 # remove lockfile in case script is interrupted
97 trap InterruptedScript SIGINT SIGTERM SIGHUP SIGKILL SIGSTOP
98 function InterruptedScript {
99   echo " "
100   echo "Script was interrupted."
101   if [ -f $lockfile ] ; then
102     rm $lockfile
103   fi
104   exit 0
105 }
106
107 ###
108 ### arguments handling
109 ###
110
111 PARAMS=""
112
113 while (( "$#" )); do
114   case "$1" in
115     -d|--dev)
116       devmode="TRUE"
117       shift
118       ;;
119     -b|--branches)
120       if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
121         branches_csv=$2
122         shift 2
123       else
124         echo "Error: Argument for $1 is missing" >&2
125         usage
126         exit 1
127       fi
128       ;;
129     -u|--user)
130       if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
131         lfusername=$2
132         shift 2
133       else
134         echo "Error: Argument for $1 is missing" >&2
135         usage
136         exit 1
137       fi
138         ;;
139     -*|--*=) # unsupported flags
140       echo "Error: Unsupported argument $1" >&2
141       usage
142       exit 1
143       ;;
144     *) # preserve positional arguments
145       PARAMS="$PARAMS $1"
146       shift
147       ;;
148   esac
149 done
150
151 # set positional arguments in their proper place
152 eval set -- "$PARAMS"
153
154 # old: declare -a branches=("master" "frankfurt" "guilin")
155 if [[ $branches_csv == "" || $lfusername == "" ]]; then
156   usage
157   exit -1
158 fi
159
160 # master branch is automatically added and must not part of the user arguments
161 if [[ $branches_csv == *"master"* ]]; then
162   usage
163   exit -1
164 fi
165 # clone master first, the the other branches
166 branches_csv="master,${branches_csv}"
167
168 # create the branches array by readinging in the values from the variable
169 IFS=',' read -r -a branches <<< "${branches_csv}"
170
171 #echo "DBUG: devmode      = \"${devmode}\""
172 #echo "DBUG: branches_csv = \"${branches_csv}\""
173 #echo "DBUG: lfusername   = \"${lfusername}\""
174 #echo "DBUG: branches     = \"${branches[@]}\""
175
176 # restart script with logging enabled
177 lockfile="checkdocs-runtime-lockfile"
178 if [ ! -f $lockfile ] ; then
179   touch $lockfile
180   echo "Restarting script with logging enabled."
181   ${fullcommand} 2>&1 | tee checkdocs.log
182   rm $lockfile
183   exit
184 fi
185
186 echo " "
187 echo "checkdocs.sh Version ${script_version}"
188 echo " "
189
190 # curl must be installed
191 if ! command -v curl &> /dev/null
192 then
193   echo "ERROR: curl command could not be found"
194   exit -1
195 fi
196
197 today=$(date '+%Y-%m-%d');
198 repolist="gerrit-repos-master-"$today".txt";
199 unique=$(date +%s)
200
201 echo "Retrieving a full list of ONAP repositories (master) from gerrit.onap.org."
202
203 # retrieve the full repolist from gerrit
204 # workaround because of the (wrong?) response of gerrit.onap.org which makes jq command fail
205 # "| awk '{if(NR>1)print}'" filters the first line of the response so that jq will work again (thx marek)
206 curl -s 'https://gerrit.onap.org/r/projects/?d' | awk '{if(NR>1)print}' | jq -c '.[] | {id, state}' | sed -r 's:%2F:/:g; s:["{}]::g; s:id\:::; s:,state\::|:; /All-Projects/d; /All-Users/d' >./$repolist
207
208 # process the created repolist
209 # only active projects will be cloned in case the requested branch of the project exists
210 echo "Accessing gerrit.onap.org with username \"${lfusername}\"."
211 echo "Start cloning of repositories."
212
213 for branch in "${branches[@]}"
214 do
215
216   echo " "
217   echo "###"
218   echo "### ${branch}"
219   echo "###"
220   echo " "
221
222   branch_upper=$(echo "${branch}" | tr '[:lower:]' '[:upper:]')
223
224   mkdir $branch
225   cp $repolist $branch
226   cd $branch
227
228   devcounter=0
229
230   # process repolist
231   while read line
232   do
233
234   if [[ $devmode == "TRUE" ]]; then
235     devcounter=$((devcounter+1))
236   fi
237
238   if [[ $devcounter -lt "11" ]]; then
239
240       if [[ $devmode == "TRUE" ]]; then
241         echo "INFO: devmode! counter=${devcounter}"
242       fi
243
244       drawline
245       reponame=$(echo $line | awk -F "|" '{print $1}');
246       repostate=$(echo $line | awk -F "|" '{print $2}');
247       echo $reponame
248       echo $repostate
249
250       if [[ $repostate == "ACTIVE" ]]; then
251         echo "Cloning \"${branch}\" branch of ACTIVE project ${reponame}..."
252
253         git clone --branch ${branch} --recurse-submodules ssh://${lfusername}@gerrit.onap.org:29418/$reponame ./$reponame
254         gitexitcode=$?
255
256         if [[ ! ${gitexitcode} == "0" ]]; then
257           errormsg=$(tail -1 ../checkdocs.log)
258         else
259           errormsg="cloned"
260         fi
261
262         # gerritclone.log format:  $1=gitexitcode|$2=reponame|$3=repostate|$4=errormsg
263         echo "${gitexitcode}|${reponame}|${repostate}|${errormsg}" | tee -a ${branch}_gerritclone.log
264
265       elif [[ $repostate == "READ_ONLY" ]]; then
266         echo "-|${reponame}|${repostate}|ignored" | tee -a ${branch}_gerritclone.log
267       else
268         echo "-|${reponame}|unknown repo state \"${repostate}\"|-" | tee -a ${branch}_gerritclone.log
269       fi
270
271       # examine repo
272       if [[ ${gitexitcode} == "0" ]]; then
273
274         printf "\ndocs directories:\n"
275         find ./$reponame -type d -name docs | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_docs.log
276
277         printf "\nrst files:\n"
278         find ./$reponame -type f -name *.rst | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_rstfiles.log
279
280         printf "\nrelease notes rst:\n"
281         find ./$reponame -type f | grep 'release.*note.*.rst' | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_releasenotes.log
282
283         printf "\ntox.ini files:\n"
284         find ./$reponame -type f -name tox.ini | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_toxini.log
285
286         printf "\nconf.py files:\n"
287         find ./$reponame -type f -name conf.py | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_confpy.log
288
289         printf "\nindex.rst files:\n"
290         find ./$reponame -type f -name index.rst | sed -r 's:./::' | sed -r s:${reponame}:[${reponame}]: | tee -a ${branch}_indexrst.log
291
292       fi
293
294     # end defcounter loop
295     fi
296
297     gitexitcode=""
298
299   done <${repolist}
300
301   # examine repos
302   drawline
303   find . -type f -name values.yaml -print -exec grep "image:" {} \; | sed -r 's:^ +::' | tee ${branch}_dockerimagesfull.log
304   drawline
305   ls --format single-column -d */ | sed 's:/$::' | tee ${branch}_directories.log
306   drawline
307   cat ${branch}_dockerimagesfull.log | grep image | sed -r 's:image\:::' | sed -r 's:^ +::' | sed '/^[[:space:]]*$/d' >${branch}_dockerimages.log
308   drawline
309   ls --format single-column -d oom/kubernetes/*/ | tee ${branch}_oomkubernetes.log
310   drawline
311
312   # examine docs
313   readarray -t docs_array < ./${branch}_docs.log;
314
315   for line in "${docs_array[@]}"
316   do
317
318     echo $line | tee -a ${branch}_docsconfig.log
319
320     # remove [ and ] which are distinguish the project name in the output
321     line=$(echo $line | sed -r 's:\[:: ; s:\]::')
322
323     if [ -f ./${line}/conf.py ] ; then
324       echo "  conf.py ..... found" | tee -a ${branch}_docsconfig.log
325     else
326       echo "  conf.py ..... NOT FOUND" | tee -a ${branch}_docsconfig.log
327     fi
328
329     if [ -f ./${line}/index.rst ] ; then
330       echo "  index.rst ... found" | tee -a ${branch}_docsconfig.log
331     else
332       echo "  index.rst ... NOT FOUND" | tee -a ${branch}_docsconfig.log
333     fi
334
335     if [ -f ./${line}/tox.ini ] ; then
336       echo "  tox.ini ..... found" | tee -a ${branch}_docsconfig.log
337     else
338       echo "  tox.ini ..... NOT FOUND" | tee -a ${branch}_docsconfig.log
339     fi
340
341     echo " " | tee -a ${branch}_docsconfig.log
342
343   done
344   unset docs_array
345
346   drawline
347
348   ###
349   ### build a csv table that combines results
350   ###
351
352   #
353   # csv column #1: project name
354   #
355
356   readarray -t array < ./${repolist};
357   i=0
358   csv[i]="project"
359   ((i++))
360   for line in "${array[@]}"
361   do
362     reponame=$(echo $line | awk -F "|" '{print $1}');
363     project=$(echo $reponame | sed 's:/.*$::')
364     #echo "DBUG: reponame=${reponame}"
365     #echo "DBUG:  project=${project}"
366     #echo "DBUG:        i=${i}"
367     csv[i]=${project}
368     ((i++))
369   done
370   unset array
371   unset i
372   unset reponame
373   unset project
374
375   #
376   # csv column #2: repo name
377   #
378
379   readarray -t array < ./${repolist};
380   i=0
381   csv[i]="${csv[i]},MASTER repo name"
382   ((i++))
383   for line in "${array[@]}"
384   do
385     reponame=$(echo $line | awk -F "|" '{print $1}');
386     csv[i]="${csv[i]},${reponame}"
387     ((i++))
388   done
389   unset array
390   unset i
391   unset reponame
392
393   #
394   # csv column #3: repo state
395   #
396
397   readarray -t array < ./${repolist};
398   i=0
399   csv[i]="${csv[i]},MASTER repo state"
400   ((i++))
401   for line in "${array[@]}"
402   do
403     repostate=$(echo $line | awk -F "|" '{print $2}');
404     csv[i]="${csv[i]},${repostate}"
405     ((i++))
406   done
407   unset array
408   unset i
409   unset repostate
410
411   #
412   # csv column #4: clone message
413   #
414
415   readarray -t array < ./${branch}_gerritclone.log;
416   i=0
417   csv[i]="${csv[i]},${branch_upper} clone message"
418   ((i++))
419   for line in "${array[@]}"
420   do
421     # gerritclone.log format:  $1=gitexitcode|$2=reponame|$3=repostate|$4=errormsg
422     errormsg=$(echo $line | awk -F "|" '{print $4}');
423     csv[i]="${csv[i]},${errormsg}"
424     ((i++))
425   done
426   unset array
427   unset i
428   unset errormsg
429
430   #
431   # csv column #5: RELEASE component (yes|no|maybe)
432   # to be filled with values of the planned release config file maintained by
433   # the onap release manager
434   #
435
436   # gerritclone.log format:  $1=gitexitcode|$2=reponame|$3=repostate|$4=errormsg
437   readarray -t array < ./${branch}_gerritclone.log;
438   i=0
439   csv[i]="${csv[i]},${branch_upper} component"
440   ((i++))
441   for line in "${array[@]}"
442   do
443
444     # gerritclone.log format:  $1=gitexitcode|$2=reponame|$3=repostate|$4=errormsg
445     gitexitcode=$(echo $line | awk -F "|" '{print $1}');
446        reponame=$(echo $line | awk -F "|" '{print $2}');
447       repostate=$(echo $line | awk -F "|" '{print $3}');
448        errormsg=$(echo $line | awk -F "|" '{print $4}');
449
450     if [[ ${repostate} == "ACTIVE" && ${gitexitcode} == "0" ]]; then
451       releasecomponent="yes"
452     elif [[ ${repostate} == "ACTIVE" && ${gitexitcode} == "128" ]]; then
453       releasecomponent="maybe"
454     elif [ ${repostate} == "READ_ONLY" ]; then
455       releasecomponent="no"
456     else
457       releasecomponent="unknown"
458     fi
459
460     csv[i]="${csv[i]},${releasecomponent}"
461     ((i++))
462   done
463   unset array
464   unset i
465   unset gitexitcode
466   unset reponame
467   unset repostate
468   unset errormsg
469   unset releasecomponent
470
471   #
472   # csv column #6: docs (at repo root directory only; no recursive search!)
473   # csv column #7: conf.py
474   # csv column #8: tox.ini
475   # csv column #9: index.rst
476   #
477   # columns are filled with values from requested branch.
478   # if data is not available values from master branch are used.
479   # to identify master branch values, data is put into brackets "(...)"
480   #
481
482   readarray -t array < ./${repolist};
483   i=0
484   csv[$i]="${csv[i]},docs,conf.py,tox.ini,index.rst"
485   ((i++))
486   for line in "${array[@]}"
487   do
488     line=$(echo $line | sed 's:|.*$::')
489     #echo "DBUG: line=${line}"
490     #echo "DBUG: i=${i}"
491
492     # docs
493     if [ -d ./${line}/docs ] ; then
494       docs="docs"
495     elif [ -d ../master/${line}/docs ] ; then
496       docs="(docs)"
497     else
498       docs="-"
499     fi
500
501     # conf.py
502     if [ -f ./${line}/docs/conf.py ] ; then
503       docs="${docs},conf.py"
504     elif [ -f ../master/${line}/docs/conf.py ] ; then
505       docs="${docs},(conf.py)"
506     else
507       docs="${docs},-"
508     fi
509
510     # tox.ini
511     if [ -f ./${line}/docs/tox.ini ] ; then
512       docs="${docs},tox.ini"
513     elif [ -f ../master/${line}/docs/tox.ini ] ; then
514       docs="${docs},(tox.ini)"
515     else
516       docs="${docs},-"
517     fi
518
519     # index.rst
520     if [ -f ./${line}/docs/index.rst ] ; then
521       docs="${docs},index.rst"
522     elif [ -f ../master/${line}/docs/index.rst ] ; then
523       docs="${docs},(index.rst)"
524     else
525       docs="${docs},-"
526     fi
527
528     #echo "DBUG: docs=${docs}"
529     line="${csv[i]},${docs}"
530     csv[$i]=${line}
531     ((i++))
532   done
533   unset array
534   unset i
535   unset docs
536
537   #
538   # csv column #10: index.html@RTD accessibility check
539   # csv column #11: index.html url
540   #
541
542   readarray -t array < ./${branch}_gerritclone.log;
543   i=0
544   csv[i]="${csv[i]},index.html@RTD,index.html url"
545   ((i++))
546   for line in "${array[@]}"
547   do
548     # gerritclone.log format:  $1=gitexitcode|$2=reponame|$3=repostate|$4=errormsg
549     gitexitcode=$(echo $line | awk -F "|" '{print $1}');
550        reponame=$(echo $line | awk -F "|" '{print $2}');
551       repostate=$(echo $line | awk -F "|" '{print $3}');
552        errormsg=$(echo $line | awk -F "|" '{print $4}');
553
554             url=""
555     curl_result=""
556
557     # this routine works only with release "frankfurt" and later because
558     # earlier releases are using submodule structure for documentation files
559     if echo "$branch" | grep -q '^[abcde]'; then
560       curl_result="unsupported release"
561       url="-"
562     else
563
564       # we are working on "frankfurt" branch or later ...
565       # only if repostate IS ACTIVE a curl test is required
566       if [[ ${repostate} == "ACTIVE" ]]; then
567
568         # OPTIONAL: USE ALSO GITEXITCODE AS A FILTER CRITERIA ???
569
570         # url base
571         # important! only doc project needs a different url base
572         if [[ ${reponame} == "doc" ]]; then
573           url_start="https://docs.onap.org"
574         else
575           url_start="https://docs.onap.org/projects/onap"
576         fi
577         url_lang="en"
578         url_branch=${branch}
579
580         # "master" branch documentation is available as "latest" in RTD
581         if [[ ${url_branch} == "master" ]]; then
582           url_branch="latest"
583         fi
584
585         # replace all / characters in repo name with - charachter
586         url_repo=$(echo ${reponame} | sed -r 's/\//-/g')
587         url_file="index.html"
588
589         # build the full url
590         if [[ ${reponame} == "doc" ]]; then
591           # build the full url for the doc project
592           url="${url_start}/${url_lang}/${url_branch}/${url_file}"
593         else
594           # build the full url for the other projects
595           url="${url_start}-${url_repo}/${url_lang}/${url_branch}/${url_file}"
596         fi
597         #echo "DBUG: url=$url"
598
599         # test accessibility of url
600         curl --head --silent --fail "${url}?${unique}" >/dev/null
601         curl_result=$?
602
603         # convert numeric results to text
604         if [ "${curl_result}" = "0" ]; then
605           curl_result="accessible"
606         elif [ "${curl_result}" = "22" ]; then
607           curl_result="does not exist"
608         else
609           curl_result="ERROR:${curl_result}"
610         fi
611
612         # url does not exist for this branch.
613         # in case the requested url is not already for "master" branch,
614         # we try to access the url of the master branch and denote the
615         # result by using round brackets (result)
616         if [[ ${curl_result} == "does not exist" && ! $branch == "master" ]]; then
617
618           # build the full (master/latest) url
619           url="${url_start}-${url_repo}/${url_lang}/latest/${url_file}"
620           #echo "DBUG: url=$url"
621
622           # test accessibility of url in "master branch" (latest)
623           curl --head --silent --fail "${url}?${unique}" >/dev/null
624           curl_result=$?
625           # denote result as a value from "master" branch (latest)
626           url="(${url})"
627
628           # convert numeric results to text
629           if [ "${curl_result}" = "0" ]; then
630             curl_result="(accessible)"
631           elif [ "${curl_result}" = "22" ]; then
632             curl_result="(does not exist)"
633           else
634             curl_result="(ERROR:${curl_result})"
635           fi
636
637         fi
638       else
639         # repostate IS NOT ACTIVE - no curl test required
640         curl_result="-"
641         url="-"
642       fi
643     fi
644
645     echo "$url ... $curl_result"
646     csv[i]="${csv[i]},${curl_result},${url}"
647     #echo "DBUG: csv line=${csv[i]}"
648
649     ((i++))
650   done
651
652   #
653   # csv column #12: release notes
654   #
655
656   readarray -t array < ../${repolist};
657   i=0
658   csv[i]="${csv[i]},release notes"
659   ((i++))
660   for line in "${array[@]}"
661   do
662     line=$(echo $line | sed 's:|.*$::')
663     #echo "DBUG: line=\"${line}\""
664     #echo "DBUG: i=${i}"
665     relnote=""
666
667     # put repo name in square brackets for increased grep hit rate
668     # escape minus and bracket characters to avoid problems with the grep command
669     #repo_grepable=$(echo ${line} | sed -r s:${line}:[${line}]: | sed -r 's/-/\\-/g' | sed -r 's/\[/\\[/g' | sed -r 's/\]/\\]/g')
670     #echo "DBUG: repo_grepable=\"${repo_grepable}\""
671
672     # check if repo dir exists in this branch
673     if [ -d ./${line} ] ; then
674       # if yes, check if repo name appears in the branch releasenotes.log
675       relnote=$(find "./${line}" -type f | grep 'release.*note.*.rst' | wc -l);
676       # repo dir DOES NOT exist in this branch - so check if repo dir exists in MASTER branch
677     elif [ -d ../master/${line} ] ; then
678       # if yes, check if repo name appears in the MASTER releasenotes.log
679       # count release notes files in MASTER branch (in repo root and its subdirectories)
680       relnote=$(find "../master/${line}" -type f | grep 'release.*note.*.rst' | wc -l);
681       # put results in round brackets to show that this is MASTER data
682       relnote=$(echo ${relnote} | sed -r s:${relnote}:\(${relnote}\):)
683     else
684       relnote="-"
685     fi
686
687     line="${csv[i]},${relnote}"
688     csv[i]=${line}
689     ((i++))
690
691   done
692   unset array
693   unset i
694   unset relnote
695   unset repo_grepable
696
697   #
698   # build the table.csv file
699   #
700
701   for i in "${csv[@]}"
702   do
703     echo "$i" | tee -a ./${branch}_table.csv
704   done
705
706   #
707   # create data package for this branch and zip it
708   #
709
710   datadir=${branch}_data
711   mkdir $datadir
712   cp $repolist $datadir
713   cp ${branch}_table.csv $datadir
714   cp ${branch}_*.log $datadir
715   zip -r ${datadir}.zip $datadir
716
717   # return from the branch directory
718   cd ..
719
720 # return and work on the next requested branch ... or exit
721 done