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
 #
c6e7156e
 . mulle-bootstrap-local-environment.sh
d388168a
 . mulle-bootstrap-brew.sh
7fdfcd11
 . mulle-bootstrap-scm.sh
d7f96955
 . mulle-bootstrap-scripts.sh
b11d86bc
 . mulle-bootstrap-auto-update.sh
5de2fbd6
 
 
40fe269d
 usage()
 {
    cat <<EOF
c4ce7ff9
 usage: fetch [-f] <install|nonrecursive|update>
    -f           : override dirty harry check
 
40fe269d
    install      : clone or symlink non-exisiting repositories and other resources
    nonrecursive : like above, but ignore .bootstrap folders of repositories
020d550a
    update       : execute `git pull` in fetched repositories
40fe269d
 
290ab3f7
    You can specify the names of the repositories to update.
40fe269d
    Currently available names are:
 EOF
7a4ae0c8
    (cd "${CLONESFETCH_SUBDIR}" ; ls -1 ) 2> /dev/null
40fe269d
 }
 
 
3be635de
 
4aa41e69
 while :
 do
    if [ "$1" = "-h" -o "$1" = "--help" ]
40fe269d
    then
4aa41e69
       usage >&2
       exit 1
40fe269d
    fi
3be635de
 
4aa41e69
    if [ "$1" = "-f" ]
40fe269d
    then
4aa41e69
       FORCE="YES"
       [ $# -eq 0 ] || shift
       continue
40fe269d
    fi
4aa41e69
 
    break
 done
 
 
 
 if [ -z "${COMMAND}" ]
 then
    COMMAND=${1:-"install"}
    [ $# -eq 0 ] || shift
 fi
 
 if [ "${MULLE_BOOTSTRAP}" = "mulle-bootstrap" ]
 then
    COMMAND="install"
5de2fbd6
 fi
 
4aa41e69
 
 case "$COMMAND" in
    install)
       ;;
    nonrecursive)
      COMMAND=install
      DONT_RECURSE="YES"
       ;;
    update)
       ;;
    *)
       usage >&2
       exit 1
       ;;
 esac
 
5de2fbd6
 
 
1e8d5d86
 #
 # Use brews for stuff we don't tag
 #
 install_taps()
 {
    local tap
    local taps
 
    log_fluff "Looking for taps"
 
    taps=`read_fetch_setting "taps" | sort | sort -u`
    if [ "${taps}" != "" ]
    then
       fetch_brew_if_needed
 
61fc7238
       local old
 
1e8d5d86
       old="${IFS:-" "}"
       IFS="
 "
       for tap in ${taps}
       do
56104254
          IFS="${old}"
1e8d5d86
          exekutor brew tap "${tap}" > /dev/null || exit 1
       done
56104254
       IFS="${old}"
1e8d5d86
    else
       log_fluff "No taps found"
    fi
 }
 
 
 install_brews()
 {
    local brew
    local brews
 
    install_taps
 
    log_fluff "Looking for brews"
 
    brews=`read_fetch_setting "brews" | sort | sort -u`
    if [ "${brews}" != "" ]
    then
       local old
50fec60e
       local flag
1e8d5d86
 
       old="${IFS:-" "}"
       IFS="
 "
       for brew in ${brews}
       do
56104254
          IFS="${old}"
1e8d5d86
          if [ "`which "${brew}"`" = "" ]
          then
             brew_update_if_needed "${brew}"
50fec60e
             flag=$?
 
94eb4f61
             if [ $flag -eq 2 ]
a75ed0ba
             then
50fec60e
                log_info "No brewing being done."
                return 1
a75ed0ba
             fi
50fec60e
 
             log_fluff "brew ${COMMAND} \"${brew}\""
             exekutor brew "${COMMAND}" "${brew}" || exit 1
1e8d5d86
          else
             log_info "\"${brew}\" is already installed."
          fi
       done
       IFS="${old}"
    else
       log_fluff "No brews found"
    fi
 }
 
 
 #
 # future, download tarballs...
422c21da
 # we check for existance during fetch, but install during build
fe01cf28
 #
