mulle-bootstrap-fetch.sh
e3e80f18
 #! /bin/sh
5de2fbd6
 #
 #   Copyright (c) 2015 Nat! - Mulle kybernetiK
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
 #   modification, are permitted provided that the following conditions are met:
 #
 #   Redistributions of source code must retain the above copyright notice, this
 #   list of conditions and the following disclaimer.
 #
 #   Redistributions in binary form must reproduce the above copyright notice,
 #   this list of conditions and the following disclaimer in the documentation
 #   and/or other materials provided with the distribution.
 #
 #   Neither the name of Mulle kybernetiK nor the names of its contributors
 #   may be used to endorse or promote products derived from this software
 #   without specific prior written permission.
 #
 #   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 #   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 #   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 #   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 #   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 #   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 #   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 #   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 #   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #   POSSIBILITY OF SUCH DAMAGE.
 
 #
 # this script installs the proper git clones into "clones"
 # it does not to git subprojects.
 # You can also specify a list of "brew" dependencies. That
 # will be third party libraries, you don't tag or debug
 #
 . mulle-bootstrap-warn-scripts.sh
c6e7156e
 . mulle-bootstrap-local-environment.sh
d388168a
 . mulle-bootstrap-brew.sh
5de2fbd6
 
 
40fe269d
 usage()
 {
    cat <<EOF
 usage: fetch <install|nonrecursive|update> [repos]*
    install      : clone or symlink non-exisiting repositories and other resources
    nonrecursive : like above, but ignore .bootstrap folders of repositories
    update       : pull repositories
 
    You can specify the names of the repositories to update or fetch.
    Currently available names are:
 EOF
    (cd "${CLONES_SUBDIR}" ; ls -1d ) 2> /dev/null
 }
 
 
3be635de
 check_and_usage_and_help()
 {
    case "$COMMAND" in
       install)
       ;;
       nonrecursive)
         COMMAND=install
         DONT_RECURSE="YES"
       ;;
       update)
       ;;
       *)
40fe269d
       usage >&2
3be635de
       exit 1
       ;;
    esac
 }
 
40fe269d
 
3be635de
 if [ "$1" = "-h" -o "$1" = "--help" ]
 then
40fe269d
    COMMAND=help
 else
    if [ -z "${COMMAND}" ]
    then
       COMMAND=${1:-"install"}
       shift
    fi
3be635de
 
40fe269d
    if [ "${MULLE_BOOTSTRAP}" = "mulle-bootstrap" ]
    then
       COMMAND="install"
    fi
5de2fbd6
 fi
 
3be635de
 check_and_usage_and_help
5de2fbd6
 
 
 link_command()
 {
    local src
    local dst
    local tag
    local name
 
    src="$1"
    dst="$2"
    tag="$3"
 
    if [ -e "${src}" ]
    then
       echo "${src} does not exist ($PWD)" >&2
       exit 1
    fi
 
    if [ "${COMMAND}" = "install" ]
    then
40fe269d
       exekutor ln -s -f "$src" "$dst" || fail "failed to setup symlink \"$dst\" (to \"$src\")"
5de2fbd6
       if [ "$tag" != "" ]
       then
          name="`basename "${dst}"`"
          echo "tag ${tag} will be ignored, due to symlink" >&2
          echo "if you want to checkout this tag do:" >&2
3be635de
          echo "(cd .repos/${name}; git ${GITFLAGS} checkout \"${tag}\" )" >&2
5de2fbd6
       fi
    fi
 
    # when we link, we assume that dependencies are there
 }
 
 
 ask_symlink_it()
 {
    local  clone
 
    clone="$1"
    if [ ! -d "${clone}" ]
    then
       echo "You need to check out ${clone} yourself, as it's not there." >&2 || exit 1
    fi
 
3c8ec4d2
    SYMLINK_FORBIDDEN="`read_config_setting "symlink_forbidden"`"
5de2fbd6
 
    # check if checked out
    if [ -d "${clone}"/.git ]
    then
       flag=1  # mens clone it
       if [ "${SYMLINK_FORBIDDEN}" != "YES" ]
       then
          user_say_yes "Should ${clone} be symlinked instead of cloned ?
    You usually say NO to this, even more so, if tag is set (tag=${tag})"
          flag=$?
       fi
       [ $flag -eq 0 ]
       return $?
    fi
 
     # if bare repo, we can only clone anyway
    if [ -f "${clone}"/HEAD -a -d "${clone}/refs" ]
    then
       echo "${clone} looks like a bare git repository. So cloning" >&2
       echo "is the only way to go." >&2
       return 1
    fi
 
    # can only symlink because not a .git repo yet
    if [ "${SYMLINK_FORBIDDEN}" != "YES" ]
    then
       echo "${clone} is not a git repository (yet ?)" >&2
       echo "So symlinking is the only way to go." >&2
       return 0
    fi
 
    echo "SYMLINK_FORBIDDEN=YES, can't symlink" >&2
    exit 1
 }
 
 
