Working Saturnin-based meta-command

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/bin/bash
  2. . "$MKIT_DIR/include/ini.sh" || die "cannot import ini.sh"
  3. . "$MKIT_DIR/include/facts.sh" || die "cannot import facts.sh"
  4. _bump_version() {
  5. #
  6. # Bump version on stdin by level $1 (x, y or z)
  7. #
  8. local rlevel=$1
  9. local old
  10. read -r old
  11. local oldx=${old%.*.*}
  12. local oldz=${old#*.*.}
  13. local tmpy=${old%.*}
  14. local oldy=${tmpy#*.}
  15. local new=""
  16. case $rlevel in
  17. x) new="$((oldx+MKIT_BUMPSIZE)).0.0" ;;
  18. y) new="$oldx.$((oldy+MKIT_BUMPSIZE)).0" ;;
  19. z) new="$oldx.$oldy.$((oldz+MKIT_BUMPSIZE))" ;;
  20. *) die "invalid release level: $1" ;;
  21. esac
  22. echo "$new"
  23. }
  24. _relck() {
  25. #
  26. # Die if blocking condition $1 is detected
  27. #
  28. local condition="$1"
  29. local x
  30. case "$condition" in
  31. git_present)
  32. git rev-parse HEAD >&/dev/null\
  33. || die "cannot do this outside git repo"
  34. ;;
  35. at_relsrc)
  36. local relsrc=$(ini 1value project:relsrc)
  37. git_fact current_branch \
  38. | grep -qFx "$relsrc" \
  39. || die "you are not on release source branch: $relsrc"
  40. ;;
  41. not_dirty)
  42. git diff --shortstat 2>/dev/null \
  43. | grep -q . \
  44. && die "tree is dirty: $dirt"
  45. ;;
  46. tags_ok)
  47. git_fact latest_tag \
  48. | grep -q . \
  49. || die "cannot find latest tag"
  50. ;;
  51. vbump_hot)
  52. git diff-tree --no-commit-id --name-only -r HEAD \
  53. | grep -qFx mkit.ini \
  54. || die "last change must be version bump in mkit.ini"
  55. ;;
  56. no_wip)
  57. git_fact reldiff \
  58. | grep '^....... WIP ' \
  59. && die "WIP commit since $(git_fact latest_tag)"
  60. ;;
  61. ini_version)
  62. local oracle=$(git_fact latest_version | _bump_version "$rlevel")
  63. ini 1value project:version \
  64. | grep -qFx "$oracle" \
  65. || die "new version not in mkit.ini: $oracle"
  66. ;;
  67. *)
  68. die "unknown release check: $condition"
  69. ;;
  70. esac
  71. }
  72. _release() {
  73. #
  74. # Prepare release
  75. #
  76. # Span release routines: make a signed tag, check branch
  77. # and update release branch
  78. #
  79. # FIXME: Using project:prerl as build.sh:semver() does may not be
  80. # compatible with this release strategy
  81. #
  82. local rlevel=$1
  83. local newtag
  84. local reldst
  85. _relck git_present
  86. _relck at_relsrc
  87. _relck not_dirty
  88. _relck tags_ok
  89. _relck vbump_hot
  90. _relck no_wip
  91. _relck ini_version
  92. newtag=$(git_fact latest_version | _bump_version "$rlevel" | git_ver2tag )
  93. set -e
  94. debug_var newtag
  95. $MKIT_DRY && return
  96. git tag -m "$(_release_msg)" "$newtag"
  97. reldst=$(ini 1value project:reldst)
  98. debug_var reldst
  99. if test -n "$reldst";
  100. then
  101. git branch -f "$reldst" "$newtag"
  102. fi
  103. }
  104. _release_msg() {
  105. #
  106. # Generate message for annotated tag
  107. #
  108. # The last commit before issuing a release must be "Bump version" commit
  109. # suggested by _vbump_gitmsg() and manually edited by user. Since the
  110. # commit contains changelog, this function just uses the message body.
  111. #
  112. # The sort message (first line) is replaced with a nicer one (with project
  113. # name, codename and version).
  114. #
  115. echo "$(ini 1value project:name) $newtag - $(ini 1value project:codename)"
  116. echo
  117. git show -s --format=%B \
  118. | tail -n +3
  119. }
  120. _vbump() {
  121. local rlevel="$1"
  122. local nextver # after the bump
  123. _relck git_present
  124. _relck at_relsrc
  125. _relck not_dirty
  126. nextver=$(ini 1value project:version | _bump_version "$rlevel")
  127. debug_var nextver
  128. $MKIT_DRY && return
  129. update_version "$nextver" mkit.ini \
  130. || die "failed to update version in mkit.ini"
  131. git add mkit.ini \
  132. || die "failed to add mkit.ini to the index"
  133. git commit -e -m "$(_vbump_gitmsg)"
  134. }
  135. _vbump_gitmsg() {
  136. echo "Bump version"
  137. echo ""
  138. echo "Overview of changes:"
  139. echo ""
  140. git_fact reldiff \
  141. | sed '
  142. s/^[a-f0-9]\{7\} / * &/; t PATHS
  143. s/^/ /
  144. :PATHS
  145. '
  146. }
  147. release_x() {
  148. _release x
  149. }
  150. release_y() {
  151. _release y
  152. }
  153. release_z() {
  154. _release z
  155. }
  156. vbump_x() {
  157. _vbump x
  158. }
  159. vbump_y() {
  160. _vbump y
  161. }
  162. vbump_z() {
  163. _vbump z
  164. }