1e8d5d86
 check_tars()
 {
    local tarballs
    local tar
 
    log_fluff "Looking for tarballs"
 
    tarballs="`read_fetch_setting "tarballs" | sort | sort -u`"
    if [ "${tarballs}" != "" ]
    then
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
       for tar in ${tarballs}
       do
56104254
          IFS="${old}"
1e8d5d86
          if [ ! -f "$tar" ]
          then
             fail "tarball \"$tar\" not found"
          fi
          log_fluff "tarball \"$tar\" found"
       done
       IFS="${old}"
    else
       log_fluff "No tarballs found"
    fi
 }
 
 
 #
 # Use gems for stuff we don't tag
 #
 install_gems()
 {
    local gems
    local gem
 
    log_fluff "Looking for gems"
 
    gems="`read_fetch_setting "gems" | sort | sort -u`"
    if [ "${gems}" != "" ]
    then
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
       for gem in ${gems}
       do
56104254
          IFS="${old}"
1e8d5d86
          log_fluff "gem install \"${gem}\""
 
          echo "gem needs sudo to install ${gem}" >&2
          exekutor sudo gem install "${gem}" || exit 1
       done
       IFS="${old}"
    else
       log_fluff "No gems found"
    fi
 }
 
 
 #
 # Use pips for stuff we don't tag
 #
 install_pips()
 {
    local pips
    local pip
 
    log_fluff "Looking for pips"
 
    pips="`read_fetch_setting "pips" | sort | sort -u`"
    if [ "${pips}" != "" ]
    then
       local old
 
       old="${IFS:-" "}"
       IFS="
 "
       for pip in ${pips}
       do
56104254
          IFS="${old}"
1e8d5d86
          log_fluff "pip install \"${gem}\""
 
          echo "pip needs sudo to install ${pip}" >&2
          exekutor sudo pip install "${pip}" || exit 1
       done
       IFS="${old}"
    else
       log_fluff "No pips found"
    fi
 }
 
700d4f51
 
1e8d5d86
 #
 ###
 #
5de2fbd6
 link_command()
 {
    local src
    local dst
    local tag
 
    src="$1"
    dst="$2"
    tag="$3"
 
fe01cf28
    local dstdir
a203984b
    dstdir="`dirname -- "${dst}"`"
fe01cf28
 
70513e67
    if [ ! -e "${dstdir}/${src}" -a "${MULLE_BOOTSTRAP_DRY_RUN}" != "YES" ]
5de2fbd6
    then
70513e67
       fail "${C_RESET}${C_BOLD}${dstdir}/${src}${C_ERROR} does not exist ($PWD)"
5de2fbd6
    fi
 
    if [ "${COMMAND}" = "install" ]
    then
fe01cf28
       #
       # relative paths look nicer, but could fail in more complicated
       # settings, when you symlink something, and that repo has symlinks
       # itself
       #
       if read_yes_no_config_setting "absolute_symlinks" "NO"
       then
          local real
 
          real="`( cd "${dstdir}" ; realpath "${src}")`"
7fdfcd11
          log_fluff "Converted symlink \"${src}\" to \"${real}\""
fe01cf28
          src="${real}"
       fi
 
f146fd2e
       log_info "Symlinking ${C_MAGENTA}${C_BOLD}`basename -- ${src}`${C_INFO} ..."
40fe269d
       exekutor ln -s -f "$src" "$dst" || fail "failed to setup symlink \"$dst\" (to \"$src\")"
36b34def
 
5de2fbd6
       if [ "$tag" != "" ]
       then
fe01cf28
          local name
 
a203984b
          name="`basename -- "${dst}"`"
fe01cf28
          log_warning "tag ${tag} will be ignored, due to symlink" >&2
          log_warning "if you want to checkout this tag do:" >&2
70513e67
          log_warning "${C_RESET}${C_BOLD}(cd .repos/${name}; git ${GITFLAGS} checkout \"${tag}\" )${C_WARNING}" >&2
5de2fbd6
       fi
    fi
 
    # when we link, we assume that dependencies are there
 }
 
 
 ask_symlink_it()
 {
    local  clone
 
    clone="$1"
    if [ ! -d "${clone}" ]
    then
fe01cf28
       fail "You need to check out ${clone} yourself, as it's not there."
5de2fbd6
    fi
 
f146fd2e
    #
5de2fbd6
    # check if checked out
f146fd2e
    #
5de2fbd6
    if [ -d "${clone}"/.git ]
    then
f146fd2e
        # if bare repo, we can only clone anyway
602ae7d9
       if git_is_bare_repository "${clone}"
f146fd2e
       then
          log_info "${clone} is a bare git repository. So cloning"
          log_info "is the only way to go."
          return 1
       fi
 
5de2fbd6
       flag=1  # mens clone it
       if [ "${SYMLINK_FORBIDDEN}" != "YES" ]
       then
a75ed0ba
          local prompt
 
          prompt="Should ${clone} be symlinked instead of cloned ?
 You usually say NO to this."
 
          if [ ! -z "${tag}" ]
          then
             prompt="${prompt} (Even more so, since tag is set as ${tag})"
          fi
 
          user_say_yes "$prompt"
5de2fbd6
          flag=$?
       fi
a75ed0ba
 
5de2fbd6
       [ $flag -eq 0 ]
       return $?
    fi
 
    # can only symlink because not a .git repo yet
    if [ "${SYMLINK_FORBIDDEN}" != "YES" ]
    then
fe01cf28
       log_info "${clone} is not a git repository (yet ?)"
       log_info "So symlinking is the only way to go."
5de2fbd6
       return 0
    fi
 
fe01cf28
    fail "Can't symlink"
5de2fbd6
 }
 
 
