123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #!/bin/bash
  2. . "$MKIT_DIR/include/ini.sh" || die "cannot import ini.sh"
  3. build() {
  4. #
  5. # Add meat to all skeletons
  6. #
  7. local srcpath
  8. find src -type f -name '*.skel' \
  9. | while read srcpath;
  10. do
  11. build1 "$srcpath"
  12. done
  13. }
  14. build1() {
  15. #
  16. # Process one skeleton
  17. #
  18. local srcpath dstpath
  19. srcpath=$1
  20. dstpath=${srcpath%.skel}
  21. case $dstpath in
  22. *.md) <"$srcpath" expand_includes | expand_variables >"$dstpath" ;;
  23. *) <"$srcpath" expand_variables >"$dstpath" ;;
  24. esac
  25. echo "$dstpath" >> built.list
  26. }
  27. build_manpages() {
  28. local manfile mdfile
  29. if command -v ronn >/dev/null;
  30. then
  31. ini lskeys "files:man" \
  32. | while read manfile;
  33. do
  34. mdfile="$manfile.md"
  35. ronn -r "$mdfile"
  36. echo "$manfile" >> built.list
  37. done
  38. else
  39. echo "ronn is not installed"
  40. return 1
  41. fi
  42. }
  43. clean() {
  44. #
  45. # Clean up tree after building
  46. #
  47. test -f built.list && {
  48. <built.list xargs rm -f
  49. rm -f built.list
  50. }
  51. true
  52. }
  53. dist() {
  54. #
  55. # Create distributable tarball
  56. #
  57. local version=$(get_version)
  58. local dirname=$MKIT_PKGNAME-$version
  59. mkdir -p "$dirname"
  60. local item
  61. cp -R "$(ini values "lists:dist")" "$dirname"
  62. sed -i -e "s/^VERSION = .*/VERSION = $version/" "$dirname/config.mk"
  63. tar -cf "$dirname.tar" "$dirname"
  64. gzip "$dirname.tar"
  65. rm -rf "$dirname"
  66. }
  67. expand_includes() {
  68. #
  69. # Expand include directives
  70. #
  71. # Expand e.g. `<!-- include4: foo.sh -->` to include code of foo.sh
  72. #
  73. perl -we '
  74. use strict;
  75. my $text;
  76. while (<>) {
  77. chomp;
  78. if (m/<!-- include4: (\S+) -->/) {
  79. open my $fh, $1 or warn "cannot find: $1";
  80. my $text = do { local($/); <$fh> };
  81. close $fh;
  82. $text =~ s/^(.)/ $1/gm;
  83. chomp $text;
  84. print "$text\n";
  85. } else {
  86. print "$_\n";
  87. }
  88. }
  89. '
  90. }
  91. expand_variables() {
  92. #
  93. # Expand variable values
  94. #
  95. local script=$(mktemp --tmpdir mkit-tmp.XXXXXXXXXX)
  96. local varname varvalue
  97. ini lskeys "vars" \
  98. | while read varname;
  99. do
  100. varvalue="$(ini 1value "vars:$varname" | sed -e 's/\$/\\$/' )"
  101. echo "s|$varname|$varvalue|;" >> "$script"
  102. done
  103. echo "s|__CODENAME__|$CODENAME|;" >> "$script"
  104. echo "s|__VERSION__|$(get_version)|;" >> "$script"
  105. perl -wp "$script"
  106. rm "$script"
  107. }
  108. get_version() {
  109. #
  110. # Build semver version string with build metadata
  111. #
  112. # Build version string from available info using following
  113. # logic:
  114. #
  115. # 1. use VERSION (from config.mk)
  116. # 2. if we are in git, override the version with last tag
  117. # 3. if set, add PRERELEASE (from config.mk) as pre-release ID
  118. # (afer dash)
  119. # 4. if we are at a later commit than the last tag, add branch
  120. # name and commit sha1 to build metadata (after plus sign)
  121. # 5. if the tree is "dirty", i.e. has uncommited changes,
  122. # add "dirty" to build metadata
  123. #
  124. # The version is compatible with SemVer 2.0.0.
  125. #
  126. # Examples:
  127. #
  128. # myprog v1.0.7 # all clear
  129. # myprog v1.0.7-alpha # PRERELEASE="alpha"
  130. # myprog v1.0.7-alpha+g1aef811.master # ^^ + some commits after
  131. # myprog v1.0.7-alpha+gf14fc4f.api2 # ^^ + on a feature branch
  132. # myprog v1.0.7-alpha+gf14fc4f.api2.dirty # ^^ + tree edited
  133. # myprog v1.0.7-alpha+dirty # tag OK but tree edited
  134. # myprog v1.0.7+dirty # ^^ but no pre-release id
  135. #
  136. # Note that versions with "dirty" should be perceived as kind of
  137. # dangerous outside developer's own machine. Versions with sha1 are
  138. # safer but must not be released.
  139. #
  140. # I have considered decorating the git commit refs to make them
  141. # sort of sortable (e.g. "r1.g1aef811"), but on second thought,
  142. # I don't think it's good idea to give *any* semantics to meta-data
  143. # at all. First, there is no rule that r1<r2<r3; a commit can be
  144. # removing what other just added and one change can be split to
  145. # multiple commits. Also, the whole thing breaks anyway once you
  146. # rebase your branch (no, it's not a sin). The sole purpose of
  147. # meta-data is to *identify* the code, and provide safe path back
  148. # to tree; commit refs are already perfect for that.
  149. #
  150. # FIXME: Using PRERELEASE for release IDs may not be compatible with
  151. # release strategy implemented in release.sh
  152. #
  153. local version=$VERSION
  154. local prerl=$PRERELEASE
  155. grep ":" <<<"$prerl" && warn "colon in PRERELEASE may corrupt version data: $prerl"
  156. if git rev-parse HEAD >&/dev/null;
  157. then # we are in git repo... so we can get smart
  158. local lasttag=$(git tag | grep ^v | sort -V | tail -n1)
  159. if ! git describe --tags --exact-match HEAD >&/dev/null;
  160. then # we are at a later commit than the last tag
  161. local sha=g$(git log -1 --pretty=format:%h HEAD)
  162. local curbranch=$(git rev-parse --abbrev-ref HEAD)
  163. local commit="$curbranch.$sha"
  164. fi
  165. if test "$(git diff --shortstat 2>/dev/null)" != "";
  166. then # the tree is "dirty", i.e. has been edited
  167. local dirty=dirty
  168. fi
  169. test -n "$lasttag" && version=${lasttag:1}
  170. local suffix=""
  171. case "$commit:$dirty" in
  172. :) suffix="" ;;
  173. :dirty) suffix="+$dirty" ;;
  174. *:) suffix="+$commit" ;;
  175. *:dirty) suffix="+$commit.$dirty" ;;
  176. esac
  177. test -b "$prerl" && suffix="-$prerl$suffix"
  178. version="$version$suffix"
  179. fi
  180. echo "$version"
  181. }