tg: fix recursing with missing dependencies
authorAndrey Borzenkov <arvidjaar@gmail.com>
Sat, 19 Mar 2011 16:53:10 +0000 (19 19:53 +0300)
committerAndrey Borzenkov <arvidjaar@gmail.com>
Sat, 19 Mar 2011 16:53:10 +0000 (19 19:53 +0300)
In the following dependency chain:

t/1 => t/2 => t/3

with missing initial t/1 no error is was returned when attempting
to update t/3, because t/2 was assumed to be external origin that
does not need update.

Extend recurse_deps() API to inform driver about missing dependency
by setting $_dep_missing before calling.

Use it in branch_needs_update() to indicate missing deps by emitting
additional '!' and forcing tg-update.sh to recurse into parent and
fail due to missing dep. All other drivers were extended to check
for $_dep_missing and silently return (that is what happened anyway).

Signed-off-by: Andrey Borzenkov <arvidjaar@gmail.com>
tg-export.sh
tg-push.sh
tg.sh

index 4574882..11842b7 100644 (file)
@@ -261,6 +261,9 @@ fi
 
 driver()
 {
+       # FIXME should we abort on missing dependency?
+       [ -z "$_dep_missing" ] || return 0
+
        case $_dep in refs/remotes/*) return;; esac
        branch_needs_update >/dev/null
        [ "$_ret" -eq 0 ] ||
@@ -273,7 +276,7 @@ driver()
 # in topological order.
 if [ -z "$branches" ]; then
        recurse_deps driver "$name"
-       (_ret=0; _dep="$name"; _name=""; _dep_is_tgish=1; driver)
+       (_ret=0; _dep="$name"; _name=; _dep_is_tgish=1; _dep_missing=; driver)
 else
        echo "$branches" | tr ',' '\n' | while read _dep; do
                _dep_is_tgish=1
index a928fba..f4652f5 100644 (file)
@@ -49,6 +49,9 @@ _listfile="$(get_temp tg-push-listfile)"
 
 push_branch()
 {
+       # FIXME should we abort on missing dependency?
+       [ -z "$_dep_missing" ] || return 0
+
        # if so desired omit non tgish deps
        $tgish_deps_only && [ -z "$_dep_is_tgish" ] && return 0
 
@@ -66,6 +69,7 @@ for name in $branches; do
        # re-use push_branch, which expects some pre-defined variables
        _dep="$name"
        _dep_is_tgish=1
+       _dep_missing=
        ref_exists "top-bases/$_dep" ||
                _dep_is_tgish=
        push_branch "$name"
diff --git a/tg.sh b/tg.sh
index e8447cb..268cdd4 100644 (file)
--- a/tg.sh
+++ b/tg.sh
@@ -192,11 +192,13 @@ is_sha1()
 # CMD can refer to $_name for queried branch name,
 # $_dep for dependency name,
 # $_depchain for space-seperated branch backtrace,
+# $_dep_missing boolean to check whether $_dep is present
 # and the $_dep_is_tgish boolean.
 # It can modify $_ret to affect the return value
 # of the whole function.
 # If recurse_deps() hits missing dependencies, it will append
-# them to space-separated $missing_deps list and skip them.
+# them to space-separated $missing_deps list and skip them
+# affter calling CMD with _dep_missing set.
 # remote dependencies are processed if no_remotes is unset.
 recurse_deps()
 {
@@ -219,9 +221,12 @@ recurse_deps()
 
        _ret=0
        while read _dep; do
+               _dep_missing=
                if ! ref_exists "$_dep" ; then
-                       # All hope is lost
+                       # All hope is lost. Inform driver and continue
                        missing_deps="$missing_deps $_dep"
+                       _dep_missing=1
+                       eval "$_cmd"
                        continue
                fi
 
@@ -249,6 +254,11 @@ recurse_deps()
 # description for details) and set $_ret to non-zero.
 branch_needs_update()
 {
+       if [ -n "$_dep_missing" ]; then
+               echo "! $_depchain"
+               return 0
+       fi
+
        _dep_base_update=
        if [ -n "$_dep_is_tgish" ]; then
                if has_remote "$_dep"; then
@@ -274,8 +284,9 @@ branch_needs_update()
 # This function is recursive; it outputs reverse path from NAME
 # to the branch (e.g. B_DIRTY B1 B2 NAME), one path per line,
 # inner paths first. Innermost name can be ':' if the head is
-# not in sync with the base or '%' if the head is not in sync
-# with the remote (in this order of priority).
+# not in sync with the base, '%' if the head is not in sync
+# with the remote (in this order of priority) or '!' if depednecy
+# is missing.
 # It will also return non-zero status if NAME needs update.
 # If needs_update() hits missing dependencies, it will append
 # them to space-separated $missing_deps list and skip them.