imapfilter convenience wrapper

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. #!/bin/bash
  2. # MKit - simple install helper
  3. # See LICENSE file for copyright and license details.
  4. mkit_import ini
  5. mkit_import facts
  6. __release__bump_version() {
  7. #
  8. # Bump version on stdin by level $1 (x, y or z)
  9. #
  10. local rlevel=$1 # release level
  11. local old # old version
  12. local oldx # ... X
  13. local oldz # ... Z
  14. local oldy # ... Y
  15. local tmpy # Y parsing cache
  16. local new # bumped version
  17. read -r old
  18. oldx=${old%.*.*}
  19. oldz=${old#*.*.}
  20. tmpy=${old%.*}
  21. oldy=${tmpy#*.}
  22. case $rlevel in
  23. x) new="$((oldx+MKIT_BUMPSIZE)).0.0" ;;
  24. y) new="$oldx.$((oldy+MKIT_BUMPSIZE)).0" ;;
  25. z) new="$oldx.$oldy.$((oldz+MKIT_BUMPSIZE))" ;;
  26. *) die "invalid release level: $1" ;;
  27. esac
  28. echo "$new"
  29. }
  30. __release__check() {
  31. #
  32. # Die if blocking condition $1 is detected
  33. #
  34. local condition=$1 # condition name
  35. local oracle # expected value
  36. case "$condition" in
  37. git_present)
  38. git rev-parse HEAD >&/dev/null\
  39. || die "cannot do this outside git repo"
  40. ;;
  41. at_relsrc)
  42. oracle=$(ini 1value project:relsrc)
  43. git_fact current_branch \
  44. | grep -qFxe "$oracle" \
  45. || die "you are not on release source branch: $oracle"
  46. ;;
  47. not_dirty)
  48. git diff --shortstat 2>/dev/null \
  49. | grep -q . \
  50. && die "tree is dirty!"
  51. ;;
  52. tags_ok)
  53. git_fact latest_tag \
  54. | grep -q . \
  55. || die "cannot find latest tag"
  56. ;;
  57. vbump_hot)
  58. git diff-tree --no-commit-id --name-only -r HEAD \
  59. | grep -qFx mkit.ini \
  60. || die "last change must be version bump in mkit.ini"
  61. ;;
  62. no_wip)
  63. git_fact reldiff_brief \
  64. | grep -iE \
  65. -e '^[^ ]+ WIP ' \
  66. -e '^[^ ]+ WIP$' \
  67. -e '^[^ ]+ WIP:' \
  68. && die "WIP commit since $(git_fact latest_tag)"
  69. ;;
  70. ini_version)
  71. oracle=$(git_fact latest_version | __release__bump_version "$rlevel")
  72. ini 1value project:version \
  73. | grep -qFxe "$oracle" \
  74. || die "new version not in mkit.ini: $oracle"
  75. ;;
  76. *)
  77. die "unknown release check: $condition"
  78. ;;
  79. esac
  80. }
  81. __release() {
  82. #
  83. # Prepare release
  84. #
  85. # Span release routines: make a signed tag, check branch
  86. # and update release branch
  87. #
  88. # FIXME: Using project:prerl as build.sh:semver() does may not be
  89. # compatible with this release strategy
  90. #
  91. local rlevel=$1 # release level (x, y or z)
  92. local newtag # new tag
  93. local relsrc # release source branch (if any)
  94. local reldst # release destination branch (if any)
  95. __release__check git_present
  96. __release__check at_relsrc
  97. __release__check not_dirty
  98. __release__check tags_ok
  99. __release__check vbump_hot
  100. __release__check no_wip
  101. __release__check ini_version
  102. newtag=$(git_fact latest_version | __release__bump_version "$rlevel" | git_ver2tag )
  103. set -e
  104. debug_var newtag
  105. $MKIT_DRY && return
  106. git tag -m "$(__release_msg)" "$newtag"
  107. relsrc=$(ini 1value project:relsrc)
  108. reldst=$(ini 1value project:reldst)
  109. debug_var relsrc reldst
  110. if test -n "$reldst" && test "$reldst" != "$relsrc"; then
  111. git branch -f "$reldst" "$newtag"
  112. fi
  113. }
  114. __release_msg() {
  115. #
  116. # Generate message for annotated tag
  117. #
  118. # The last commit before issuing a release must be "Bump version" commit
  119. # suggested by __release__vbump_gitmsg() and manually edited by user. Since the
  120. # commit contains changelog, this function just uses the message body.
  121. #
  122. # The sort message (first line) is replaced with a nicer one (with project
  123. # name, codename and version).
  124. #
  125. echo "$(ini 1value project:name) $newtag - $(ini 1value project:codename)"
  126. echo
  127. git show -s --format=%B \
  128. | tail -n +3
  129. }
  130. __release__update_ini() {
  131. #
  132. # Change project:version in mkit.ini at path $2 to value $1
  133. #
  134. local version=$1 # new version
  135. local inifile=$2 # mkit.ini path
  136. local tmp # mkit.ini cache
  137. tmp=$(mktemp -t mkit.__release__update_ini.XXXXXXXX)
  138. <"$inifile" perl -e '
  139. my $hit = 0;
  140. my $done = 0;
  141. foreach (<STDIN>) {
  142. if ($done) { print; next; }
  143. elsif (m/\[project\]/) { $hit++; print; next; }
  144. elsif (m/\[/) { $hit = 0; print; next; }
  145. elsif ($hit) { s/\bversion\b( *)=( *).*/version$1=$2$ARGV[0]/ and $done++; print; }
  146. else { print; next; }
  147. }
  148. ' "$version" >"$tmp" || die "failed to update version in mkit.ini"
  149. mv "$tmp" "$inifile"
  150. }
  151. __release__vbump() {
  152. #
  153. # Do version bump at level $1
  154. #
  155. # Perform checks, compute new version, update mkit.ini and initiate
  156. # 'Bump version' commit with changelog template.
  157. #
  158. local rlevel=$1 # bump level (x, y or z)
  159. local nextver # version after the bump
  160. local cache # cache for the message
  161. __release__check git_present
  162. __release__check at_relsrc
  163. __release__check not_dirty
  164. nextver=$(ini 1value project:version | __release__bump_version "$rlevel")
  165. debug_var nextver
  166. $MKIT_DRY && return
  167. __release__update_ini "$nextver" mkit.ini \
  168. || die "failed to update version in mkit.ini"
  169. git add mkit.ini \
  170. || die "failed to add mkit.ini to the index"
  171. cache=$(mktemp -t "mkit.__release__vbump_gitmsg.XXXXXXXX")
  172. __release__vbump_gitmsg "$nextver" > "$cache"
  173. git commit -e -F "$cache" # note: reading from stdin will break vim
  174. rm "$cache"
  175. }
  176. __release__vbump_gitmsg() {
  177. #
  178. # Compose git message template for 'Bump version' commit
  179. #
  180. local nextver=$1
  181. echo "Bump version to $nextver"
  182. echo ""
  183. echo "Overview of changes:"
  184. echo ""
  185. git_fact reldiff \
  186. | sed '
  187. s/^[a-f0-9]\{7\} /\n * &/; t PATHS
  188. s/^/ /
  189. :PATHS
  190. '
  191. }
  192. release() {
  193. #
  194. # Perform release on Z level
  195. #
  196. __release z
  197. }
  198. release_x() {
  199. #
  200. # Perform release on X level
  201. #
  202. __release x
  203. }
  204. release_y() {
  205. #
  206. # Perform release on Y level
  207. #
  208. __release y
  209. }
  210. release_z() {
  211. #
  212. # Perform release on Z level
  213. #
  214. __release z
  215. }
  216. vbump() {
  217. #
  218. # Perform version bump on Z level
  219. #
  220. __release__vbump z
  221. }
  222. vbump_x() {
  223. #
  224. # Perform version bump on X level
  225. #
  226. __release__vbump x
  227. }
  228. vbump_y() {
  229. #
  230. # Perform version bump on Y level
  231. #
  232. __release__vbump y
  233. }
  234. vbump_z() {
  235. #
  236. # Perform version bump on Z level
  237. #
  238. __release__vbump z
  239. }