58a0fbff32ef0aa4a2c9061fdd10cdfdcbee5d8a
[shellsnippets/shellsnippets.git] / mksh / sysadmin / mvndebri.sh
1 #!/bin/mksh
2 rcsid='$MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $'
3 rcsid='$Id: mvndebri.sh 2503 2011-11-17 15:28:58Z tglase $'
4 #-
5 # Copyright (c) 2008, 2009, 2010, 2011
6 #       Thorsten Glaser <tg@mirbsd.org>
7 # Copyright (c) 2011
8 #       Thorsten Glaser <t.glaser@tarent.de>
9 #
10 # Provided that these terms and disclaimer and all copyright notices
11 # are retained or reproduced in an accompanying document, permission
12 # is granted to deal in this work without restriction, including un-
13 # limited rights to use, publicly perform, distribute, sell, modify,
14 # merge, give away, or sublicence.
15 #
16 # This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
17 # the utmost extent permitted by applicable law, neither express nor
18 # implied; without malicious intent or gross negligence. In no event
19 # may a licensor, author or contributor be held liable for indirect,
20 # direct, other damage, loss, or other issues arising in any way out
21 # of dealing in the work, even if advised of the possibility of such
22 # damage or existence of a defect, except proven that it results out
23 # of said person's immediate fault when using the work as intended.
24
25 if [[ $1 != /* || -z $2 || ! -d $1/$2/. ]]; then
26         print -u2 Syntax error.
27         exit 1
28 fi
29 jobname=$2
30
31 hn=$(hostname)
32 case $hn {
33 (hudson.evolvis.org)
34         hn=evolvis-hudson
35         repo_keyid=0x16B5D1B2
36         ;;
37 (dev-hudson?(.*))
38         hn=dev-hudson
39         repo_keyid=0x199D2F3B
40         ;;
41 (test-hudson?(.*))
42         hn=test-hudson
43         repo_keyid=0xDB58AF73
44         ;;
45 # […]
46 (tglase.bonn.tarent.de)
47         hn=devel-testsystem
48         repo_keyid=0x5EB8D3B3
49         ;;
50 (*)
51         print -u2 "Cannot determine hostname from '$hn'"
52         exit 1
53         ;;
54 }
55 case $hn {
56 (evolvis-hudson)
57         dhn=jenkins-debs.evolvis.org
58         ;;
59 (*)
60         dhn=${hn}-debs.bonn.tarent.de
61         ;;
62 }
63 repo_origin='tarent solutions GmbH'
64 repo_label=tarent_auto_${hn}_$jobname
65 repo_title="tarent $hn $jobname automatic DEB Repository"
66 function repo_description {
67         typeset suite_nick=$1
68
69         print -nr -- "tarent-$hn $jobname/$suite_nick autobuild repository"
70 }
71
72
73 #set -A dpkgarchs -- alpha amd64 arm armeb armel armhf avr32 hppa \
74 #    i386 ia64 kfreebsd-amd64 kfreebsd-i386 lpia m32r m68k mips mipsel \
75 #    powerpc powerpcspe ppc64 s390 s390x sh3 sh3eb sh4 sh4eb sparc
76 set -A dpkgarchs -- amd64 i386
77
78 function putfile {
79         tee $1 | gzip -n9 >$1.gz
80 }
81
82 function sortlist {
83         typeset x u=$1
84
85         if [[ $u = -u ]]; then
86                 shift
87         else
88                 u=
89         fi
90
91         for x in "$@"; do
92                 print -r -- "$x"
93         done | sort $u
94 }
95
96 set +U
97 export LC_ALL=C
98 unset LANGUAGE
99 saveIFS=$IFS
100 cd "$1/$2"
101 shift
102 shift
103 if [[ ! -d dists/. ]]; then
104         print -u2 Not an APT repository.
105         exit 1
106 fi
107
108 suites=:
109 for suite in "$@"; do
110         suites=:dists/$suite$suites
111 done
112
113 allsuites=
114 for suite in dists/*; do
115         allsuites="$allsuites${allsuites:+ }${suite##*/}"
116         [[ $suites = : || $suites = *:"$suite":* ]] || continue
117         components=Components:
118         for dist in $suite/*; do
119                 [[ -d $dist/. ]] || continue
120                 rm -rf $dist/binary-* $dist/source
121                 ovf= oef= osf=
122                 [[ -s $dist/override.file ]] && ovf=$dist/override.file
123                 [[ -s $dist/override.extra ]] && oef="-e $dist/override.extra"
124                 [[ -s $dist/override.src ]] && osf="-s $dist/override.src"
125                 components="$components ${dist##*/}"
126                 for arch in ${dpkgarchs[*]} all; do
127                                 print "\n===> Creating" \
128                                     "${dist#dists/}/$arch/Packages\n"
129                                 mkdir -p $dist/binary-$arch
130                                 dpkg-scanpackages $oef -m -a $arch \
131                                     $dist $ovf | \
132                                     putfile $dist/binary-$arch/Packages
133                 done
134                 print "\n===> Creating ${dist#dists/}/Sources"
135                 mkdir -p $dist/source
136                 dpkg-scansources $osf \
137                     $dist $ovf | \
138                     putfile $dist/source/Sources
139                 print done.
140         done
141         print "\n===> Creating ${suite#dists/}/Release.gpg"
142         rm -f $suite/Release*
143         (cat <<-EOF
144                 Origin: ${repo_origin}
145                 Label: ${repo_label}
146                 Suite: ${suite##*/}
147                 Codename: ${suite##*/}
148                 Date: $(date -u)
149                 Architectures: all ${dpkgarchs[*]} source
150                 $components
151                 Description: $(repo_description "${suite##*/}")
152                 MD5Sum:
153         EOF
154         exec 4>$suite/Release-sha1
155         exec 5>$suite/Release-sha2
156         print -u4 SHA1:
157         print -u5 SHA256:
158         cd $suite
159         for n in Contents-* */{binary-*,source}/{Packag,Sourc}es*; do
160                 [[ -f $n ]] || continue
161                 # GNU *sum tools are horridly inefficient
162                 set -A x -- $(md5sum "$n")
163                 nm=${x[0]}
164                 set -A x -- $(sha1sum "$n")
165                 nsha1=${x[0]}
166                 set -A x -- $(sha256sum "$n")
167                 nsha2=${x[0]}
168                 ns=$(stat -c '%s' "$n")
169                 print " $nm $ns $n"
170                 print -u4 " $nsha1 $ns $n"
171                 print -u5 " $nsha2 $ns $n"
172         done) >$suite/Release
173         cat $suite/Release-sha1 $suite/Release-sha2 >>$suite/Release
174         rm $suite/Release-sha1 $suite/Release-sha2
175         gpg -u $repo_keyid -sb --batch \
176             --passphrase-file /etc/tarent/maven.kpw \
177             <$suite/Release >$suite/Release.gpg
178 done
179
180 print "\n===> Creating debidx.htm\n"
181
182 integer nsrc=0 nbin=0
183 br='<br />'
184
185 for suite in dists/*; do
186         for dist in $suite/*; do
187                 [[ -d $dist/. ]] || continue
188                 suitename=${suite##*/}
189                 if [[ $suitename != +([a-z0-9_]) ]]; then
190                         print -u2 "Invalid suite name '$suitename'"
191                         continue 2
192                 fi
193                 distname=${dist##*/}
194                 if [[ $distname != +([a-z0-9_-]) ]]; then
195                         print -u2 "Invalid dist name '$distname'"
196                         continue
197                 fi
198
199                 gzip -dc $dist/source/Sources.gz |&
200                 pn=; pv=; pd=; pp=; Lf=
201                 while IFS= read -pr line; do
202                         case $line {
203                         (" "*)
204                                 if [[ -n $Lf ]]; then
205                                         eval x=\$$Lf
206                                         x=$x$line
207                                         eval $Lf=\$x
208                                 fi
209                                 ;;
210                         ("Package: "*)
211                                 pn=${line##Package:*([   ])}
212                                 Lf=pn
213                                 ;;
214                         ("Version: "*)
215                                 pv=${line##Version:*([   ])}
216                                 Lf=pv
217                                 ;;
218                         ("Binary: "*)
219                                 pd=${line##Binary:*([    ])}
220                                 Lf=pd
221                                 ;;
222                         ("Directory: "*)
223                                 pp=${line##Directory:*([         ])}
224                                 Lf=pp
225                                 ;;
226                         (?*)    # anything else
227                                 Lf=
228                                 ;;
229                         (*)     # empty line
230                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
231                                         i=0
232                                         while (( i < nsrc )); do
233                                                 [[ ${sp_name[i]} = "$pn" && \
234                                                     ${sp_dist[i]} = "$distname" ]] && break
235                                                 let i++
236                                         done
237                                         if (( i == nsrc )); then
238                                                 let nsrc++
239                                                 pvo=
240                                                 ppo=
241                                         else
242                                                 eval pvo=\$\{sp_ver_${suitename}[i]\}
243                                                 eval ppo=\$\{sp_dir_${suitename}[i]\}
244                                         fi
245                                         sp_name[i]=$pn
246                                         sp_dist[i]=$distname
247                                         #sp_suites[i]="${sp_suites[i]} $suitename"
248                                         eval sp_ver_${suitename}[i]='${pvo:+$pvo,}$pv'
249                                         eval sp_dir_${suitename}[i]='${ppo:+$ppo,}$pp/'
250                                         sp_desc[i]=${sp_desc[i]},$pd
251                                 fi
252                                 pn=; pv=; pd=; pp=; Lf=
253                                 ;;
254                         }
255                 done
256
257                 gzip -dc $(for f in $dist/binary-*/Packages.gz; do
258                         [[ -e $f ]] || continue
259                         realpath "$f"
260                 done | sort -u) |&
261                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
262                 while IFS= read -pr line; do
263                         case $line {
264                         (" "*)
265                                 if [[ -n $Lf ]]; then
266                                         eval x=\$$Lf
267                                         x=$x$line
268                                         eval $Lf=\$x
269                                 fi
270                                 ;;
271                         ("Package: "*)
272                                 pN=${line##Package:*([   ])}
273                                 Lf=pN
274                                 ;;
275                         ("Source: "*)
276                                 pn=${line##Source:*([    ])}
277                                 pn=${pn%% *}
278                                 Lf=pn
279                                 ;;
280                         ("Version: "*)
281                                 pv=${line##Version:*([   ])}
282                                 Lf=pv
283                                 ;;
284                         ("Description: "*)
285                                 pd=${line##Description:*([       ])}
286                                 ;;
287                         ("Architecture: "*)
288                                 pp=${line##Architecture:*([      ])}
289                                 Lf=pp
290                                 ;;
291                         ("Filename: "*)
292                                 pf=${line##Filename:*([  ])}
293                                 Lf=pf
294                                 ;;
295                         (?*)    # anything else
296                                 Lf=
297                                 ;;
298                         (*)     # empty line
299                                 if [[ $pf = *:* || $pf = *'%'* ]]; then
300                                         print -u2 Illegal character in $dist \
301                                             packages $pp "'Filename: $pf'"
302                                         exit 1
303                                 fi
304                                 [[ -n $pn ]] || pn=$pN
305                                 if [[ -n $pn && -n $pv && -n $pd && -n $pp ]]; then
306                                         i=0
307                                         while (( i < nbin )); do
308                                                 [[ ${bp_disp[i]} = "$pN" && ${bp_desc[i]} = "$pd" && \
309                                                     ${bp_dist[i]} = "$distname" ]] && break
310                                                 let i++
311                                         done
312                                         (( i == nbin )) && let nbin++
313                                         bp_name[i]=$pn
314                                         bp_disp[i]=$pN
315                                         bp_dist[i]=$distname
316                                         #bp_suites[i]="${bp_suites[i]} $suitename"
317                                         [[ -n $pf ]] && pv="<a href=\"$pf\">$pv</a>"
318                                         pv="$pp: $pv"
319                                         eval x=\${bp_ver_${suitename}[i]}
320                                         [[ $br$x$br = *"$br$pv$br"* ]] || x=$x${x:+$br}$pv
321                                         eval bp_ver_${suitename}[i]=\$x
322                                         bp_desc[i]=$pd
323                                 fi
324                                 pn=; pv=; pd=; pp=; pN=; pf=; Lf=
325                                 ;;
326                         }
327                 done
328         done
329 done
330
331 (cat <<'EOF'
332 <?xml version="1.0"?>\r
333 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
334  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
335 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>
336  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
337  <meta name="MSSmartTagsPreventParsing" content="TRUE" />
338 EOF
339 print -r -- " <title>${repo_title} Index</title>"
340 cat <<'EOF'
341  <meta name="generator" content="$Id: mvndebri.sh 2503 2011-11-17 15:28:58Z tglase $ based on $MirOS: contrib/hosted/tg/deb/mkdebidx.sh,v 1.51 2011/05/13 20:53:29 tg Exp $" />
342  <style type="text/css">
343   table {
344    border: 1px solid black;
345    border-collapse: collapse;
346    text-align: left;
347    vertical-align: top;
348   }
349   tr {
350    border: 1px solid black;
351    text-align: left;
352    vertical-align: top;
353   }
354   td {
355    border: 1px solid black;
356    text-align: left;
357    vertical-align: top;
358   }
359   th {
360    background-color: #000000;
361    color: #FFFFFF;
362   }
363   .tableheadcell {
364    border: 1px solid #999999;
365    padding: 3px;
366    white-space: nowrap;
367   }
368   .srcpkgline {
369    background-color: #CCCCCC;
370   }
371   .srcpkgdist {
372    background-color: #666666;
373    color: #FFFFFF;
374    font-weight: bold;
375   }
376   .binpkgdist {
377    background-color: #999999;
378    color: #FFFFFF;
379    font-weight: bold;
380   }
381  </style>
382 </head><body>
383 EOF
384 print -r -- "<h1>${repo_title}</h1>"
385 cat <<EOF
386 <p><a href="dists/">Browse</a> the repository.
387  This repository uses <a
388   href="http://pgp.uni-mainz.de:11371/pks/lookup?search=${repo_keyid}&amp;op=vindex">${repo_keyid}</a>
389  as signing key.
390 </p>
391 <h2>Suites</h2>
392 <ul>
393 EOF
394
395 allsuites=$(for suitename in $allsuites; do
396         print $suitename
397 done | sort -u)
398
399 for suitename in $allsuites; do
400         suite=dists/$suitename
401         print -n " <li>${suite##*/}: <a href=\"$suite/\">$jobname for $suitename</a> (dists:"
402         vdists=
403         for dist in $suite/*; do
404                 [[ -d $dist/. ]] || continue
405                 distname=${dist##*/}
406                 vdists="$vdists $distname"
407                 print -n " <a href=\"$suite/$distname/\">$distname</a>"
408         done
409         print ")<br />"
410         print " <tt>deb http://${dhn}/$jobname $suitename$vdists</tt>"
411         print "</li>"
412 done
413 print "</ul>"
414 print "<h2>Packages</h2>"
415 print "<table width=\"100%\"><thead>"
416 print "<tr class=\"tablehead\">"
417 print " <th class=\"tableheadcell\">dist</th>"
418 print " <th class=\"tableheadcell\" rowspan=\"2\">Binary / Description</th>"
419 for suitename in $allsuites; do
420         print " <th class=\"tableheadcell\" rowspan=\"2\">$suitename</th>"
421 done
422 print "</tr><tr class=\"tablehead\">"
423 print " <th class=\"tableheadcell\">package name</th>"
424 print "</tr></thead><tbody>"
425
426 set -A bp_sort
427 i=0
428 while (( i < nbin )); do
429         print $i ${bp_disp[i++]} #${bp_suites[i]}
430 done | sort -k2 |&
431 while read -p num rest; do
432         bp_sort[${#bp_sort[*]}]=$num
433 done
434
435 i=0
436 while (( i < nsrc )); do
437         print $i ${sp_name[i++]}
438 done | sort -k2 |&
439 while read -p num rest; do
440         print "\n<!-- sp #$num = ${sp_name[num]} -->"
441         print "<tr class=\"srcpkgline\">"
442         print " <td class=\"srcpkgdist\">${sp_dist[num]}</td>"
443         pd=
444         for x in $(tr ', ' '\n' <<<"${sp_desc[num]}" | sort -u); do
445                 [[ -n $x ]] && pd="$pd, $x"
446         done
447         print " <td rowspan=\"2\" class=\"srcpkgdesc\">${pd#, }</td>"
448         for suitename in $allsuites; do
449                 eval pvo=\${sp_ver_${suitename}[num]}
450                 eval ppo=\${sp_dir_${suitename}[num]}
451                 IFS=,
452                 set -A pva -- $pvo
453                 set -A ppa -- $ppo
454                 IFS=$saveIFS
455                 (( ${#pva[*]} )) || pva[0]=
456                 y=
457                 i=0
458                 while (( i < ${#pva[*]} )); do
459                         pv=${pva[i]}
460                         pp=${ppa[i]}
461                         if [[ $pv = *"\1a"* ]]; then
462                                 pvdsc=${pv%%"\1a"*}
463                                 pv=${pv##*"\1a"}
464                         else
465                                 pvdsc=$pv
466                         fi
467                         if [[ -z $pv ]]; then
468                                 pv=-
469                         elif [[ $pp != ?(/) ]]; then
470                                 pv="<a href=\"$pp${sp_name[num]}_${pvdsc##+([0-9]):}.dsc\">$pv</a>"
471                         fi
472                         [[ $pp != ?(/) ]] && pv="<a href=\"$pp\">[dir]</a> $pv"
473                         y=${y:+"$y<br />"}$pv
474                         let i++
475                 done
476                 print " <td rowspan=\"2\" class=\"srcpkgitem\">$y</td>"
477         done
478         print "</tr><tr class=\"srcpkgline\">"
479         print " <td class=\"srcpkgname\">${sp_name[num]}</td>"
480         print "</tr>"
481         k=0
482         while (( k < nbin )); do
483                 (( (i = bp_sort[k++]) < 0 )) && continue
484                 [[ ${bp_name[i]} = "${sp_name[num]}" && \
485                     ${bp_dist[i]} = "${sp_dist[num]}" ]] || continue
486                 bp_sort[k - 1]=-1
487                 #print "<!-- bp #$i for${bp_suites[i]} -->"
488                 print "<!-- bp #$i -->"
489                 print "<tr class=\"binpkgline\">"
490                 print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
491                 print " <td class=\"binpkgdesc\">${bp_desc[i]}</td>"
492                 for suitename in $allsuites; do
493                         eval pv=\${bp_ver_${suitename}[i]}
494                         if [[ -z $pv ]]; then
495                                 pv=-
496                         fi
497                         print " <td class=\"binpkgitem\">$pv</td>"
498                 done
499                 print "</tr>"
500         done
501 done
502
503 num=0
504 for i in ${bp_sort[*]}; do
505         (( i < 0 )) && continue
506         if (( !num )); then
507                 print "\n<!-- sp ENOENT -->"
508                 print "<tr class=\"srcpkgline\">"
509                 print " <td class=\"srcpkgname\">~ENOENT~</td>"
510                 print " <td class=\"srcpkgdesc\">binary" \
511                     "packages without a matching source package</td>"
512                 for suitename in $allsuites; do
513                         print " <td class=\"srcpkgitem\">-</td>"
514                 done
515                 print "</tr>"
516                 num=1
517         fi
518         #print "<!-- bp #$i for${bp_suites[i]} -->"
519         print "<!-- bp #$i -->"
520         print "<tr class=\"binpkgline\">"
521         print " <td class=\"binpkgdist\">${bp_dist[i]}</td>"
522         print " <td rowspan=\"2\" class=\"binpkgdesc\">${bp_desc[i]}</td>"
523         for suitename in $allsuites; do
524                 eval pv=\${bp_ver_${suitename}[i]}
525                 if [[ -z $pv ]]; then
526                         pv=-
527                 fi
528                 print " <td rowspan=\"2\" class=\"binpkgitem\">$pv</td>"
529         done
530         print "</tr><tr class=\"binpkgline\">"
531         print " <td class=\"binpkgname\">${bp_disp[i]}</td>"
532         print "</tr>"
533 done
534
535 cat <<EOF
536
537 </tbody></table>
538
539 <p>• <a href="http://validator.w3.org/check/referer">Valid XHTML/1.1!</a>
540  • <small>Generated on $(date -u +'%F %T') by <tt
541  style="white-space:pre;">$rcsid</tt></small> •</p>
542 </body></html>
543 EOF
544
545 :) >debidx.htm
546 print done.