123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #!/bin/bash
  2. # saturnin - Smart and ready desktop helper
  3. # See LICENSE file for copyright and license details.
  4. tmp=$(mktemp)
  5. sed -e 's/ = /=/' < config.mk > $tmp
  6. . $tmp
  7. rm -f $tmp
  8. bindir=${DESTDIR}${PREFIX}/bin
  9. shrdir=${DESTDIR}${PREFIX}/share/saturnin
  10. lexdir=${DESTDIR}${PREFIX}/libexec/saturnin
  11. list_of_bins() {
  12. echo bin/saturnin
  13. }
  14. list_of_lexs() {
  15. echo libexec/saturnin-czrates
  16. echo libexec/saturnin-clip
  17. echo libexec/saturnin-dmenu
  18. echo libexec/saturnin-iam
  19. echo libexec/saturnin-conf
  20. echo libexec/saturnin-ip
  21. echo libexec/saturnin-ln
  22. echo libexec/saturnin-push
  23. echo libexec/saturnin-revert
  24. echo libexec/saturnin-watch
  25. echo libexec/saturnin-www
  26. }
  27. list_of_installed_bins() {
  28. list_of_bins | sed -e "s/bin/$(sed -e 's/\//\\\//g' <<<$bindir)/"
  29. }
  30. list_of_installed_lexs() {
  31. list_of_lexs | sed -e "s/libexec/$(sed -e 's/\//\\\//g' <<<$lexdir)/"
  32. }
  33. die() {
  34. for l in "$@"; do echo "$l" >&2; done
  35. exit 9
  36. }
  37. list_of_shrs() {
  38. echo ffoo/saturnin_www.sh
  39. }
  40. build1() {
  41. local srcpath dstpath
  42. srcpath=$1
  43. dstpath=${srcpath%.skel}
  44. case $dstpath in
  45. *.md) cat $srcpath \
  46. | expand_includes \
  47. | expand_variables \
  48. > $dstpath ;;
  49. *) cat $srcpath \
  50. | expand_variables \
  51. > $dstpath ;;
  52. esac
  53. echo $dstpath >> built.list
  54. }
  55. build() {
  56. local srcpath
  57. find -type f -name '*.skel' \
  58. | while read srcpath;
  59. do
  60. build1 "$srcpath"
  61. done
  62. }
  63. clean() {
  64. #
  65. # Clean up tree after building
  66. #
  67. test -f built.list && {
  68. cat built.list | xargs rm -f
  69. rm -f built.list
  70. } || :
  71. }
  72. dist() {
  73. #
  74. # Create distributable tarball
  75. #
  76. local version=$(get_version)
  77. local dirname=saturnin-$version
  78. mkdir -p $dirname
  79. cp -R bin \
  80. config.mk \
  81. ffoo \
  82. Makefile \
  83. README \
  84. LICENSE \
  85. setup \
  86. utils \
  87. $dirname
  88. sed -i -e "s/^VERSION = .*/VERSION = $version/" $dirname/config.mk
  89. tar -cf $dirname.tar $dirname
  90. gzip $dirname.tar
  91. rm -rf $dirname
  92. }
  93. expand_includes() {
  94. #
  95. # Expand include directives
  96. #
  97. # Expand e.g. `<!-- include4: foo.sh -->` to include code of foo.sh
  98. #
  99. perl -we '
  100. use strict;
  101. my $text;
  102. while (<>) {
  103. chomp;
  104. if (m/<!-- include4: (\S+) -->/) {
  105. open my $fh, $1 or warn "cannot find: $1";
  106. my $text = do { local($/); <$fh> };
  107. close $fh;
  108. $text =~ s/^(.)/ $1/gm;
  109. chomp $text;
  110. print "$text\n";
  111. } else {
  112. print "$_\n";
  113. }
  114. }
  115. '
  116. }
  117. expand_variables() {
  118. #
  119. # Expand variable values
  120. #
  121. perl -pe "
  122. s|__SATURNIN_CONFIG_LOCAL__|$SATURNIN_CONFIG_PATH_LOCAL|;
  123. s|__SATURNIN_CONFIG_USER__|\\\$HOME/$SATURNIN_CONFIG_PATH_USER|;
  124. s|__SATURNIN_CACHE_HOME__|\\\$HOME/$SATURNIN_CACHE_HOME|;
  125. s|__SATURNIN_SHARE__|$shrdir|;
  126. s|__SATURNIN_LIBEXEC__|$lexdir|;
  127. s|__VERSION__|$(get_version)|;
  128. "
  129. }
  130. install() {
  131. #
  132. # Install product
  133. #
  134. mkdir -vp $bindir \
  135. $shrdir/ffoo \
  136. $lexdir
  137. list_of_bins | xargs cp -vrt $bindir
  138. list_of_shrs | xargs cp -vrt $shrdir/ffoo
  139. list_of_lexs | xargs cp -vrt $lexdir
  140. list_of_installed_bins | xargs chmod -v 755
  141. list_of_installed_lexs | xargs chmod -v 755
  142. test -f .autoclean && clean || :
  143. }
  144. get_version() {
  145. #
  146. # Build semver version string with build metadata
  147. #
  148. # Build version string from available info using following
  149. # logic:
  150. #
  151. # 1. use VERSION (from config.mk)
  152. # 2. if we are in git, override the version with last tag
  153. # 3. if set, add STAGE (from config.mk) as pre-release ID
  154. # (afer dash)
  155. # 4. if we are at a later commit than the last tag, add commit
  156. # sha1 to build metadata (after plus sign)
  157. # 5. if the tree is "dirty", i.e. has uncommited changes,
  158. # add "dirty" to build metadata
  159. #
  160. # The version is compatible with SemVer 2.0.0.
  161. #
  162. # Examples:
  163. #
  164. # myprog v1.0.7 # all clear
  165. # myprog v1.0.7-alpha # STAGE="alpha"
  166. # myprog v1.0.7-alpha+g1aef811 # ^^ + some commits after
  167. # myprog v1.0.7-alpha+g1aef811.dirty # ^^ + tree edited
  168. # myprog v1.0.7-alpha+dirty # tag OK but tree edited
  169. # myprog v1.0.7+dirty # ^^ but no stage
  170. #
  171. # Note that versions with "dirty" should be perceived as kind of
  172. # dangerous outside developer's own machine. Versions with sha1 are
  173. # safer but must not be released.
  174. #
  175. # I have considered decorating the git commit refs to make them
  176. # sort of sortable (e.g. "r1.g1aef811"), but on second thought,
  177. # I don't think it's good idea to give *any* semantics to meta-data
  178. # at all. First, there is no rule that r1<r2<r3; a commit can be
  179. # removing what other just added and one change can be split to
  180. # multiple commits. Also, the whole thing breaks anyway once you
  181. # rebase your branch (no, it's not a sin). The sole purpose of
  182. # meta-data is to *identify* the code, and provide safe path back
  183. # to tree; commit refs are already perfect for that.
  184. #
  185. local version=$VERSION
  186. local stage=$STAGE
  187. if git rev-parse HEAD >&/dev/null;
  188. then # we are in git repo... so we can get smart
  189. local lasttag=$(git tag | grep ^v | sort -V | tail -n1)
  190. if ! git describe --tags --exact-match HEAD >&/dev/null;
  191. then # we are not at later commit than the last tag
  192. local sha=g$(git log -1 --pretty=format:%h HEAD)
  193. fi
  194. if test "$(git diff --shortstat 2>/dev/null)" != "";
  195. then # thr tree is "dirty", i.e. has been edited
  196. local dirty=dirty
  197. fi
  198. version=${lasttag:1}
  199. local suffix=""
  200. case $stage:$sha:$dirty in
  201. ::) suffix="" ;;
  202. ::dirty) suffix="+$dirty" ;;
  203. :g*:) suffix="+$sha" ;;
  204. :g*:dirty) suffix="+$sha.dirty" ;;
  205. *::) suffix="-$stage" ;;
  206. *::dirty) suffix="-$stage+$dirty" ;;
  207. *:g*:) suffix="-$stage+$sha" ;;
  208. *:g*:dirty) suffix="-$stage+$sha.$dirty" ;;
  209. esac
  210. version=$version$suffix
  211. fi
  212. echo $version
  213. }
  214. uninstall() {
  215. #
  216. # Uninstall product
  217. #
  218. list_of_installed_bins | xargs rm -vf
  219. rm -vrf $shrdir
  220. rm -vrf $lexdir
  221. }
  222. case $1 in
  223. build|clean|dist|install|install_manpages|manpages|uninstall)
  224. $1
  225. ;;
  226. *)
  227. echo "usage: $(basename $0) build|clean|dist|install|uninstall" >&2
  228. esac