#!/bin/bash # saturnin - Smart and ready desktop helper # See LICENSE file for copyright and license details. tmp=$(mktemp) sed -e 's/ = /=/' < config.mk > $tmp . $tmp rm -f $tmp bindir=${DESTDIR}${PREFIX}/bin shrdir=${DESTDIR}${PREFIX}/share/saturnin lexdir=${DESTDIR}${PREFIX}/libexec/saturnin list_of_bins() { echo bin/saturnin } list_of_lexs() { echo libexec/saturnin-czrates echo libexec/saturnin-dmenu echo libexec/saturnin-iam echo libexec/saturnin-conf echo libexec/saturnin-ip echo libexec/saturnin-ln echo libexec/saturnin-push echo libexec/saturnin-revert echo libexec/saturnin-watch echo libexec/saturnin-www } list_of_installed_bins() { list_of_bins | sed -e "s/bin/$(sed -e 's/\//\\\//g' <<<$bindir)/" } list_of_installed_lexs() { list_of_lexs | sed -e "s/libexec/$(sed -e 's/\//\\\//g' <<<$lexdir)/" } die() { for l in "$@"; do echo "$l" >&2; done exit 9 } list_of_shrs() { echo ffoo/saturnin_www.sh } build1() { local srcpath dstpath srcpath=$1 dstpath=${srcpath%.skel} case $dstpath in *.md) cat $srcpath \ | expand_includes \ | expand_variables \ > $dstpath ;; *) cat $srcpath \ | expand_variables \ > $dstpath ;; esac echo $dstpath >> built.list } build() { local srcpath find -type f -name '*.skel' \ | while read srcpath; do build1 "$srcpath" done } clean() { # # Clean up tree after building # test -f built.list && { cat built.list | xargs rm -f rm -f built.list } || : } dist() { # # Create distributable tarball # local version=$(get_version) local dirname=saturnin-$version mkdir -p $dirname cp -R bin \ config.mk \ ffoo \ Makefile \ README \ LICENSE \ setup \ utils \ $dirname sed -i -e "s/^VERSION = .*/VERSION = $version/" $dirname/config.mk tar -cf $dirname.tar $dirname gzip $dirname.tar rm -rf $dirname } expand_includes() { # # Expand include directives # # Expand e.g. `` to include code of foo.sh # perl -we ' use strict; my $text; while (<>) { chomp; if (m//) { open my $fh, $1 or warn "cannot find: $1"; my $text = do { local($/); <$fh> }; close $fh; $text =~ s/^(.)/ $1/gm; chomp $text; print "$text\n"; } else { print "$_\n"; } } ' } expand_variables() { # # Expand variable values # perl -pe " s|__SATURNIN_CONFIG_LOCAL__|$SATURNIN_CONFIG_PATH_LOCAL|; s|__SATURNIN_CONFIG_USER__|\\\$HOME/$SATURNIN_CONFIG_PATH_USER|; s|__SATURNIN_SHARE__|$shrdir|; s|__SATURNIN_LIBEXEC__|$lexdir|; s|__VERSION__|$(get_version)|; " } install() { # # Install product # mkdir -vp $bindir \ $shrdir/ffoo \ $lexdir list_of_bins | xargs cp -vrt $bindir list_of_shrs | xargs cp -vrt $shrdir/ffoo list_of_lexs | xargs cp -vrt $lexdir list_of_installed_bins | xargs chmod -v 755 list_of_installed_lexs | xargs chmod -v 755 test -f .autoclean && clean || : } get_version() { # # Build semver version string with build metadata # # Build version string from available info using following # logic: # # 1. use VERSION (from config.mk) # 2. if we are in git, override the version with last tag # 3. if set, add STAGE (from config.mk) as pre-release ID # (afer dash) # 4. if we are at a later commit than the last tag, add commit # sha1 to build metadata (after plus sign) # 5. if the tree is "dirty", i.e. has uncommited changes, # add "dirty" to build metadata # # The version is compatible with SemVer 2.0.0. # # Examples: # # myprog v1.0.7 # all clear # myprog v1.0.7-alpha # STAGE="alpha" # myprog v1.0.7-alpha+g1aef811 # ^^ + some commits after # myprog v1.0.7-alpha+g1aef811.dirty # ^^ + tree edited # myprog v1.0.7-alpha+dirty # tag OK but tree edited # myprog v1.0.7+dirty # ^^ but no stage # # Note that versions with "dirty" should be perceived as kind of # dangerous outside developer's own machine. Versions with sha1 are # safer but must not be released. # # I have considered decorating the git commit refs to make them # sort of sortable (e.g. "r1.g1aef811"), but on second thought, # I don't think it's good idea to give *any* semantics to meta-data # at all. First, there is no rule that r1&/dev/null; then # we are in git repo... so we can get smart local lasttag=$(git tag | grep ^v | sort -V | tail -n1) if ! git describe --tags --exact-match HEAD >&/dev/null; then # we are not at later commit than the last tag local sha=g$(git describe --always HEAD) fi if test "$(git diff --shortstat 2>/dev/null)" != ""; then # thr tree is "dirty", i.e. has been edited local dirty=dirty fi version=${lasttag:1} local suffix="" case $stage:$sha:$dirty in ::) suffix="" ;; ::dirty) suffix="+$dirty" ;; :g*:) suffix="+$sha" ;; :g*:dirty) suffix="+$sha.dirty" ;; *::) suffix="-$stage" ;; *::dirty) suffix="-$stage+$dirty" ;; *:g*:) suffix="-$stage+$sha" ;; *:g*:dirty) suffix="-$stage+$sha.$dirty" ;; esac version=$version$suffix fi echo $version } uninstall() { # # Uninstall product # list_of_installed_bins | xargs rm -vf rm -vrf $shrdir rm -vrf $lexdir } case $1 in build|clean|dist|install|install_manpages|manpages|uninstall) $1 ;; *) echo "usage: $(basename $0) build|clean|dist|install|uninstall" >&2 esac