| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 | #!/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. `<!-- include4: foo.sh -->` to include code of foo.sh
    #
    perl -we '
        use strict;
        my $text;
        while (<>) {
            chomp;
            if (m/<!-- include4: (\S+) -->/) {
                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<r2<r3; a commit can be
    # removing what other just added and one change can be split to
    # multiple commits.  Also, the whole thing breaks anyway once you
    # rebase your branch (no, it's not a sin).  The sole purpose of
    # meta-data is to *identify* the code, and provide safe path back
    # to tree; commit refs are already perfect for that.
    #
    local version=$VERSION
    local stage=$STAGE
    if git rev-parse HEAD >&/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
 |