cmd_tab.h+: fix: ARG_R should always imply ARG_S!
[s-mailx.git] / mk-release.inc
blobd57f2f0bb041ad8e504b541fe3d06812a4f8193e
1 #@ Include file for the mk-release.sh generic release builder.
2 #@ It also needs two hooks: update_stable_hook(), update_release_hook(),
3 #@ which need to "git add" what they have modified.
5 : ${PROGRAM:?"Need \$PROGRAM"}
6 : ${UPROGRAM:?"Need \$UPROGRAM"}
7 : ${MANUAL:?"May need \$MANUAL for announcement references"}
9 : ${UPLOAD:?"Need \$UPLOAD URL for scp(1)"}
11 : ${MAILX:=mailx}
12 : ${ACCOUNT:?"May need mailx(1) -A \$ACCOUNT"}
13 : ${MAILTO:?"May need \$MAILTO for announcement"}
14 : ${MAILBCC:?"May need \$MAILBCC for announcement"}
16 ##  --  >8  --  8<  --  ##
18 ORIG_LC_ALL=${LC_ALL} LC_ALL=C
19 export LC_ALL
21 DATE_MAN=`date -u +'%b %d, %Y'`
22 DATE_ISO=`date -u +%Y-%m-%d`
24 yesno() {
25    while [ 1 ]; do
26       [ ${#} -gt 0 ] && printf '%s ' "${@}"
27       printf '[y/n] '
28       read i
29       case ${i} in
30       [Yy]*) return 0;;
31       [Nn]*) return 1;;
32       *) ;;
33       esac
34    done
37 headref="`git rev-parse --verify HEAD`"
38 brref=
39 for i in `git rev-parse --branches=stable master^{commit}`; do
40    if [ ${headref} = ${i} ]; then
41       brref=${headref}
42       break
43    fi
44 done
45 if [ -z "${brref}" ]; then
46    echo >&2 'Not on the [master] or a [stable/*] branch'
47    exit 1
49 if [ "`git status --porcelain --ignored |
50       awk 'BEGIN{no=0}{++no}END{print no}'`" -ne 0 ]; then
51    echo >&2 'Directory not clean, see git status --ignored'
52    exit 2
55 echo 'Preparing a release on commit '"${headref}"
56 #brname="`git branch | sed -e '/^* /b X' -e d -e :X -e 's/^* //'`"
57 brname=`git symbolic-ref --short HEAD`
58 echo '  That is '"${brname}"
59 printf '  Name of release tag: '
60 read REL
61 VERSION=${REL}
62 vmaj=`{ echo ${VERSION}; } | sed -e 's/^\([^.]\{1,\}\).*/\1/'`
63 vmin=`{ echo ${VERSION}; } | sed -e 's/^[^.]\{1,\}\.\([^.]\{1,\}\).*/\1/'`
64 [ ${vmin} = ${VERSION} ] && VERSION=${VERSION}.0 vmin=0
65 vupd=`{ echo ${VERSION}; } |
66       sed -e 's/^[^.]\{1,\}\.[^.]\{1,\}\.\([^.-]\{1,\}\).*/\1/'`
67 [ ${vupd} = ${VERSION} ] && VERSION=${VERSION}.0 vupd=0
68 REL=${VERSION}
69 export VERSION
70 if yesno 'Is '${PROGRAM}' <v'${REL}'> correct?'; then :; else
71    echo >&2 'Bailing out'
72    exit 3
75 stblbrname=stable/v${vmaj}.${vmin}
76 brref=`git rev-parse --verify ${stblbrname} 2>/dev/null`
77 if [ -z "${brref}" ]; then
78    if yesno 'Create and switch to new branch '"${stblbrname}"; then
79       git checkout -b ${stblbrname}
80    fi
81 elif [ ${brref} != ${headref} ] || [ ${brname} != ${stblbrname} ]; then
82    echo >&2 "For ${REL} we should be on ${stblbrname}, not ${brname}"
83    echo >&2 'Bailing out'
84    exit 4
87 relbrname=release/v${VERSION}
88 brref=`git rev-parse --verify ${relbrname} 2>/dev/null`
89 if [ -z "${brref}" ]; then :; else
90    echo >&2 "The ${relbrname} already exists"
91    echo >&2 'Bailing out'
92    exit 5
96 echo 'Updating stable/ files to match the release'
98 if [ -f version.h ] && [ -f mk-mk.in ]; then
99    grep=grep sed=sed cmp=cmp mv=mv make -f mk-mk.in _update-version
100    git add version.h
102 update_stable_hook
104 LC_ALL=${ORIG_LC_ALL} git commit -S -m "Bump ${UPROGRAM} v${REL}, ${DATE_ISO}"
105 LC_ALL=${ORIG_LC_ALL} git tag -s -f \
106    -m "Bump ${UPROGRAM} v${REL}, ${DATE_ISO}" "v${REL}"
110 if yesno 'Create release/ branch?'; then
111    git checkout -b ${relbrname}
113    git rm -f .gitignore .mailmap TODO mk-release.*
114    update_release_hook
116    LC_ALL=${ORIG_LC_ALL} git commit -S \
117       -m "Bump ${UPROGRAM} v${REL}.ar, ${DATE_ISO}"
118    LC_ALL=${ORIG_LC_ALL} git tag -s -f \
119       -m "Bump ${UPROGRAM} v${REL}.ar, ${DATE_ISO}" "v${REL}.ar"
121    if yesno 'Shall i update release/latest "symlink"?'; then
122       git update-ref refs/heads/release/latest ${relbrname}
123    fi
124    if yesno 'Shall i update release/stable "symlink"?'; then
125       git update-ref refs/heads/release/stable ${relbrname}
126    fi
127 else
128    relbrname=${stblbrname}
132 # [timeline]
134 if [ ${relbrname} != ${stblbrname} ] &&
135       `git rev-parse --verify timeline^{commit} >/dev/null 2>&1` &&
136       yesno 'Shall i update [timeline]?'; then
137    git checkout timeline
138    git rm -rf '*'
139    git archive --format=tar "v${REL}.ar" | tar -x -f -
140    git add .
141    LC_ALL=${ORIG_LC_ALL} git commit -S -m "${UPROGRAM} v${REL}.ar, ${DATE_ISO}"
145 # repo push
147 [ ${relbrname} != ${stblbrname} ] && git checkout ${stblbrname}
148 git log --no-walk --decorate --oneline --branches --remotes
149 yesno 'Push git(1) repo?' && git push
152 # Big balls
154 if [ ${relbrname} != ${stblbrname} ] && yesno 'Create tarballs?'; then
155    bigballs=y
156    (
157    # Repack with standard tar(1) to avoid new-style headers
158    git archive --format=tar --prefix="${PROGRAM}-${REL}/" "v${REL}.ar" |
159       ( cd "${TMPDIR}" && tar -x -f - )
160    cd "${TMPDIR}"
162    tar -c -f "${PROGRAM}-${REL}.tar" "${PROGRAM}-${REL}"
163    < "${PROGRAM}-${REL}.tar" xz -e -C sha256 > "${PROGRAM}-${REL}.tar.xz"
164    < "${PROGRAM}-${REL}.tar" gzip > "${PROGRAM}-${REL}.tar.gz"
165    rm "${PROGRAM}-${REL}.tar"
167    openssl sha1 "${PROGRAM}-${REL}.tar.xz" >> "${PROGRAM}-${REL}.cksum"
168    openssl sha256 "${PROGRAM}-${REL}.tar.xz" >> "${PROGRAM}-${REL}.cksum"
169    openssl sha512 "${PROGRAM}-${REL}.tar.xz" >> "${PROGRAM}-${REL}.cksum"
170    gpg --detach-sign --armor "${PROGRAM}-${REL}.tar.xz"
171    cat "${PROGRAM}-${REL}.tar.xz.asc" >> "${PROGRAM}-${REL}.cksum"
173    openssl sha1 "${PROGRAM}-${REL}.tar.gz" >> "${PROGRAM}-${REL}.cksum"
174    openssl sha256 "${PROGRAM}-${REL}.tar.gz" >> "${PROGRAM}-${REL}.cksum"
175    openssl sha512 "${PROGRAM}-${REL}.tar.gz" >> "${PROGRAM}-${REL}.cksum"
176    gpg --detach-sign --armor "${PROGRAM}-${REL}.tar.gz"
177    cat "${PROGRAM}-${REL}.tar.gz.asc" >> "${PROGRAM}-${REL}.cksum"
178    )
179 else
180    bigballs=
184 # Announcement .txt and .html
186 if yesno 'Prepare announcement?'; then
187    anntxt=y
188    if [ -f .git/mk-release.txt ]; then
189       cp .git/mk-release.txt "${TMPDIR}/${PROGRAM}-${REL}.txt"
190    else
191       : > "${TMPDIR}/${PROGRAM}-${REL}.txt"
192    fi
193    if [ -n "${bigballs}" ] && [ -f "${TMPDIR}/${PROGRAM}-${REL}.cksum" ]; then
194       echo >> "${TMPDIR}/${PROGRAM}-${REL}.txt"
195       cat "${TMPDIR}/${PROGRAM}-${REL}.cksum" >>\
196          "${TMPDIR}/${PROGRAM}-${REL}.txt"
197    fi
198    if `git cat-file -e ${relbr}:NEWS 2>/dev/null`; then
199       echo >> "${TMPDIR}/${PROGRAM}-${REL}.txt"
200       git show ${relbr}:NEWS >> "${TMPDIR}/${PROGRAM}-${REL}.txt"
201    fi
203    LC_ALL=${ORIG_LC_ALL} ${EDITOR} "${TMPDIR}/${PROGRAM}-${REL}.txt"
205    # HTML convert ready for S-Web42
206    APO=\'
207    < "${TMPDIR}/${PROGRAM}-${REL}.txt" awk -v manual="${MANUAL}" '
208    BEGIN{
209       header = 1
210       hot = 0
211       print "<?begin?><?mode icewatsm?><pre>"
212    }
213    function strips(){
214       gsub("&", "\\&amp;")
215       gsub("<", "\\&lt;")
216       gsub(">", "\\&gt;")
217    }
218    function urls(){
219       any = 0
220       res = ""
221       s = $0
223       while(match(s, /(\\?(http|ftp)s?\??:\/\/[^ ]*)/)){
224          pre = substr(s, 1, RSTART - 1)
225          mat = substr(s, RSTART, RLENGTH)
226          s = substr(s, RSTART + RLENGTH)
227          if("\\" == substr(mat, 1, 1))
228             mat = substr(mat, 2)
229          else{
230             xt = 0
231             if(match(mat, /^https\?/))
232                mat = "https" substr(xt = mat, RSTART + 6)
233             else if(match(mat, /^ftps\?/))
234                mat = "ftps" substr(xt = mat, RSTART + 5)
235             if(match(mat, /sdaoden\.eu/))
236                mat = "<?lref" (xt ? "t " : " ") mat (xt ? "<>" xt : "") "?>"
237             else
238                mat = "<?href" (xt ? "t " : " ") mat (xt ? "<>" xt : "") "?>"
239          }
240          res = res pre mat
241          any = 1
242       }
243       if(any && length(s))
244          res = res s
245       $0 = any ? res : s
246    }
247    /^[[:space:]]*s-.*-mode[[:space:]]*$/{
248       header = 1
249       next
250    }
251    /ChangeLog|shortlog/{
252       if(header)
253          next
254       if(hot == 0)
255          hot = 1
256       strips()
257    }
258    /Appendix/{
259       if(header)
260          next
261       hot = -1
262       strips()
263    }
264    {
265       if(header){
266          if(length == 0)
267             header = 0
268          next
269       }
270       strips()
271       urls()
272       if(hot <= 0){
273          print
274          next
275       }
276       any = 0
277       res = ""
278       s = $0
279       while(match(s,
280             /("[^"]+"|\*[^\*]+\*|`[^'${APO}']+'${APO}'|[-~][-\/:_.[:alnum:]]+|\$[_[:alnum:]]+)#[0-9]+(\|#_?[0-9]+)?/))
281       {
282          pre = substr(s, 1, RSTART - 1)
283          mat = substr(s, RSTART, RLENGTH)
284          s = substr(s, RSTART + RLENGTH)
286          if(match(mat, /\|#_?[0-9]+/)){
287             targ = substr(mat, RSTART + 2)
288             mat = substr(mat, 1, RSTART - 1)
289          }else{
290             match(mat, /#[0-9]+/)
291             targ = substr(mat, RSTART + 1, RLENGTH)
292          }
293          res = res pre "<?lreft " manual "#" targ "<>" mat "?>"
294          any = 1
295       }
296       if(any && length(s))
297          res = res s
298       print any ? res : s
299    }
300    END{
301       print "</pre><?end?>"
302    }
303    ' > "${TMPDIR}/.${PROGRAM}-ann.html"
304 else
305    anntxt=
309 # Upload
311 if [ -n "${bigballs}" ] && yesno 'Upload archives'; then
312    (
313    cd "${TMPDIR}"
315    {
316       echo "-put ${PROGRAM}-${REL}.tar.xz"
317       echo "-rm ${PROGRAM}-latest.tar.xz"
318       echo "-ln -s ${PROGRAM}-${REL}.tar.xz ${PROGRAM}-latest.tar.xz"
320       echo "-put ${PROGRAM}-${REL}.tar.gz"
321       echo "-rm ${PROGRAM}-latest.tar.gz"
322       echo "-ln -s ${PROGRAM}-${REL}.tar.gz ${PROGRAM}-latest.tar.gz"
324       echo "-put ${PROGRAM}-${REL}.tar.xz.asc"
325       echo "-rm ${PROGRAM}-latest.tar.xz.asc"
326       echo "-ln -s ${PROGRAM}-${REL}.tar.xz.asc ${PROGRAM}-latest.tar.xz.asc"
328       echo "-put ${PROGRAM}-${REL}.tar.gz.asc"
329       echo "-rm ${PROGRAM}-latest.tar.gz.asc"
330       echo "-ln -s ${PROGRAM}-${REL}.tar.gz.asc ${PROGRAM}-latest.tar.gz.asc"
332       if [ -n "${anntxt}" ]; then
333          echo "-put ${PROGRAM}-${REL}.txt"
334          echo "-rm ${PROGRAM}-latest.txt"
335          echo "-ln -s ${PROGRAM}-${REL}.txt ${PROGRAM}-latest.txt"
336       fi
338       echo "-chmod 0644 ${PROGRAM}-${REL}.*"
339    } |
340    sftp -b - ${UPLOAD}
341    )
345 # Announcement mail
347 if [ -n "${anntxt}" ] && yesno 'Send announcement mail?'; then
348    LC_ALL=${ORIG_LC_ALL} ${MAILX} -A ${ACCOUNT} \
349       -s "[ANN]ounce of ${UPROGRAM} v${REL}" \
350       -q "${TMPDIR}/${PROGRAM}-${REL}.txt" \
351       -b ${MAILBCC} ${MAILTO}
354 # Finally remove the temporary instances than ran this
355 rm -f .git/mk-release.*
356 echo 'Done'
357 exit
358 # s-sh-mode