commit 660013947e06201a5e0eb12d05196f51c8cea2a5
Author: Jan Pokorný <jpokorny(a)redhat.com>
Date: Thu Mar 8 11:08:14 2012 +0100
third-party/init: rework for easier maintenance
Signed-off-by: Jan Pokorný <jpokorny(a)redhat.com>
README.maint | 3 +-
TODO.txt | 6 -
third-party/init-jquery | 21 +++-
third-party/init-jquery-ui | 53 ++++++---
third-party/init-pyscss | 35 ++++--
third-party/init-requirejs | 8 +-
third-party/init.sh | 279 +++++++++++++++++++++++++++++++++-----------
7 files changed, 296 insertions(+), 109 deletions(-)
---
diff --git a/README.maint b/README.maint
index 324098e..7045881 100644
--- a/README.maint
+++ b/README.maint
@@ -156,7 +156,8 @@ in case of jumping tag-to-tag::
cd ..
git add git-jquery-ui
# magic to update cached outputs (if any) here, in this case:
- ./init.sh jqueryui # create distribution files
+ ./init.sh clean jqueryui # remove old distribution files
+ ./init.sh jqueryui # + create new (implicit "get" action)
git add third-party/jquery-ui # add respective "cache" changes
git commit -m 'bump jQuery UI: 1.8.18'
diff --git a/TODO.txt b/TODO.txt
index 41e7d34..a3ea58a 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -1,7 +1 @@
(remaining steps of unfinished *small* tasks here)
-
-- third-party/init.sh: distinguish "eager get" and "get"
- when the latter means "be ok with out-git-cached files"
- (and better overall approach should be considered, e.g.,
- way to automatically update to the newest tag, which
- might be even task for crontab ;)
diff --git a/third-party/init-jquery b/third-party/init-jquery
index c754a4a..2c9c1f5 100644
--- a/third-party/init-jquery
+++ b/third-party/init-jquery
@@ -1,9 +1,18 @@
+# vim:ft=sh:noet
# jquery.js
jquery () {
- DIR="git-jquery"
- DIST_DIR="jquery"
- do_git_submodule $1 $DIR || return $?
- do_post_get $1 \
- make -C $DIR DIST_DIR=../$DIST_DIR jquery
+ _sourcedir="git-jquery"
+ _targetdir="target-jquery"
+
+ # target init
+ target_init () {
+ target_get () {
+ init_verbosely make -C $_sourcedir DIST_DIR=../$_targetdir jquery
+ }
+ init_target $1 $_targetdir target_get
+ }
+
+ # proceed
+ init_git_submodule $1 $_sourcedir target_init
}
-register jquery
+init_register jquery
diff --git a/third-party/init-jquery-ui b/third-party/init-jquery-ui
index 22e98df..6f67904 100644
--- a/third-party/init-jquery-ui
+++ b/third-party/init-jquery-ui
@@ -1,26 +1,43 @@
+# vim:ft=sh:noet
# jQuery UI
jqueryui () {
- DIR="git-jquery-ui"
- DIST_DIR="jquery-ui"
- MOCK_DIRS="$DIST_DIR/ui/minified $DIST_DIR/themes/base/minified
$DIST_DIR/ui-headered"
- do_git_submodule $1 $DIR || return $?
+ _sourcedir="git-jquery-ui"
+ _targetdir="target-jquery-ui"
+ _mockdirs="\
+ $_targetdir/ui/minified \
+ $_targetdir/themes/base/minified \
+ $_targetdir/ui-headered "
- # some ant extras may be also required:
- # ant-nodeps
- require "ant" || return 1
+ # target init
+ target_init () {
+ target_get () {
+ # some ant extras may be also required:
+ # * ant-nodeps
+ init_require "ant" || return 1
- # decorate build to make it happy
- mkdir -p $MOCK_DIRS
+ # decorate build to make it happy
+ init_verbosely mkdir -p $_mockdirs
- do_post_get $1 \
- ant -k -q -f $DIR/build/build.xml -Ddist.dir=../../$DIST_DIR concatenate
replace-version prepend-header
- # images not copied automatically to DIST_DIR
+ init_verbosely \
+ ant -k -q -f $_sourcedir/build/build.xml \
+ -Ddist.dir=../../$_targetdir concatenate \
+ replace-version prepend-header
+ ret=$?
- # undecorate
- rm -rf $MOCK_DIRS
- pushd git-jquery-ui >/dev/null
+ # undecorate
+ rm -rf -- $_mockdirs
- cp --parents -R $(find -name "ui-*.png") ../$DIST_DIR
- popd >/dev/null
+ [ $ret -ne 0 ] && return $ret
+
+ # images not copied automatically to _targetdir, we do
+ pushd $_sourcedir >/dev/null
+ cp --parents -R $(find -name "ui-*.png") ../$_targetdir
+ popd >/dev/null
+ }
+ init_target $1 $_targetdir target_get
+ }
+
+ # proceed
+ init_git_submodule $1 $_sourcedir target_init
}
-register jqueryui
+init_register jqueryui
diff --git a/third-party/init-pyscss b/third-party/init-pyscss
index e3de17f..544e2d7 100644
--- a/third-party/init-pyscss
+++ b/third-party/init-pyscss
@@ -1,14 +1,29 @@
+# vim:ft=sh:noet
# pyScss: SCSS to CSS compiler
pyscss () {
- DIR="git-pyscss"
- do_git_submodule $1 $DIR || return $?
+ _sourcedir="git-pyscss"
- if require "gcc"; then
- pushd $DIR >/dev/null
- python setup.py build_ext -i
- popd >/dev/null
- else
- announce "no worries, only C speed ups will not be in place"
- fi
+ # hooks
+ source_postget () {
+ if init_require "gcc"; then
+ pushd $_sourcedir >/dev/null
+ python setup.py build_ext -i
+ popd >/dev/null
+ else
+ init_announce "no worries, only C speed-ups will not be in place"
+ fi
+ }
+ source_postclean () {
+ for f in $(find "$_sourcedir" -name '*.o' -o -name '*.so');
do
+ rm -i "$f"
+ done
+ }
+
+ # proceed
+ init_git_submodule $1 $_sourcedir || return $?
+
+ # post-hooking
+ init_post_get $1 source_postget
+ init_post_clean $1 source_postclean
}
-register pyscss
+init_register pyscss
diff --git a/third-party/init-requirejs b/third-party/init-requirejs
index 1b1eb61..6293615 100644
--- a/third-party/init-requirejs
+++ b/third-party/init-requirejs
@@ -1,5 +1,9 @@
+# vim:ft=sh:noet
# require.js: JS modules loader
requirejs () {
- do_git_submodule $1 "git-requirejs" || return $?
+ _sourcedir="git-requirejs"
+
+ # proceed
+ init_git_submodule $1 $_sourcedir
}
-register requirejs
+init_register requirejs
diff --git a/third-party/init.sh b/third-party/init.sh
index 8f70202..eabddf2 100755
--- a/third-party/init.sh
+++ b/third-party/init.sh
@@ -4,19 +4,25 @@
# 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: remove RET_DEL etc., deletion should be isolated now?
+# 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 ]
@@ -32,15 +38,21 @@ check_ret () {
}
do_del () {
- #echo "delete $1?"
- [ -d "$1" ] && rm -rfI -- "$1" || do_announce "$1 not
present" $CLR_WRN
+ 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
return $RET_DEL
}
do_announce () {
# usage: see announce ($1, $3) + [$2 = colour (defaults to 32/green)]
# 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
@@ -54,21 +66,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 () {
+init_announce () {
# usage: $1=message to output [, $2 = start with extra newline if "delimit")]
do_announce "$1" $CLR_OK $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
@@ -82,102 +133,198 @@ require () {
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
+ ;;
+ "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
+ #local -f get_refresh_hook
+ 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 ] && [ $ret -ne $RET_DEL ] && 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}"
+
+ local -f get_refresh_hook
+ 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}"
+ local -f get_refresh_hook
+ 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 -a \$ret -ne $RET_DEL ] && 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
}