700d4f51
 
40fe269d
 log_fetch_action()
 {
151d8edd
    local dstdir
7fdfcd11
    local url
40fe269d
 
7fdfcd11
    url="$1"
151d8edd
    dstdir="$2"
40fe269d
 
1e8d5d86
    local info
 
7fdfcd11
    if [ -L "${url}" ]
1e8d5d86
    then
       info=" symlinked "
    else
       info=" "
    fi
 
7fdfcd11
    log_fluff "Perform ${COMMAND}${info}${url} in ${dstdir} ..."
1e8d5d86
 }
 
 
602ae7d9
 search_git_repo_in_parent_directory()
 {
    local name
    local branch
 
    name="$1"
    branch="$2"
 
    local found
 
    if [ ! -z "${branch}" ]
    then
       found="../${name}.${branch}"
       if [ -d "${found}" ]
       then
          echo "${found}"
          return
       fi
    fi
 
    found="../${name}"
    if [ -d "${found}" ]
    then
       echo "${found}"
       return
    fi
 
    found="../${name}.git"
    if [ -d "${found}" ]
    then
       echo "${found}"
       return
    fi
 }
 
 
1e8d5d86
 checkout()
 {
7fdfcd11
    local url
1e8d5d86
    local name
151d8edd
    local dstdir
602ae7d9
    local branch
7fdfcd11
    local tag
bf4c7902
    local scm
1e8d5d86
 
7fdfcd11
    name="$1"
    url="$2"
151d8edd
    dstdir="$3"
602ae7d9
    branch="$4"
    tag="$5"
bf4c7902
    scm="$6"
1e8d5d86
 
151d8edd
    [ ! -z "$name" ]   || internal_fail "name is empty"
7fdfcd11
    [ ! -z "$url" ]    || internal_fail "url is empty"
151d8edd
    [ ! -z "$dstdir" ] || internal_fail "dstdir is empty"
1e8d5d86
 
fe01cf28
    local relative
7fdfcd11
    local name2
1e8d5d86
 
a203984b
    relative="`dirname -- "${dstdir}"`"
fe01cf28
    relative="`compute_relative "${relative}"`"
    if [ ! -z "${relative}" ]
    then
       relative="${relative}/"
    fi
a203984b
    name2="`basename -- "${url}"`"  # only works for git really
1e8d5d86
 
7fdfcd11
    local operation
    local map
bf4c7902
    local scmflagsdefault
7fdfcd11
 
bf4c7902
    case "${scm}" in
7fdfcd11
       git|"" )
          operation="git_clone"
602ae7d9
          scmflagsdefault="--recursive"
7fdfcd11
          ;;
       svn)
          operation="svn_checkout"
          ;;
 
       *)
bf4c7902
          fail "unknown scm system ${scm}"
7fdfcd11
          ;;
    esac
 
    local found
    local src
    local script
 
    src="${url}"
1e8d5d86
    script="`find_repo_setting_file "${name}" "bin/${COMMAND}.sh"`"
 
    if [ ! -z "${script}" ]
    then
       run_script "${script}" "$@"
    else
7fdfcd11
       case "${url}" in
