terom@52: # vim: set ft=sh : terom@52: # terom@52: # Dependency-based updates + utils terom@52: terom@52: ## Compare the given output file with all given source files: terom@52: # terom@52: # check_update $out ${deps[@]} && do_update $out ... || ... terom@52: # terom@52: # Returns true if the output file needs to be updated. terom@52: function check_update { terom@52: # target terom@52: local out=$1; shift terom@52: terom@52: debug "$out" terom@52: terom@52: # need update? terom@52: local update= terom@52: terom@52: if [ ${#@} == 0 ]; then terom@52: debug " update: unknown deps" terom@52: update=y terom@52: terom@52: elif [ ! -e $out ]; then terom@52: debug " update: dest missing" terom@52: update=y terom@52: terom@52: elif [ $UPDATE_FORCE ]; then terom@52: debug " update: forced" terom@52: update=y terom@52: fi terom@52: terom@52: # check deps terom@52: for dep in "$@"; do terom@52: # don't bother checking if already figured out terom@52: [ $update ] && continue terom@52: terom@52: # check terom@52: if [ ! -e $ROOT/$dep ]; then terom@52: fail "$dst: Missing source: $dep" terom@52: terom@52: elif [ $ROOT/$out -ot $ROOT/$dep ]; then terom@52: debug " update: $dep" terom@52: update=y terom@52: else terom@52: debug " check: $dep" terom@52: fi terom@52: done terom@52: terom@52: [ ! $update ] && debug " up-to-date" terom@52: terom@52: # return terom@52: [ $update ] terom@52: } terom@52: terom@52: ## Generate updated output file from given command's stdout: terom@52: # terom@52: # do_update $out $BIN/cmd --args terom@52: # terom@52: # Writes output to a temporary .new file, optionally shows a diff of changes, and commits terom@52: # the new version to $out (unless noop'd). terom@52: function do_update { terom@52: local out=$1; shift terom@52: local tmp=$out.new terom@52: terom@52: debug "$out" terom@52: cmd "$@" > $ROOT/$tmp terom@52: terom@52: # compare terom@52: if [ -e $ROOT/$out ] && [ $UPDATE_DIFF ]; then terom@52: debug " changes:" terom@52: terom@52: # terse terom@52: indent " " diff --unified=1 $ROOT/$out $ROOT/$tmp || true terom@52: fi terom@52: terom@52: # deploy terom@52: if [ $UPDATE_NOOP ]; then terom@52: # cleanup terom@52: debug " no-op" terom@52: terom@52: cmd rm $ROOT/$tmp terom@52: else terom@52: # commit terom@52: debug " deploy" terom@52: terom@52: cmd mv $ROOT/$tmp $ROOT/$out terom@52: fi terom@52: } terom@52: terom@52: ## Look for a link target: terom@52: # terom@52: # find_link $lnk $tgt... terom@52: # terom@52: # Outputs the first given target to exist, skipping any that are the same as the given $lnk. terom@52: # If no $tgt matches, outputs the last one, or '-'. terom@52: function choose_link { terom@52: local lnk=$1; shift terom@52: local tgt=- terom@52: terom@52: for tgt in "$@"; do terom@52: [ $tgt != $out ] && [ -e $ROOT/$tgt ] && break terom@52: done terom@52: terom@52: echo $tgt terom@52: } terom@52: terom@52: terom@52: ## Compare symlink to target: terom@52: # terom@52: # check_link $lnk $tgt && do_link $lnk $tgt || ... terom@52: # terom@52: # Tests if the symlink exists, and the target matches. terom@52: # Fails if the target does not exist. terom@52: function check_link { terom@52: local lnk=$1 terom@52: local tgt=$2 terom@52: terom@52: [ ! -e $ROOT/$tgt ] && fail "$tgt: target does not exist" terom@52: terom@52: [ ! -e $ROOT/$lnk ] || [ $(readlink $ROOT/$lnk) != $ROOT/$tgt ] terom@52: } terom@52: terom@52: ## Update symlink to point to target: terom@52: # terom@52: # do_link $lnk $tgt terom@52: # terom@52: function do_link { terom@52: local lnk=$1 terom@52: local tgt=$2 terom@52: terom@52: cmd ln -sf $ROOT/$tgt $ROOT/$lnk terom@52: } terom@52: terom@52: ## Update .serial number: terom@52: # terom@52: # do_update_serial $serial terom@52: # terom@52: # Shows old/new serial on debug. terom@52: function do_update_serial { terom@52: local serial=$1 terom@52: terom@52: # read terom@52: local old=$(test -e $ROOT/$serial && cat $ROOT/$serial || echo '') terom@52: terom@52: terom@52: cmd $BIN/update-serial $ROOT/$serial terom@52: terom@52: # read terom@52: local new=$(cat $ROOT/$serial) terom@52: terom@52: debug " $old -> $new" terom@52: } terom@52: terom@52: ## Perform `hg commit` for $DATA terom@52: function do_commit { terom@52: local msg=$1 terom@52: terom@55: [ $LOG_DIFF ] && indent " " hg_diff terom@52: terom@52: hg_commit "$msg" terom@52: } terom@52: terom@52: