~sourcemage/sorcery

26cd7f0d6dad4c4f58191fa4b553577c292f3930 — Jaka Kranjc 14 years ago 18956fc devel-ir
WIP: more improved resurrect stuff
M usr/sbin/cast => usr/sbin/cast +2 -0
@@ 574,6 574,8 @@ function pass_four()  {
      message "Can't find spell version for some reason, is $SPELL a spell?"
    else
      can_resurrect $SPELL $VERSION &> /dev/null &&
      #TODO: in the end, check if this call is redundant
      # maybe also ask the user if they want to resurrect an older version
      ! does_spell_need_update $SPELL &> /dev/null &&
      do_resurrect=yes
    fi

M usr/sbin/resurrect => usr/sbin/resurrect +7 -2
@@ 55,7 55,7 @@ function do_resurrect() {
    # use the version for only one spell in case more were specified (illegal)
    unset USE_VERSION

    find_cache "$INSTALL_CACHE/$spell-$requested_version-$HOST" cache
    find_cache "$INSTALL_CACHE/$spell-$requested_version-$HOST" cache single $SPELL
    if [[ ! -f $cache ]]; then
      error_message "$error_base no cache for version $requested_version" \
        "was found.$DEFAULT_COLOR"


@@ 204,9 204,14 @@ function is_resurrectable() {
  local spell=$1
  local msg_base="$SPELL_COLOR$spell$DEFAULT_COLOR cannot be resurrected because"

  if ! can_resurrect $spell "*" > /dev/null; then
  if ! can_resurrect $spell "*" simple > /dev/null; then
    message "$msg_base no cache was found!"
    return 1
  else
    if ! can_resurrect $spell "*"; then
      message "$msg_base the available caches are too old!"
      return 1
    fi
  fi
  if spell_held $spell; then
    message "$msg_base it is held!"

M var/lib/sorcery/modules/libresurrect => var/lib/sorcery/modules/libresurrect +63 -6
@@ 14,15 14,72 @@
## @param spellname
## determines if a particular version of a spell can be resurrected
#---------------------------------------------------------------------
function can_resurrect()  {
function can_resurrect() { (
  debug "libresurrect" "can_resurrect - $*"
  local SPELL=$1
  local VERSION=$2
  local mode=${3:-strict}
  local caches cache
  local rc=1

  find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" caches all $SPELL || return 1
  [[ $mode == simple ]] && return 0

  codex_set_current_spell_quick $(codex_find_spell_by_name $SPELL)

  # if there is more than one, check all, but one good cache is enough
  for cache in $caches; do
    # check if the patchlevels match
    local label=$(tar --test-label --file "$cache" 2>/dev/null)
    if [[ -z $label ]]; then
      # no label - do file-based lookup from the cache
      local tablet_path=var/state/sorcery/tablet
      # get the spellname/date part of the path
      local tmp=$(tar tOfOO "$cache" 2>&1 $tablet_path | sed -n "1 s,$tablet_path/,,p; q")

      local version patchlevel security_patch updated
      version=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/version)
      patchlevel=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/patchlevel)
      security_patch=$(tar fOx "$cache" 2>&1 $tablet_path/$tmp/security_patch)
      updated=$(tar fOOx "$cache" 2>&1 $tablet_path/$tmp/updated)

      if [[ $VERSION == "*" ]] || [[ ${version:-0} == $VERSION ]] &&
#FIXME
#some callers may not care if the patchlevels don't match
#so think about adding more modes
#/FIXME
         [[ $patchlevel == ${PATCHLEVEL:-0} ]] &&
         [[ $security_patch == ${SECURITY_PATCH:-0} ]] &&
         [[ ${updated:-0} == ${UPDATED:-0} ]]; then
        rc=0
        break
      else
        rc=1
        continue
      fi
    else
      local factors="$SPELL ${VERSION:-0} ${PATCHLEVEL:-0} ${SECURITY_PATCH:-0} ${UPDATED:-0}"
      if [[ $label == $factors ]]; then
        rc=0
        break
      else
        rc=1
        continue
      fi
    fi

  find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" || return 1
  debug "libresurrect" "I am able to resurrect."
  return 0
}
    #TODO check if subdependencies are satisfied
    #TODO HERE?: don't resurrect if a cast_self trigger is known

  done

  if [[ $rc == 0 ]]; then
    debug "libresurrect" "I am able to resurrect."
  fi
  #codex_clear_current_spell #instead we're in a subshell to prevent any kind of leakage

  return $rc
) }

#------------------------------------------------------------------------
## @param spell


@@ 83,7 140,7 @@ function resurrect_spell()  { (

  # 1) if no cache file exists fail
  if [[ -z $CACHE_COMP ]]; then
    CACHE_COMP=$(can_resurrect $SPELL $VERSION) || {
    find_cache "$INSTALL_CACHE/$SPELL-$VERSION-$HOST" CACHE_COMP single $SPELL || {
      message "No cache file could be found"
      return 1
    }

M var/lib/sorcery/modules/libtrack => var/lib/sorcery/modules/libtrack +52 -10
@@ 357,23 357,65 @@ function construct_cache_name() {
function find_cache() {
  debug "libtrack" "$FUNCNAME $@"
  local filename=$1
  local upvar=$2
  local mode=${3:-single}
  local spell=$4
  local real_name

  if [[ -f  $filename ]]; then
    real_name=$filename
  # always find all the caches then check if they are really of the right spell;
  # this avoids problems like wine matching in wine-gecko, since the cache
  # filenames use the dash as a field separator and are thus unreliable
  local basename _caches
  smgl_basename "$filename" basename
  _caches=$(find $INSTALL_CACHE -type f -name "$basename*" | sort -V)
  if [[ -n $spell ]]; then # no point in checking if we have nothing to compare against
    local _cache good_caches
    for _cache in $_caches; do
      local label=( $(tar --test-label --file $_cache 2>/dev/null) )
      if [[ ${label[0]} != $spell ]]; then
        continue
      else
        good_caches="$_cache $good_caches"
      fi
    done

    if [[ -z $good_caches ]]; then
      debug "libtrack" "$FUNCNAME found no good cache labels for: $filename"
      return 1
    fi

    # any cache of the good_caches will do
    if [[ $mode == all ]]; then
      real_name="$good_caches"
    else
      # use the first if more were found
      # usually the most recent version one, due to the sort call on _caches
      read real_name < <(cut -d" " -f1 <<< "$good_caches")
    fi
  else
    # use the first if more were found
    local basename
    smgl_basename "$filename" basename
    read real_name < <(find $INSTALL_CACHE -type f -name "$basename*")
    # old dumb mode
    # only alter calls this function without the spell argument
    debug "libtrack" "$FUNCNAME with no spell argument: $filename"

    if [[ -f $filename ]]; then
      real_name=$filename
    else
      if [[ $mode == all ]]; then
        real_name=$_caches
      else
        # use the first if more were found
        real_name=$(tail -n1 <<< "$_caches")
      fi
    fi
    [[ -z $real_name ]] && return 1
  fi
  [[ -z $real_name ]] && return 1

  debug "libtrack" "$FUNCNAME found $real_name"

  if [[ -z $2 ]]; then
    echo $real_name
  if [[ -z $upvar ]]; then
    echo "$real_name"
  else
    upvar $2 "$real_name"
    upvar $upvar "$real_name"
  fi
  return 0
}