1e8d5d86
          /*)
602ae7d9
             if git_is_bare_repository "${url}"
1e8d5d86
             then
602ae7d9
                :
             else
                ask_symlink_it "${src}"
                if [ $? -eq 0 ]
                then
                   operation=link_command
                fi
1e8d5d86
             fi
          ;;
 
          ../*|./*)
602ae7d9
             if git_is_bare_repository "${url}"
1e8d5d86
             then
602ae7d9
                :
             else
                ask_symlink_it "${src}"
                if [ $? -eq 0 ]
                then
                   operation=link_command
                   src="${relative}${url}"
                fi
1e8d5d86
             fi
          ;;
 
          *)
602ae7d9
             found="`search_git_repo_in_parent_directory "${name}" "${branch}"`"
             if [ -z "${found}" ]
1e8d5d86
             then
602ae7d9
                found="`search_git_repo_in_parent_directory "${name2}" "${branch}"`"
1e8d5d86
             fi
 
602ae7d9
             if [ ! -z "${found}" ]
1e8d5d86
             then
a75ed0ba
                user_say_yes "There is a \"${found}\" folder in the parent directory of this project.
 (\"${PWD}\"). Use it ?"
1e8d5d86
                if [ $? -eq 0 ]
                then
7fdfcd11
                   src="${found}"
602ae7d9
 
                   if git_is_bare_repository "${src}"
1e8d5d86
                   then
602ae7d9
                      :
                   else
                      ask_symlink_it "${src}"
                      if [ $? -eq 0 ]
                      then
                         operation=link_command
                         src="${relative}${found}"
                      fi
1e8d5d86
                   fi
                fi
             fi
602ae7d9
 
1e8d5d86
          ;;
       esac
40fe269d
 
57730883
       local scmflags
 
602ae7d9
       scmflags="`read_repo_setting "${name}" "checkout" "${scmflagsdefault}"`"
       "${operation}" "${src}" "${dstdir}" "${branch}" "${tag}" "${scmflags}"
151d8edd
       mulle-bootstrap-warn-scripts.sh "${dstdir}/.bootstrap" "${dstdir}" || fail "Ok, aborted"  #sic
40fe269d
    fi
 }
 
1e8d5d86
 
602ae7d9
 ensure_clone_branch_is_correct()
 {
    local dstdir
    local branch
 
    dstdir="${1}"
    branch="${2}"
 
    local actual
 
    if [ ! -z "${branch}" ]
    then
       actual="`git_get_branch "${dstdir}"`"
       if [ "${actual}" != "${branch}" ]
       then
          fail "Repository \"${dstdir}\" checked-out branch is \"${actual}\".
 But \"${branch}\" is specified.
 Suggested fix:
    mulle-bootstrap clean dist
    mulle-bootstrap"
       fi
    fi
 }
 
79a901e7
 
 did_clone_repository()
 {
    local name
    local url
    local branch
 
    name="$1"
    url="$2"
    branch="$3"
 
    local dstdir
 
    dstdir="${CLONESFETCH_SUBDIR}/${name}"
    run_build_settings_script "${name}" "${url}" "${dstdir}" "did-install" "${dstdir}" "${name}"
 }
 
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()
 {
d7f96955
    local name
7fdfcd11
    local url
bf4c7902
    local dstdir
602ae7d9
    local branch
40fe269d
 
7fdfcd11
    name="$1"
    url="$2"
151d8edd
    dstdir="$3"
602ae7d9
    branch="$4"
bf4c7902
 
    local flag
40fe269d
 
151d8edd
    if [ ! -e "${dstdir}" ]
40fe269d
    then
3c8ec4d2
       checkout "$@"
1e8d5d86
       flag=1
d7f96955
 
40fe269d
       if [ "${COMMAND}" = "install" -a "${DONT_RECURSE}" = "" ]
       then
61fc7238
          local old_bootstrap
a203984b
 
61fc7238
          old_bootstrap="${BOOTSTRAP_SUBDIR}"
a203984b
 
          BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
79a901e7
          clone_embedded_repositories "${dstdir}/"
61fc7238
          BOOTSTRAP_SUBDIR="${old_bootstrap}"
a203984b
 
0109072d
          bootstrap_auto_update "${name}" "${url}" "${dstdir}"
1e8d5d86
          flag=$?
       fi
 
7fdfcd11
       run_build_settings_script "${name}" "${url}" "${dstdir}" "post-${COMMAND}" "$@"
1e8d5d86
 
       # means we recursed and should start fetch from top
       if [ ${flag} -eq 0 ]
       then
          return 1
40fe269d
       fi
3c8ec4d2
    else
602ae7d9
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
 
7fdfcd11
       log_fluff "Repository \"${dstdir}\" already exists"
40fe269d
    fi
79a901e7
 
40fe269d
    return 0
 }
 
 
79a901e7
 
40fe269d
 clone_repository()
5de2fbd6
 {
7fdfcd11
    local name
    local url
602ae7d9
    local branch
bf4c7902
    local scm
40fe269d
 
5fb25a38
    name="$1"
    url="$2"
    branch="$3"
    scm="$4"
40fe269d
 
5de2fbd6
    local tag
151d8edd
    local dstdir
7fdfcd11
    local flag
a75ed0ba
    local doit
5de2fbd6
 
d7f96955
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
7a4ae0c8
    dstdir="${CLONESFETCH_SUBDIR}/${name}"
40fe269d
 
a75ed0ba
    doit=1
    if [ "${DO_CHECK_USR_LOCAL_INCLUDE}" = "YES" ]
    then
       has_usr_local_include "${name}"
       doit=$?
    fi
602ae7d9
 
a75ed0ba
    flag=0
    if [ $doit -ne 0 ]
    then
       log_fetch_action "${name}" "${dstdir}"
79a901e7
 
a75ed0ba
       # mark the checkout progress, so that we don't do incomplete fetches and
       # later on happily build
7fdfcd11
 
a75ed0ba
       create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
       checkout_repository "${name}" "${url}" "${dstdir}" "${branch}" "${tag}" "${scm}"
       flag=$?
 
       remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
    else
       log_info "${C_MAGENTA}${C_BOLD}${name}${C_INFO} is a system library, so not fetching it"
    fi
79a901e7
 
7fdfcd11
    return $flag
40fe269d
 }
 
 
1e8d5d86
 
 clone_repositories()
 {
40fe269d
    local stop
    local clones
    local clone
7fdfcd11
    local old
    local name
    local url
0109072d
    local fetched
    local match
602ae7d9
    local branch
bf4c7902
    local scm
79a901e7
    local rval
7fdfcd11
 
    old="${IFS:-" "}"
0109072d
    fetched=""
 
5de2fbd6
    stop=0
    while [ $stop -eq 0 ]
    do
       stop=1
 
7fdfcd11
       clones="`read_fetch_setting "repositories"`"
5de2fbd6
       if [ "${clones}" != "" ]
       then
40fe269d
          ensure_clones_directory
5de2fbd6
 
7fdfcd11
          IFS="
 "
5de2fbd6
          for clone in ${clones}
          do
7fdfcd11
             IFS="${old}"
0109072d
 
5fb25a38
             clone="`expanded_setting "${clone}"`"
 
0109072d
             # avoid superflous updates
f146fd2e
             match="`echo "${fetched}" | grep -x "${clone}"`"
0109072d
             # could remove prefixes here https:// http://
 
             if [ "${match}" != "${clone}" ]
40fe269d
             then
0109072d
                fetched="${fetched}
 ${clone}"
 
5fb25a38
                name="`canonical_name_from_clone "${clone}"`"
                url="`url_from_clone "${clone}"`"
                branch="`branch_from_clone "${clone}"`"
                scm="`scm_from_clone "${clone}"`"
 
                clone_repository "${name}" "${url}" "${branch}" "${scm}"
 
0109072d
                if [ $? -eq 1 ]
                then
                   stop=0
                   break
                fi
40fe269d
             fi
          done
       fi
    done
1e8d5d86
 
7fdfcd11
    IFS="
 "
0109072d
    for clone in ${fetched}
1e8d5d86
    do
7fdfcd11
       IFS="${old}"
61fc7238
 
5fb25a38
       clone="`expanded_setting "${clone}"`"
 
7fdfcd11
       name="`canonical_name_from_clone "${clone}"`"
       url="`url_from_clone "${clone}"`"
bf4c7902
       branch="`branch_from_clone "${clone}"`"
 
602ae7d9
       did_clone_repository "${name}" "${url}" "${branch}"
1e8d5d86
    done
7fdfcd11
 
    IFS="${old}"
40fe269d
 }
5de2fbd6
 
 
79a901e7
 clone_embedded_repository()
fe01cf28
 {
a203984b
    local dstprefix
79a901e7
    local clone
a203984b
 
    dstprefix="$1"
79a901e7
    clone="$2"
a203984b
 
7fdfcd11
    local name
    local url
a203984b
    local dstdir
602ae7d9
    local branch
79a901e7
    local tag
bf4c7902
    local scm
fe01cf28
 
79a901e7
    name="`canonical_name_from_clone "${clone}"`"
    url="`url_from_clone "${clone}"`"
    branch="`branch_from_clone "${clone}"`"
    scm="`scm_from_clone "${clone}"`"
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
    dstdir="${dstprefix}${name}"
7fdfcd11
 
79a901e7
    log_fetch_action "${name}" "${dstdir}"
fcfae396
 
79a901e7
    if [ ! -d "${dstdir}" ]
fe01cf28
    then
79a901e7
       create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
61fc7238
 
79a901e7
       #
       # embedded_repositories are just cloned, no symlinks,
       #
       local old_forbidden
7fdfcd11
 
79a901e7
       old_forbidden="${SYMLINK_FORBIDDEN}"
fe01cf28
 
79a901e7
       SYMLINK_FORBIDDEN="YES"
       checkout "${name}" "${url}" "${dstdir}" "${branch}" "${tag}" "${scm}"
       SYMLINK_FORBIDDEN="${old_forbidden}"
58c301d4
 
79a901e7
       if read_yes_no_config_setting "update_gitignore" "YES"
       then
          if [ -d .git ]
7fdfcd11
          then
79a901e7
             append_dir_to_gitignore_if_needed "${dstdir}"
          fi
       fi
fe01cf28
 
79a901e7
       # memo that we did this with a symlink
       # store it inside the possibly recursed dstprefix dependency
       local symlinkcontent
       local symlinkdir
       local symlinkrelative
fe01cf28
 
79a901e7
       symlinkrelative=`compute_relative "${CLONESFETCH_SUBDIR}/.embedded"`
       symlinkdir="${dstprefix}${CLONESFETCH_SUBDIR}/.embedded"
       mkdir_if_missing "${symlinkdir}"
       symlinkcontent="${symlinkrelative}/${dstdir}"
fe01cf28
 
79a901e7
       log_fluff "Remember embedded repository \"${name}\" via \"${symlinkdir}/${name}\""
       exekutor ln -s "${symlinkcontent}" "${symlinkdir}/${name}"
 
       run_build_settings_script "${name}" "${url}" "${dstdir}" "post-${COMMAND}" "$@"
    else
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
57730883
 
79a901e7
       log_fluff "Repository \"${dstdir}\" already exists"
    fi
7a4ae0c8
 
79a901e7
    remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 }
57730883
 
7a4ae0c8
 
79a901e7
 clone_embedded_repositories()
 {
    local dstprefix
602ae7d9
 
79a901e7
    dstprefix="$1"
 
    local clones
    local clone
    local old
 
    old="${IFS:-" "}"
 
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="YES"
    export MULLE_BOOTSTRAP_SETTINGS_NO_AUTO
 
    clones="`read_fetch_setting "embedded_repositories"`"
    if [ "${clones}" != "" ]
    then
       IFS="
 "
       for clone in ${clones}
       do
          IFS="${old}"
 
5fb25a38
          clone="`expanded_setting "${clone}"`"
 
79a901e7
          clone_embedded_repository "${dstprefix}" "${clone}"
fe01cf28
       done
58c301d4
 
       remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
fe01cf28
    fi
7fdfcd11
 
    IFS="${old}"
fcfae396
 
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO=
fe01cf28
 }
 
 
6a672446
 # return 0, all cool
 # return 1, is symlinked
 # return 2, .bootstrap/repositories changed
 # return 3, is symlinked and .bootstrap/repositories changed
 
40fe269d
 update()
 {
    local name
7fdfcd11
    local url
602ae7d9
    local branch
40fe269d
    local tag
151d8edd
    local dstdir
bf4c7902
    local scm
3ed530a3
 
7fdfcd11
    name="$1"
    url="$2"
151d8edd
    dstdir="$3"
602ae7d9
    branch="$4"
    tag="$5"
bf4c7902
    scm="$6"
3ed530a3
 
7fdfcd11
    [ ! -z "$url" ]           || internal_fail "url is empty"
151d8edd
    exekutor [ -d "$dstdir" ] || internal_fail "dstdir \"${dstdir}\" is wrong ($PWD)"
    [ ! -z "$name" ]          || internal_fail "name is empty"
c6e7156e
 
7fdfcd11
    local operation
 
bf4c7902
    case "${scm}" in
7fdfcd11
       git|"" )
          operation="git_pull"
          ;;
       svn)
          operation="svn_update"
          ;;
       *)
bf4c7902
          fail "unknown scm system ${scm}"
7fdfcd11
          ;;
    esac
 
40fe269d
    local script
6a672446
    local before_r
    local before_e
    local after_r
    local after_e
    local rval
c6e7156e
 
927b4b79
    before_r=`modification_timestamp "${dstdir}/.bootstrap/repositories" 2> /dev/null`
    before_e=`modification_timestamp "${dstdir}/.bootstrap/embedded_repositories" 2> /dev/null`
6a672446
 
    rval=0
fcfae396
    if [ ! -L "${dstdir}" ]
40fe269d
    then
1b26e970
       run_repo_settings_script "${name}" "${dstdir}" "pre-update" "$@"
d7f96955
 
       script="`find_repo_setting_file "${name}" "bin/update.sh"`"
40fe269d
       if [ ! -z "${script}" ]
       then
          run_script "${script}" "$@"
       else
602ae7d9
          "${operation}" "${dstdir}" "${branch}" "${tag}"
40fe269d
       fi
3ed530a3
 
1b26e970
       run_repo_settings_script "${name}" "${dstdir}" "post-update" "$@"
fcfae396
    else
602ae7d9
       ensure_clone_branch_is_correct "${dstdir}" "${branch}"
79a901e7
       log_info "Repository ${C_MAGENTA}${C_BOLD}${name}${C_INFO} exists and is symlinked, so not updated."
6a672446
 
       rval=1
    fi
 
927b4b79
    after_r=`modification_timestamp "${dstdir}/.bootstrap/repositories" 2> /dev/null`
    after_e=`modification_timestamp "${dstdir}/.bootstrap/embedded_repositories" 2> /dev/null`
6a672446
 
58c301d4
    if [ "${before_r}" != "${after_r}" -o "${before_e}" != "${after_e}" ]
6a672446
    then
       rval="`expr "$rval" + 2`"
40fe269d
    fi
58c301d4
 
6a672446
    return "$rval"
40fe269d
 }
 
 
 update_repository()
 {
7fdfcd11
    local name
    local url
602ae7d9
    local branch
58c301d4
    local dstdir
40fe269d
 
7fdfcd11
    name="$1"
    url="$2"
602ae7d9
    branch="$3"
58c301d4
    dstdir="${CLONESFETCH_SUBDIR}/${name}"
40fe269d
 
    local name
    local tag
6a672446
    local rval
 
3c8ec4d2
    tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
40fe269d
 
58c301d4
    exekutor [ -x "${dstdir}" ] || fail "\"${name}\" is not accesible anymore in \"repositories\""
40fe269d
 
7fdfcd11
    log_fetch_action "${url}" "${dstdir}"
1e8d5d86
 
602ae7d9
    update "${name}" "${url}" "${dstdir}" "${branch}" "${tag}"
6a672446
    rval=$?
fcfae396
    #update will return 1 if repo is symlinked
 
6a672446
    if [ "${DONT_RECURSE}" = "" ]
a203984b
    then
6a672446
       if [ $rval -eq 0 -o $rval -eq 2 ]
       then
          local old_bootstrap
61fc7238
 #      local old_fetch
a203984b
 
6a672446
          old_bootstrap="${BOOTSTRAP_SUBDIR}"
61fc7238
 #      old_fetch="${CLONESFETCH_SUBDIR}"
a203984b
 
6a672446
          BOOTSTRAP_SUBDIR="${dstdir}/.bootstrap"
fcfae396
 #      CLONESFETCH_SUBDIR="${dstdir}/.repos"
7a4ae0c8
 
6a672446
          update_embedded_repositories "${dstdir}/"
fcfae396
 
6a672446
          BOOTSTRAP_SUBDIR="${old_bootstrap}"
61fc7238
 #      CLONESFETCH_SUBDIR="${old_fetch}"
6a672446
       fi
a203984b
    fi
602ae7d9
 
    ensure_clone_branch_is_correct "${dstdir}" "${branch}"
6a672446
    [ $rval -eq 0 -o $rval -eq 2 ]
    return $?
1e8d5d86
 }
 
 
 did_update_repository()
 {
7fdfcd11
    local name
    local url
1e8d5d86
 
7fdfcd11
    name="$1"
    url="$2"
1e8d5d86
 
151d8edd
    local dstdir
1e8d5d86
 
7a4ae0c8
    dstdir="${CLONESFETCH_SUBDIR}/${name}"
40fe269d
 
7fdfcd11
    run_build_settings_script "${name}" "${url}" "${dstdir}" "did-update" "${dstdir}" "${name}"
40fe269d
 }
 
 
 #
 # 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
1e8d5d86
    local name
40fe269d
    local i
7fdfcd11
    local old
 
    old="${IFS:-" "}"
5de2fbd6
 
40fe269d
    if [ $# -ne 0 ]
    then
7fdfcd11
       IFS="
 "
1e8d5d86
       for name in "$@"
       do
7fdfcd11
          IFS="${old}"
58c301d4
          create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
             update_repository "${name}" "${CLONESFETCH_SUBDIR}/${name}"
          remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
1e8d5d86
       done
 
7fdfcd11
       IFS="
 "
1e8d5d86
       for name in "$@"
40fe269d
       do
7fdfcd11
          IFS="${old}"
58c301d4
          create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
             did_update_repository "${name}" "${CLONESFETCH_SUBDIR}/${name}"
          remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
          done
6a672446
       IFS="${old}"
       return
    fi
 
    local stop
    local url
    local updated
    local match
    local branch
    local scm
58c301d4
    local dstdir
    local rval
6a672446
 
    updated=""
 
    stop=0
    while [ $stop -eq 0 ]
    do
       stop=1
 
7fdfcd11
       clones="`read_fetch_setting "repositories"`"
4aa41e69
       clones="`echo "${clones}" | sed '1!G;h;$!d'`"  # reverse lines
 
40fe269d
       if [ "${clones}" != "" ]
       then
7fdfcd11
          IFS="
 "
40fe269d
          for clone in ${clones}
          do
7fdfcd11
             IFS="${old}"
602ae7d9
 
5fb25a38
             clone="`expanded_setting "${clone}"`"
 
6a672446
             # avoid superflous updates
             match="`echo "${updated}" | grep -x "${clone}"`"
3c8ec4d2
 
6a672446
             if [ "${match}" != "${clone}" ]
             then
58c301d4
                updated="${updated}
6a672446
 ${clone}"
4aa41e69
 
6a672446
                name="`canonical_name_from_clone "${clone}"`"
                url="`url_from_clone "${clone}"`"
                branch="`branch_from_clone "${clone}"`"
602ae7d9
 
58c301d4
                dstdir="${CLONESFETCH_SUBDIR}/${name}"
6a672446
 
58c301d4
                create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
                   if [ -e "${dstdir}" ]
                   then
                      update_repository "${name}" "${url}" "${branch}"
                      rval=$?
                   else
                      scm="`scm_from_clone "${clone}"`"
5fb25a38
                      clone_repository "${name}" "${url}" "${branch}" "${scm}"
58c301d4
                      rval=1
                   fi
 
                remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
 
                if [ $rval -eq 1 ]
6a672446
                then
                   stop=0
                   break
                fi
             fi
1e8d5d86
          done
       fi
6a672446
    done
7fdfcd11
 
    IFS="${old}"
5de2fbd6
 }
 
 
7fdfcd11
 update_embedded_repositories()
fe01cf28
 {
a203984b
    local dstprefix
 
    dstprefix="$1"
 
fe01cf28
    local clones
    local clone
7fdfcd11
    local old
    local name
    local url
602ae7d9
    local branch
213c25c7
    local scm
fe01cf28
 
fcfae396
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO="YES"
    export MULLE_BOOTSTRAP_SETTINGS_NO_AUTO
 
7fdfcd11
    old="${IFS:-" "}"
 
    clones="`read_fetch_setting "embedded_repositories"`"
4aa41e69
    clones="`echo "${clones}" | sed '1!G;h;$!d'`"  # reverse lines
 
fe01cf28
    if [ "${clones}" != "" ]
    then
7fdfcd11
       IFS="
 "
fe01cf28
       for clone in ${clones}
       do
7fdfcd11
          IFS="${old}"
5fb25a38
 
          clone="`expanded_setting "${clone}"`"
 
7fdfcd11
          name="`canonical_name_from_clone "${clone}"`"
          url="`url_from_clone "${clone}"`"
602ae7d9
          branch="`branch_from_clone "${clone}"`"
7fdfcd11
 
fe01cf28
          tag="`read_repo_setting "${name}" "tag"`" #repo (sic)
a203984b
          dstdir="${dstprefix}${name}"
fe01cf28
 
a75ed0ba
          local doit
58c301d4
 
a75ed0ba
          doit=1
          if [ "${DO_CHECK_USR_LOCAL_INCLUDE}" = "YES" ]
213c25c7
          then
a75ed0ba
             has_usr_local_include "${name}"
             doit=$?
213c25c7
          fi
 
a75ed0ba
          if [ $doit -ne 0 ]
          then
             log_fetch_action "${name}" "${dstdir}"
 
             create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
             if [ -e "${dstdir}" ]
             then
                update "${name}" "${url}" "${dstdir}" "${branch}" "${tag}"
             else
                clone_embedded_repository "${dstprefix}" "${clone}"
             fi
 
             remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
          else
             log_info "${C_MAGENTA}${C_BOLD}${name}${C_INFO} is a system library, so not updating"
          fi
fe01cf28
       done
    fi
7fdfcd11
 
    IFS="${old}"
fcfae396
    MULLE_BOOTSTRAP_SETTINGS_NO_AUTO=
fe01cf28
 }
 
a7b563e1
 
 append_dir_to_gitignore_if_needed()
 {
    grep -s -x "$1/" .gitignore > /dev/null 2>&1
    if [ $? -ne 0 ]
    then
7fdfcd11
       exekutor echo "$1/" >> .gitignore || fail "Couldn\'t append to .gitignore"
       log_info "Added \"$1/\" to \".gitignore\""
a7b563e1
    fi
 }
 
 
5de2fbd6
 main()
 {
a75ed0ba
    log_verbose "::: fetch :::"
d7f96955
 
fe01cf28
    SYMLINK_FORBIDDEN="`read_config_setting "symlink_forbidden"`"
    export SYMLINK_FORBIDDEN
 
a75ed0ba
    #
    # should we check for '/usr/local/include/<name>' and don't fetch if
    # present (somewhat dangerous, because we do not check versions)
    #
    DO_CHECK_USR_LOCAL_INCLUDE="`read_config_setting "check_usr_local_include" "NO"`"
    export DO_CHECK_USR_LOCAL_INCLUDE
 
40fe269d
    if [ "${COMMAND}" = "install" ]
    then
1e8d5d86
       if [ $# -ne 0 ]
       then
          log_error  "Additional parameters not allowed for install"
          usage >&2
          exit 1
       fi
602ae7d9
    fi
 
4aa41e69
    [ -z "${FORCE}" ] && ensure_consistency
602ae7d9
 
    #
    # Run prepare scripts if present
    #
    if [ "${COMMAND}" = "install" ]
    then
a75ed0ba
       case "`uname`" in
          Darwin|Linux)
             install_brews
             ;;
       esac
bf4c7902
       install_gems
       install_pips
1e8d5d86
 
4aa41e69
       clone_repositories
79a901e7
       clone_embedded_repositories
602ae7d9
 
bf4c7902
       check_tars
40fe269d
    else
4aa41e69
       update_repositories "$@"
7fdfcd11
       update_embedded_repositories
40fe269d
    fi
5de2fbd6
 
    #
    # Run prepare scripts if present
    #
58c301d4
    create_file_if_missing "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
1b26e970
    run_fetch_settings_script "post-${COMMAND}" "$@"
a7b563e1
 
602ae7d9
    remove_file_if_present "${CLONESFETCH_SUBDIR}/.fetch_update_started"
 
a7b563e1
    if read_yes_no_config_setting "update_gitignore" "YES"
    then
       if [ -d .git ]
       then
          append_dir_to_gitignore_if_needed "${BOOTSTRAP_SUBDIR}.auto"
          append_dir_to_gitignore_if_needed "${BOOTSTRAP_SUBDIR}.local"
          append_dir_to_gitignore_if_needed "${DEPENDENCY_SUBDIR}"
          append_dir_to_gitignore_if_needed "${CLONES_SUBDIR}"
       fi
    fi
5de2fbd6
 }
 
40fe269d
 main "$@"