lib/update.updates
author Tero Marttila <terom@paivola.fi>
Tue, 20 Mar 2012 14:12:11 +0200
changeset 575 b68b8615c512
child 578 a2d87cfd77e4
permissions -rw-r--r--
update: split out code into lib/update.foo
# vim: set ft=sh :
#
# Dependency-based updates + utils

## Compare the given output file with all given source files:
#
#   check_update $out ${deps[@]} && do_update $out ... || ...
#
# Returns true if the output file needs to be updated.
function check_update {
    # target
    local out=$1; shift

    debug "$out"

    # need update?
    local update=

    if [ ${#@} == 0 ]; then
        debug "  update: unknown deps"
        update=y

    elif [ ! -e $out ]; then
        debug "  update: dest missing"
        update=y
        
    elif [ $UPDATE_FORCE ]; then
        debug "  update: forced"
        update=y
    fi

    # check deps
    for dep in "$@"; do
        # don't bother checking if already figured out
        [ $update ] && continue

        # check
        if [ ! -e $ROOT/$dep ]; then
            fail "$dst: Missing source: $dep"

        elif [ $ROOT/$out -ot $ROOT/$dep ]; then
            debug "  update: $dep"
            update=y
        else
            debug "  check: $dep"
        fi
    done

    [ ! $update ] && debug "  up-to-date"

    # return
    [ $update ]
}

## Generate updated output file from given command's stdout:
#
#   do_update $out $BIN/cmd --args
#
# Writes output to a temporary .new file, optionally shows a diff of changes, and commits
# the new version to $out (unless noop'd).
function do_update {
    local out=$1; shift
    local tmp=$out.new

    debug "$out"
    cmd "$@" > $ROOT/$tmp

    # compare
    if [ -e $ROOT/$out ] && [ $UPDATE_DIFF ]; then
        debug "  changes:"

        # terse
        indent "        " diff --unified=1 $ROOT/$out $ROOT/$tmp || true
    fi
    
    # deploy
    if [ $UPDATE_NOOP ]; then
        # cleanup
        debug "  no-op"

        cmd rm $ROOT/$tmp
    else
        # commit
        debug "  deploy"

        cmd mv $ROOT/$tmp $ROOT/$out
    fi
}

## Look for a link target:
#
#   find_link   $lnk    $tgt...
#
# Outputs the first given target to exist, skipping any that are the same as the given $lnk.
# If no $tgt matches, outputs the last one, or '-'.
function choose_link {
    local lnk=$1; shift
    local tgt=-

    for tgt in "$@"; do
        [ $tgt != $out ] && [ -e $ROOT/$tgt ] && break
    done
    
    echo $tgt
}


## Compare symlink to target:
#
#   check_link $lnk $tgt && do_link $lnk $tgt || ...
#
# Tests if the symlink exists, and the target matches.
# Fails if the target does not exist.
function check_link {
    local lnk=$1
    local tgt=$2

    [ ! -e $ROOT/$tgt ] && fail "$tgt: target does not exist"
    
    [ ! -e $ROOT/$lnk ] || [ $(readlink $ROOT/$lnk) != $ROOT/$tgt ]
}

## Update symlink to point to target:
#
#   do_link $lnk $tgt
#
function do_link {
    local lnk=$1
    local tgt=$2

    cmd ln -sf $ROOT/$tgt $ROOT/$lnk
}

## Update .serial number:
#
#   do_update_serial $serial
#
# Shows old/new serial on debug.
function do_update_serial {
    local serial=$1

    # read
    local old=$(test -e $ROOT/$serial && cat $ROOT/$serial || echo '')


    cmd $BIN/update-serial $ROOT/$serial
    
    # read
    local new=$(cat $ROOT/$serial)
        
    debug "  $old -> $new"
}

## Perform `hg commit` for $DATA
function do_commit {
    local msg=$1

    indent "    " hg_diff

    hg_commit "$msg"
}