From e6c75e9e6ad332b4f4c781f7d50eefa121630143 Mon Sep 17 00:00:00 2001 From: Jan Pokorný Date: Thu, 8 Mar 2012 14:18:22 +0100 Subject: init: update/sync MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan Pokorný --- init-common | 14 +-- init-optional | 6 +- init-python | 6 +- init-tg2 | 10 +- init-web | 4 +- init.sh | 296 ++++++++++++++++++++++++++++++++++++++++++---------------- 6 files changed, 236 insertions(+), 100 deletions(-) diff --git a/init-common b/init-common index 2786636..c84e2b0 100644 --- a/init-common +++ b/init-common @@ -1,14 +1,14 @@ # common vim plugins for shared projects common () { - announce "--- common ---" + init_announce "--- common ---" delimit # local_vimrc: # directory-local settings applied to contained files (+requisite) - LOCAL_VIMRC_DIR="local-vimrc" - LOCAL_VIMRC_URL="http://lh-vim.googlecode.com/svn/misc/trunk/plugin/local_vimrc.vim" - LH_COMMON_URL="http://lh-vim.googlecode.com/svn/vim-lib/trunk/autoload/lh/common.vim" + _local_vimrc_dir="url-local-vimrc" + _local_vimrc_url="http://lh-vim.googlecode.com/svn/misc/trunk/plugin/local_vimrc.vim" + _lh_common_url="http://lh-vim.googlecode.com/svn/vim-lib/trunk/autoload/lh/common.vim" # "plugin" directory has to be added (downloading recursively # the whole original "plugin" path for one file is impractical) - do_wget $1 "$LOCAL_VIMRC_DIR/plugin" "$LOCAL_VIMRC_URL" - do_wget $1 "$LOCAL_VIMRC_DIR/autoload/lh" "$LH_COMMON_URL" || return $? + init_url_wget $1 "${_local_vimrc_dir}/plugin" "${_local_vimrc_url}" || return $? + init_url_wget $1 "${_local_vimrc_dir}/autoload/lh" "${_lh_common_url}" } -register common +init_register common diff --git a/init-optional b/init-optional index 42ec78a..3e0e33e 100644 --- a/init-optional +++ b/init-optional @@ -1,10 +1,10 @@ # optional (but recommended) vim plugins optional () { - announce "--- optional ---" + init_announce "--- optional ---" delimit # makegreen: # test results integration # Tagbar (possible alternative TagList): # "code navigator" incl. JS support if jsctags installed - do_git_submodule $1 "git-makegreen" "git-tagbar" || return $? + init_git_submodule $1 "git-makegreen" "git-tagbar" } -register optional +init_register optional diff --git a/init-python b/init-python index a9e245e..75fc9ad 100644 --- a/init-python +++ b/init-python @@ -1,9 +1,9 @@ # vim plugins for Python projects python () { - announce "--- python ---" + init_announce "--- python ---" delimit # Python-mode: # integrates pylint, rope, pydoc, pyflakes # + extra highlighting, whitespace removal ... - do_git_submodule $1 "git-python-mode" || return $? + init_git_submodule $1 "git-python-mode" } -register python +init_register python diff --git a/init-tg2 b/init-tg2 index 16f3605..dda73a9 100644 --- a/init-tg2 +++ b/init-tg2 @@ -1,11 +1,11 @@ # vim plugins for TG2 projects tg2 () { - announce "--- tg2 ---" + init_announce "--- tg2 ---" delimit # genshi-contrib: # from genshi svn, contrib/vim - GENSHI_CONTRIB_DIR="genshi-contrib" - GENSHI_CONTRIB_SVN="http://svn.edgewall.org/repos/genshi/contrib/vim/" + _genshi_contrib_dir="svn-genshi-contrib" + _genshi_contrib_svn="http://svn.edgewall.org/repos/genshi/contrib/vim/" # no need for specific revision - do_svn $1 "$GENSHI_CONTRIB_DIR" "$GENSHI_CONTRIB_SVN" || return $? + init_svn $1 "$_genshi_contrib_dir" "$_genshi_contrib_svn" } -register tg2 +init_register tg2 diff --git a/init-web b/init-web index 7eb7e6c..ed7f573 100644 --- a/init-web +++ b/init-web @@ -1,6 +1,6 @@ # vim plugins for web projects web () { - announce "--- web ---" + init_announce "--- web ---" delimit # empty for now } -#register web +#init_register web diff --git a/init.sh b/init.sh index 8f70202..3780389 100755 --- a/init.sh +++ b/init.sh @@ -4,19 +4,22 @@ # NOTE: not ready for arbitrary CWD, from . only # NOTE: this is always to be run from within git repo so things like # "git rev-parse" will work (see do_git_submodule) +# NOTE: really stupid, no timestamping logic and similar fancy stuff +# TODO: new action "ahead" to check new versions (tags in git, etc.) # # internals # -CLR_USR=34 -CLR_SCR=32 +CLR_USR=32 +CLR_SCR=36 CLR_BAD=31 CLR_WRN=33 +CLR_INF=35 +CLR_CMD=34 -RET_DEL=64 - -CHOICES="" +PRINTED=false +GIT_PREFIX=$(git rev-parse --show-prefix) check_nargs () { [ $1 -ge $2 ] @@ -26,27 +29,28 @@ check_nargs () { } check_ret () { - [ $1 -ne 0 -a $1 -ne $RET_DEL ] \ + [ $1 -ne 0 ] \ && do_announce "action failed with exit status $1" $CLR_BAD return $1 } do_del () { - #echo "delete $1?" - [ -d "$1" ] && rm -rfI -- "$1" || do_announce "$1 not present" $CLR_WRN - return $RET_DEL + do_announce "about to delete $*" $CLR_WRN + do_announce "has to be confirmed (y)..." $CLR_INF + rm -rfI -- "$@" 2>/dev/null + [ $? -eq 0 ] || do_announce "something to be deleted not present" $CLR_WRN } do_announce () { - # usage: see announce ($1, $3) + [$2 = colour (defaults to 32/green)] + # usage: see announce ($1, $3) + $2=colour # use colours if available - [ "$3" = "delimit" ] && echo + if [ "$3" = "delimit" ] && $PRINTED; then + echo + else + PRINTED=true + fi if test -t 1; then - colour=$2 - if [ -z "$colour" ]; then - colour=$CLR_USR - fi - echo -en "\\033[${colour}m" + echo -en "\\033[${2}m" echo -n "$1" echo -e "\\033[0m" else @@ -54,21 +58,60 @@ do_announce () { fi } +do_action () { + # usage: $1=action, $2=directory, $3=type-specific hook for get/refresh + # sources [ , $4=custom function for hooking-in ] + + # if two-phased and function for hooking-in is present + hook=false + if [ $# -ge 4 ] && type -t function_name $4 | grep -q "^function$"; then + hook=true + fi + + case "$1" in + "get"|"refresh") + # shortcut if target dir already exists or target + # files were subsequently generated OK + [ "$1" = "get" ] && $hook && $4 "probe" && continue + $3 "$2" + ;; + "clean") + ret=0 + ;; + "purge") + do_del "$submodule" + ret=$? + ;; + *) + do_announce "Unexpected action $1" $CLR_BAD + exit 1 + ;; + esac + # repeat if two-phased and function for hooking-in is present + $hook && $4 "$1" + return $ret +} + # -# "API" for sourced choices +# kind of API for sourced choices (functions starting with "init_") # -register () { +init_register () { # usage: $1=choice to register CHOICES="$CHOICES|$1" } -announce () { - # usage: $1=message to output [, $2 = start with extra newline if "delimit")] - do_announce "$1" $CLR_OK $2 +init_announce () { + # usage: $1=message to output [, $2=start with extra newline if "delimit")] + do_announce "$1" $CLR_USR $2 } -require () { +init_verbosely () { + do_announce "$*" $CLR_CMD + $@ +} + +init_require () { # usage: $1=what is required [, $2=test (function/command)] tester=$2 if [ -z "$tester" ]; then @@ -77,107 +120,200 @@ require () { $tester $1 >/dev/null ret=$? [ $ret -eq 0 ] \ - && do_announce "require $1: checked ok" $CLR_OK \ + && do_announce "require $1: checked ok" $CLR_INF \ || do_announce "require $1: not met" $CLR_BAD return $ret } -do_git_submodule () { - # usage: $1=action ($1 passed from main), $2..$N=submodule(s) - ret=0 - git_prefix=$(git rev-parse --show-prefix) - for submodule in "${@:2}"; do - do_announce "$1 $submodule (git submodule)" $CLR_SCR delimit - if [ "$1" == "get" ]; then - pushd "$(git rev-parse --show-toplevel)" >/dev/null - # TODO: --recursive seems to be buggy? - git submodule update --init "${git_prefix}${submodule}" 2>&1 +init_target () { + # usage: $1=action ($1 passed from main or "probe"), $2..target dir + # [, $3=getter ] + existing=$(find "$2" -mindepth 1 -name dir_info.txt -o -type l -prune \ + -o -print 2>/dev/null) + case "$1" in + "probe"|"get"|"refresh") + [ "$(echo "$existing" | wc -w)" -gt 0 ] && return + mkdir -p "$2" 2>/dev/null + if [ $# -gt 2 ]; then + do_announce "about to $1 target files..." $CLR_INF + $3 ret=$? - popd >/dev/null - if [ $ret -eq 0 ]; then - pushd $submodule >/dev/null - git submodule update --init 2>&1 - popd >/dev/null + if [ $ret -ne 0 ]; then + # recursion (should be safe) + init_target purge "$2" + return $ret fi - else - do_del "$submodule" - ret=$? fi - [ $ret -ne 0 ] && [ $ret -ne $RET_DEL ] && break + ;; + "clean"|"purge") + [ "$(echo "$existing" | wc -w)" -eq 0 ] || do_del $existing + ;; + *) + do_announce "Unexpected action $1" $CLR_BAD + exit 1 + ;; + esac +} + +init_git_submodule () { + # usage: $1=action ($1 passed from main), $2..$N=submodule(s) + # + optionally, if last arg is a function, it is used + # for hooking-in + get_refresh_hook () { + pushd "$(git rev-parse --show-toplevel)" >/dev/null + # TODO: --recursive seems to be buggy? + do_announce "about to update git submodule ${1}..." $CLR_INF + init_verbosely git submodule update --init "${GIT_PREFIX}${1}" 2>&1 + ret=$? + popd >/dev/null + if [ $ret -eq 0 ]; then + pushd "$1" >/dev/null + git submodule update --init 2>&1 + popd >/dev/null + fi + return $ret + } + + arg_len=$# + arg_last=${@:$arg_len} + if type -t function_name $arg_last | grep -q "^function$"; then + let arg_len-=2 + else + let arg_len-=1 + fi + + ret=0 + for submodule in "${@:2:$arg_len}"; do + do_announce "$1 $submodule (git submodule)" $CLR_SCR delimit + do_action $1 "$submodule" get_refresh_hook $arg_last + ret=$? + [ $ret -ne 0 ] && break done check_ret $ret } -do_wget () { +# TODO: no support for custom function for hooking-in as with git_submodule +init_url_wget () { # usage: $1=action ($1 passed from main), $2=DIR, $3..$N=arguments (to wget) check_nargs $# 3 || return $? + toplevel="$2" if [ "$(dirname $2)" != "." ]; then toplevel="$(dirname $2)" fi - do_announce "$1 $toplevel (wget)" $CLR_SCR delimit - if [ "$1" == "get" ]; then + other_params="${@:3}" + + get_refresh_hook () { wget --no-verbose --no-clobber --execute robots=off \ - --directory-prefix "$2" "${@:3}" 2>&1 - else - do_del "$toplevel" - fi + --directory-prefix "$toplevel" "$other_params" 2>&1 + + } + do_announce "$1 $toplevel (wget)" $CLR_SCR delimit + do_action $1 "$toplevel" get_refresh_hook check_ret $? } -do_svn () { +# TODO: no support for custom function for hooking-in as with git_submodule +init_svn () { # usage: $1=action ($1 passed from main), $2=DIR, $3=SVN [, $4=REV] check_nargs $# 3 || return $? + toplevel="$2" if [ "$(dirname $2)" != "." ]; then toplevel="$(dirname $2)" fi - do_announce "$1 $toplevel (svn)" $CLR_SCR delimit - if [ "$1" == "get" ]; then - rev="" - if [ $# -ge 4 ]; then - rev="--revision $4" - fi - svn checkout --force $rev "$3" "$2" | grep "revision" - else - do_del "$toplevel" + svn="$3" + rev="" + if [ $# -ge 4 ]; then + rev="--revision $4" fi - check_ret $? -} -do_post_get () { - # usage: $1=action ($1 passed from main), $2..$N command + args - [ "$1" != "get" ] || "${@:2}" + get_refresh_hook () { + svn checkout --force $rev "$svn" "$toplevel" | grep "revision" + } + + do_announce "$1 $toplevel (svn)" $CLR_SCR delimit + do_action $1 "$toplevel" get_refresh_hook check_ret $? } +# +# hook-enablers +# usage: $1=action ($1 passed from main), $2..$N command + args +# + +init_post_get () { [ "$1" != "get" ] || "${@:2}"; check_ret $?; } +init_post_refresh () { [ "$1" != "refresh" ] || "${@:2}"; check_ret $?; } +init_post_clean () { [ "$1" != "clean" ] || "${@:2}"; check_ret $?; } +init_post_purge () { [ "$1" != "purge" ] || "${@:2}"; check_ret $?; } + # # source the choices (./init-* files) and go # +CHOICES="" for choice in $(ls init-*); do [ -f $choice ] && source ./$choice; done CHOICES=$(echo $CHOICES | sed 's/^|//') +ACTIONS="get|refresh|clean|purge" +help_actions () { + cat <<"EOF" +quick explanation of actions: + - basically, get-refresh and clean-purge are very similar (or even + aliasing in some cases) depending on whether the way to get the target + files is single-phase (what you fetch is what you use) or two-phased + (what you fetch is what you use to generate target files you then use) + + * get/refresh: get the target files + - single-phased (get=refresh): refetch sources (optionally: if needed) + - two-phased: + - get: if not present, generate the target files from sources, but + if sources are missing as well, fetch them first (=refresh) + - refresh: remove existing target files, refetch sources (optionally: + if needed) and generate fresh target files out of them + + * clean/purge: remove the files + - single-phased: + - clean: NOOP (unless something performed via hook) + - purge: remove the source/target files directory + - two-phased: + - clean: remove the target files directory + - purge: remove both the target files and source files directories + + NOTE: you can create composite actions on the commandline, e.g.: + ./init.sh purge all && ./init.sh all # completely from scratch +EOF +} + main () { - action="get" - if [ "$1" == "get" -o "$1" == "del" ]; then - action="$1" + action="get" # mostly, existing target files will be just reused + eval "case \"$1\" in + $ACTIONS) + action=\"$1\" [ $# -gt 1 ] && shift # || fall-through via unrecognized choice - fi + ;; + esac" while [ -n "$1" ]; do eval "case \"$1\" in - $CHOICES) - $1 $action - ret=\$? - [ \$ret -ne 0 -a \$ret -ne $RET_DEL ] && return \$ret - shift - continue;; - all) - main $action $(echo $CHOICES | sed 's/|/ /g') - break;; - help|*) - echo \"usage: ./init.sh [del] ($CHOICES|all)+\" - break;; + $CHOICES) + $1 $action + ret=\$? + [ \$ret -ne 0 ] && return \$ret + shift + continue;; + all) + main $action $(echo $CHOICES | sed 's/|/ /g') + break;; + help|*) + echo \"usage: ./init.sh [$ACTIONS] ($CHOICES|all)+\" + shift + if [ \"\$1\" != \"actions\" ]; then + echo \"see also 'help actions' for details about actions\" + else + echo + help_actions + fi + break;; esac" done } -- cgit