40fe269d
 run_fetch_settings_script()
 {
    local  name
 
    name="$1"
    shift
 
    [ -z "$name" ] && internal_fail "name is empty"
 
    local script
 
3c8ec4d2
    script="`read_fetch_setting "bin/${name}.sh"`"
40fe269d
    if [ ! -z "${script}" ]
    then
       run_script "${script}" "$@"
    fi
 }
 
 
5de2fbd6
 checkout()
 {
    local clone
    local name1
    local name2
    local tag
    local dstname
 
    clone="$1"
40fe269d
    name1="$2"
    name2="$3"
    dstname="$4"
5de2fbd6
    tag="$5"
40fe269d
 
    [ -z "$clone" ]    && internal_fail "clone is empty"
    [ -z "$name1" ]    && internal_fail "name1 is empty"
    [ -z "$name2" ]    && internal_fail "name2 is empty"
    [ -z "$dstname" ]  && internal_fail "dstname is empty"
5de2fbd6
 
    local srcname
    local operation
    local flag
    local found
 
3be635de
    #
    # this implicitly ensures, that these folders are
    # movable and cleanable by mulle-bootstrap
    # so ppl can't really use  src mistakenly
 
    if [ -e "${DEPENDENCY_SUBDIR}" -o -e "${CLONESBUILD_SUBDIR}" ]
    then
       log_error "Stale folders ${DEPENDENCY_SUBDIR} and/or ${CLONESBUILD_SUBDIR} found."
       log_error "Please remove them before continuing."
       log_info  "Suggested command: ${C_WHITE}mulle-bootstrap clean output"
       exit 1
    fi
 
5de2fbd6
    srcname="${clone}"
3c8ec4d2
    script="`read_repo_setting "${name1}" "bin/${COMMAND}.sh"`"
40fe269d
    operation="git_clone"
5de2fbd6
 
    # simplify this crap copy/paste code
40fe269d
    if [ ! -z "${script}" ]
5de2fbd6
    then
40fe269d
       run_script "${script}" "$@"
5de2fbd6
    else
       case "${clone}" in
          /*)
             ask_symlink_it "${clone}"
             if [ $? -eq 0 ]
             then
                operation=link_command
             fi
          ;;
 
          ../*|./*)
             ask_symlink_it "${clone}"
             if [ $? -eq 0 ]
             then
                operation=link_command
                srcname="${CLONES_RELATIVE}/${clone}"
             fi
          ;;
 
          *)
             found="../${name1}.${tag}"
             if [ ! -d "${found}" ]
             then
                found="../${name1}"
                if [ ! -d "${found}" ]
                then
                   found="../${name2}.${tag}"
                   if [ ! -d "${found}" ]
                   then
                      found="../${name2}"
                      if [ ! -d "${found}" ]
                      then
                         found=""
                      fi
                   fi
                fi
             fi
 
             if [ "${found}" != ""  ]
             then
                user_say_yes "There is a ${found} folder in the parent
 directory of this project.
d388168a
 Use it ?"
5de2fbd6
                if [ $? -eq 0 ]
                then
                   srcname="${found}"
                   ask_symlink_it "${srcname}"
                   if [ $? -eq 0 ]
                   then
                      operation=link_command
                      srcname="${CLONES_RELATIVE}/${found}"
                   fi
                fi
             fi
          ;;
       esac
 
40fe269d
       "${operation}" "${srcname}" "${dstname}" "${tag}"
5de2fbd6
        warn_scripts "${dstname}/.bootstrap" "${dstname}" || exit 1 # sic
    fi
 
40fe269d
    run_fetch_settings_script "post-install"
5de2fbd6
 }
 
 
40fe269d
 git_checkout_tag()
5de2fbd6
 {
40fe269d
    local dst
5de2fbd6
    local tag
 
40fe269d
    dst="$1"
    tag="$2"
5de2fbd6
 
40fe269d
    log_info "Checking out ${C_MAGENTA}${tag}${C_INFO} ..."
    ( exekutor cd "${dst}" ; exekutor git checkout ${GITFLAGS} "${tag}" )
5de2fbd6
 
40fe269d
    if [ $? -ne 0 ]
5de2fbd6
    then
40fe269d
       log_error "Checkout failed, moving ${C_CYAN}${dst}${C_ERROR} to {C_CYAN}${dst}.failed${C_ERROR}"
       log_error "You need to fix this manually and then move it back."
       log_info "Hint: check ${BOOTSTRAP_SUBDIR}/`basename "${dst}"`/TAG" >&2
5de2fbd6
 
40fe269d
       rmdir_safer "${dst}.failed"
       exekutor mv "${dst}" "${dst}.failed"
       exit 1
5de2fbd6
    fi
 }
 
 
40fe269d
 git_clone()
5de2fbd6
 {
    local src
    local dst
    local tag
 
    src="$1"
    dst="$2"
    tag="$3"
 
40fe269d
    [ -z "$src" ] && internal_fail "src is empty"
    [ -z "$dst" ] && internal_fail "dst is empty"
 
    log_info "Cloning ${C_WHITE}${src}${C_INFO} ..."
    exekutor git clone ${GITFLAGS} "${src}" "${dst}" || fail "git clone of \"${src}\" into \"${dst}\" failed"
5de2fbd6
 
    if [ "${tag}" != "" ]
    then
40fe269d
       git_checkout_tag "${dst}" "${tag}"
    fi
 }
c6e7156e
 
5de2fbd6
 
40fe269d
 git_pull()
 {
    local dst
    local tag
 
    dst="$1"
    tag="$2"
 
    [ -z "$dst" ] && internal_fail "dst is empty"
 
    log_info "Updating ${C_WHITE}${dst}${C_INFO} ..."
    ( exekutor cd "${dst}" ; exekutor git pull ${GITFLAGS} ) || fail "git pull of \"${dst}\" failed"
 
    if [ "${tag}" != "" ]
    then
       git_checkout_tag "${dst}" "${tag}"
5de2fbd6
    fi
 }
 
 
b9894c39
 INHERIT_SETTINGS="taps brews gits pips gems build_order build_ignore"
5de2fbd6
 
 
 bootstrap_recurse()
 {
    local dst
e3e80f18
    local name
5de2fbd6
 
    dst="$1"
e3e80f18
 
3c8ec4d2
    [ ! -z "${dst}" ] || internal_fail "dst was empty"
    [ "${PWD}" != "${dst}" ] || internal_fail "configuration error"
 
    name="`basename "${dst}"`"
5de2fbd6
 
    # contains own bootstrap ? and not a symlink
    if [ ! -d "${dst}/.bootstrap" ] # -a ! -L "${dst}" ]
    then
40fe269d
       log_fluff "no .bootstrap folder in \"${dst}\" found"
5de2fbd6
       return 1
    fi
 
c6e7156e
    log_info "Recursively acquiring ${dstname} .bootstrap settings ..."
 
e3e80f18
    # prepare auto folder if it doesn't exist yet
5de2fbd6
    if [ ! -d "${BOOTSTRAP_SUBDIR}.auto" ]
    then
e3e80f18
       echo "Found a .bootstrap folder for `basename "${dst}"` will set up ${BOOTSTRAP_SUBDIR}.auto" >&2
5de2fbd6
 
3be635de
       mkdir_if_missing "${BOOTSTRAP_SUBDIR}.auto/settings"
e3e80f18
       for i in $INHERIT_SETTINGS
5de2fbd6
       do
          if [ -f "${BOOTSTRAP_SUBDIR}.local/${i}" ]
          then
3be635de
             exekutor cp "${BOOTSTRAP_SUBDIR}}.local/${i}" "${BOOTSTRAP_SUBDIR}.auto/${i}" || exit 1
5de2fbd6
          else
             if [ -f "${BOOTSTRAP_SUBDIR}/${i}" ]
             then
3be635de
                exekutor cp "${BOOTSTRAP_SUBDIR}/${i}" "${BOOTSTRAP_SUBDIR}.auto/${i}" || exit 1
5de2fbd6
             fi
          fi
       done
    fi
 
    #
    # prepend new contents to old contents
    # of a few select and known files
    #
e3e80f18
    for i in $INHERIT_SETTINGS
5de2fbd6
    do
       if [ -f "${dst}/.bootstrap/${i}" ]
       then
          if [ -f "${BOOTSTRAP_SUBDIR}.auto/${i}" ]
          then
3be635de
             exekutor mv "${BOOTSTRAP_SUBDIR}.auto/${i}" "${BOOTSTRAP_SUBDIR}.auto/${i}.tmp" || exit 1
             exekutor cat "${dst}/.bootstrap/${i}" "${BOOTSTRAP_SUBDIR}.auto/${i}.tmp" > "${BOOTSTRAP_SUBDIR}.auto/${i}"  || exit 1
             exekutor rm "${BOOTSTRAP_SUBDIR}.auto/${i}.tmp" || exit 1
5de2fbd6
          else
3be635de
             exekutor cp "${dst}/.bootstrap/${i}" "${BOOTSTRAP_SUBDIR}.auto/${i}" || exit 1
5de2fbd6
          fi
       fi
    done
 
    #
e3e80f18
    # link up other non-inheriting settings
5de2fbd6
    #
e3e80f18
    if dir_has_files "${dst}/.bootstrap/settings"
5de2fbd6
    then
e3e80f18
       local relative
5de2fbd6
 
3be635de
       mkdir_if_missing "${BOOTSTRAP_SUBDIR}.auto/settings/${name}"
3c8ec4d2
       relative="`compute_relative "${BOOTSTRAP_SUBDIR}"`"
3be635de
       exekutor find "${dst}/.bootstrap/settings" -type f -depth 1 -print0 | \
          exekutor xargs -0 -I % ln -s -f "${relative}/../../"% "${BOOTSTRAP_SUBDIR}.auto/settings/${name}"
5de2fbd6
 
e3e80f18
       # flatten folders into our own settings
3be635de
       exekutor find "${dst}/.bootstrap/settings" -type d -depth 1 -print0 | \
          exekutor xargs -0 -I % ln -s -f "${relative}/../"% "${BOOTSTRAP_SUBDIR}.auto/settings"
5de2fbd6
    fi
 
e3e80f18
 
5de2fbd6
    return 0
 }
 
 
40fe269d
 ensure_clones_directory()
 {
    if [ ! -d "${CLONES_FETCH_SUBDIR}" ]
    then
       if [ "${COMMAND}" = "update" ]
       then
          fail "install first before upgrading"
       fi
       mkdir_if_missing "${CLONES_FETCH_SUBDIR}"
    fi
 }
 
 
 mark_all_zombies()
 {
    local i
 
       # first mark all repos as stale
    if dir_has_files "${CLONES_FETCH_SUBDIR}"
    then
       log_fluff "Marking all repositories as zombies for now"
 
       for i in `ls -1d "${CLONES_FETCH_SUBDIR}/"*`
       do
          if [ -d "${i}" -o -L "${i}" ]
          then
             exekutor chmod -h 000 "${i}"
          fi
       done
    fi
 }
 
 
 mark_alive()
 {
    local dstname
 
    dstname="$1"
 
    local permission
 
    # mark as alive
    if [ -d "${dstname}" -o -L "${dstname}" ] && [ ! -r "${dstname}" ]
    then
3c8ec4d2
       permission="`lso "${CLONES_FETCH_SUBDIR}"`"
40fe269d
       [ ! -z "$permission" ] || fail "failed to get permission of ${CLONES_FETCH_SUBDIR}"
       exekutor chmod -h "${permission}" "${dstname}"
 
b9894c39
       log_fluff "Marked \"${dstname}\" as alive"
40fe269d
    fi
 }
 
 
 log_fetch_action()
 {
    local dstname
    local clone
 
    clone="$1"
    dstname="$2"
 
    local info
 
    if [ -L "${clone}" ]
    then
       info="symlinked"
    else
       info=" "
    fi
 
    log_fluff "$COMMAND ${info}${clone} in ${dstname} ..."
 }
 
5de2fbd6
 #
 # Use git clones for stuff that gets tagged
 # if you specify ../ it will assume you have
 # checked it out yourself, If there is something
 # checked out already it will use it, or ask
3be635de
 # convention: .git suffix == repo to clone
 #          no .git suffix, try to symlink
5de2fbd6
 #
40fe269d
 checkout_repository()
 {
    local dstname
 
3c8ec4d2
    dstname="$4"
40fe269d
 
    if [ ! -e "${dstname}" ]
    then
3c8ec4d2
       checkout "$@"
40fe269d
       if [ "${COMMAND}" = "install" -a "${DONT_RECURSE}" = "" ]
       then
          bootstrap_recurse "${dstname}"
          if [ $? -eq 0 ]
          then
             return 1
          fi
       fi
3c8ec4d2
    else
       log_fluff "Repository \"${dstname}\" already exists"
40fe269d
    fi
    return 0
 }
 
 
 clone_repository()
5de2fbd6
 {
    local clone
40fe269d
 
    clone="$1"
 
5de2fbd6
    local name1
    local name2
    local tag
    local dstname
 
3c8ec4d2
    name1="`basename "${clone}" .git`"
    name2="`basename "${clone}"`"
    tag="`read_repo_setting "${name1}" "tag"`" #repo (sic)
5de2fbd6
 
40fe269d
    dstname="${CLONES_FETCH_SUBDIR}/${name1}"
 
    mark_alive "${dstname}"
    log_fetch_action "${clone}" "${dstname}"
 
    checkout_repository "${clone}" "${name1}" "${name2}" "${dstname}" "${tag}"
 }
 
 
 clone_repositories()
 {
    if [ $# -ne 0 ]
3ed530a3
    then
40fe269d
       log_error  "Additional parameters not allowed for install"
       usage >&2
       exit 1
3ed530a3
    fi
 
40fe269d
    local stop
    local clones
    local clone
 
    mark_all_zombies
 
5de2fbd6
    stop=0
    while [ $stop -eq 0 ]
    do
       stop=1
 
3c8ec4d2
       clones="`read_fetch_setting "gits"`"
5de2fbd6
       if [ "${clones}" != "" ]
       then
40fe269d
          ensure_clones_directory
5de2fbd6
 
          for clone in ${clones}
          do
40fe269d
             clone_repository "${clone}"
             if [ $? -eq 1 ]
             then
                stop=0
                break
             fi
          done
       fi
    done
 }
5de2fbd6
 
 
40fe269d
 update()
 {
    local clone
    local name
    local tag
    local dstname
3ed530a3
 
40fe269d
    clone="$1"
    name="$2"
    dstname="$3"
    tag="$4"
3ed530a3
 
40fe269d
    [ -z "$clone" ]    && internal_fail "clone is empty"
    [ -z "$name" ]     && internal_fail "name is empty"
    [ -z "$dstname" ]  && internal_fail "dstname is empty"
c6e7156e
 
40fe269d
    local script
c6e7156e
 
40fe269d
    log_info "Updating \"${dstname}\""
    if [ ! -L "${dstname}"  ]
    then
3c8ec4d2
       script="`read_repo_setting "${name}" "bin/update.sh"`"
40fe269d
       if [ ! -z "${script}" ]
       then
          run_script "${script}" "$@"
       else
          exekutor git_pull "${dstname}" "${tag}"
       fi
3ed530a3
 
3c8ec4d2
       script="`read_repo_setting "${name}" "bin/post-update.sh"`"
40fe269d
       if [ ! -z "${script}" ]
       then
          run_script "${script}" "$@"
       fi
    fi
 }
 
 
 update_repository()
 {
    local clone
 
    clone="$1"
 
    local name
    local tag
    local dstname
 
3c8ec4d2
    name="`basename "${clone}" .git`"
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
40fe269d
 
    dstname="${CLONES_FETCH_SUBDIR}/${name}"
    exekutor [ -e "${dstname}" ] || fail "You need to install first, before updating"
    exekutor [ -x "${dstname}" ] || fail "${name} is not anymore in \"gits\""
 
    log_fetch_action "${clone}" "${dstname}"
 
    update "${clone}" "${name}" "${dstname}" "${tag}"
 }
 
 
 #
 # Use git clones for stuff that gets tagged
 # if you specify ../ it will assume you have
 # checked it out yourself, If there is something
 # checked out already it will use it, or ask
 # convention: .git suffix == repo to clone
 #          no .git suffix, try to symlink
 #
 update_repositories()
 {
    local clones
    local clone
    local i
5de2fbd6
 
40fe269d
    if [ $# -ne 0 ]
    then
       for clone in "$@"
       do
          update_repository "${CLONES_FETCH_SUBDIR}/${clone}"
       done
    else
3c8ec4d2
       clones="`read_fetch_setting "gits"`"
40fe269d
       if [ "${clones}" != "" ]
       then
          for clone in ${clones}
          do
             update_repository "${clone}"
5de2fbd6
          done
       fi
40fe269d
    fi
5de2fbd6
 }
 
 
 
 
 #
 # Use brews for stuff we don't tag
 #
 install_taps()
 {
    local tap
    local taps
3be635de
    local old
5de2fbd6
 
3c8ec4d2
    log_fluff "Looking for taps"
 
5de2fbd6
    taps=`read_fetch_setting "taps" | sort | sort -u`
    if [ "${taps}" != "" ]
    then
3be635de
       local old
 
3c8ec4d2
       fetch_brew_if_needed
3be635de
 
       old="${IFS:-" "}"
       IFS="
 "
5de2fbd6
       for tap in ${taps}
       do
3be635de
          exekutor brew tap "${tap}" > /dev/null || exit 1
5de2fbd6
       done
3c8ec4d2
    else
       log_fluff "No taps found"
5de2fbd6
    fi
 }
 
 
 install_brews()
 {
    local brew
    local brews
 
    install_taps
 
3c8ec4d2
    log_fluff "Looking for brews"
 
5de2fbd6
    brews=`read_fetch_setting "brews" | sort | sort -u`
    if [ "${brews}" != "" ]
    then
3be635de
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
5de2fbd6
       for brew in ${brews}
       do
3c8ec4d2
          if [ "`which "${brew}"`" = "" ]
5de2fbd6
          then
3c8ec4d2
             brew_update_if_needed "${brew}"
 
             log_fluff "brew ${COMMAND} \"${brew}\""
40fe269d
             exekutor brew "${COMMAND}" "${brew}" || exit 1
3c8ec4d2
          else
             log_info "\"${brew}\" is already installed."
5de2fbd6
          fi
       done
3be635de
       IFS="${old}"
3c8ec4d2
    else
       log_fluff "No brews found"
5de2fbd6
    fi
 }
 
3be635de
 
 #
 # future, download tarballs...
 #
 check_tars()
 {
    local tarballs
    local tar
 
3c8ec4d2
    log_fluff "Looking for tarballs"
 
    tarballs="`read_fetch_setting "tarballs" | sort | sort -u`"
3be635de
    if [ "${tarballs}" != "" ]
    then
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
       for tar in ${tarballs}
       do
          if [ ! -f "$tar" ]
          then
             fail "tarball \"$tar\" not found"
          fi
3c8ec4d2
          log_fluff "tarball \"$tar\" found"
3be635de
       done
       IFS="${old}"
3c8ec4d2
    else
       log_fluff "No tarballs found"
3be635de
    fi
 }
 
 
5de2fbd6
 #
 # Use gems for stuff we don't tag
 #
 install_gems()
 {
    local gems
    local gem
 
3c8ec4d2
    log_fluff "Looking for gems"
 
    gems="`read_fetch_setting "gems" | sort | sort -u`"
5de2fbd6
    if [ "${gems}" != "" ]
    then
3be635de
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
5de2fbd6
       for gem in ${gems}
       do
3c8ec4d2
          log_fluff "gem install \"${gem}\""
 
5de2fbd6
          echo "gem needs sudo to install ${gem}" >&2
3be635de
          exekutor sudo gem install "${gem}" || exit 1
5de2fbd6
       done
3be635de
       IFS="${old}"
3c8ec4d2
    else
       log_fluff "No gems found"
5de2fbd6
    fi
 }
 
3c8ec4d2
 
5de2fbd6
 #
 # Use pips for stuff we don't tag
 #
 install_pips()
 {
    local pips
    local pip
 
3c8ec4d2
    log_fluff "Looking for pips"
 
    pips="`read_fetch_setting "pips" | sort | sort -u`"
5de2fbd6
    if [ "${pips}" != "" ]
    then
3be635de
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
5de2fbd6
       for pip in ${pips}
       do
3c8ec4d2
          log_fluff "pip install \"${gem}\""
 
5de2fbd6
          echo "pip needs sudo to install ${pip}" >&2
3be635de
          exekutor sudo pip install "${pip}" || exit 1
5de2fbd6
       done
3be635de
       IFS="${old}"
3c8ec4d2
    else
       log_fluff "No pips found"
5de2fbd6
    fi
 }
 
 
 main()
 {
3c8ec4d2
    log_fluff "::: fetch :::"
5de2fbd6
    #
    # Run prepare scripts if present
    #
40fe269d
    run_fetch_settings_script "pre-${COMMAND}"
5de2fbd6
 
 
40fe269d
    if [ "${COMMAND}" = "install" ]
    then
       clone_repositories "$@"
 
3c8ec4d2
       install_brews
40fe269d
       install_gems
       install_pips
       check_tars
    else
       update_repositories "$@"
    fi
5de2fbd6
 
    #
    # Run prepare scripts if present
    #
40fe269d
    run_fetch_settings_script "post-${COMMAND}"
5de2fbd6
 }
 
40fe269d
 main "$@"