The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
# bash+ - Modern Bash Programming
#
# Copyright (c) 2013-2015 Ingy döt Net

{
  bash+:version-check() {
    test $1 -ge 4 && return
    test $1 -eq 3 -a $2 -ge 2 && return
    echo "Bash version 3.2 or higher required for 'git hub'" >&2
    exit 1
  }
  bash+:version-check "${BASH_VERSINFO[@]}"
  unset -f Bash:version-check
}

set -e

[ -z "$BASHPLUS_VERSION" ] || return 0

BASHPLUS_VERSION='0.0.6'

@() { echo "$@"; }
bash+:export:std() { @ use die warn; }

# Source a bash library call import on it:
bash+:use() {
  local library_name="${1:?bash+:use requires library name}"; shift
  local library_path="$(bash+:findlib $library_name)"
  [ -n "$library_path" ] || {
    bash+:die "Can't find library '$library_name'." 1
  }
  source "$library_path"
  if bash+:can "$library_name:import"; then
    "$library_name:import" "$@"
  else
    bash+:import "$@"
  fi
}

# Copy bash+: functions to unprefixed functions
bash+:import() {
  local arg=
  for arg; do
    if [[ "$arg" =~ ^: ]]; then
      bash+:import `bash+:export$arg`
    else
      bash+:fcopy bash+:$arg $arg
    fi
  done
}

# Function copy
bash+:fcopy() {
  bash+:can "${1:?bash+:fcopy requires an input function name}" ||
    bash+:die "'$1' is not a function" 2
  local func=$(type "$1" 3>/dev/null | tail -n+3)
  [ -n "$3" ] && "$3"
  eval "${2:?bash+:fcopy requires an output function name}() $func"
}

# Find the path of a library
bash+:findlib() {
  local library_name="$(tr 'A-Z' 'a-z' <<< "${1//:://}").bash"
  local lib="${BASHPLUSLIB:-${BASHLIB:-$PATH}}"
  library_name="${library_name//+/\\+}"
  find ${lib//:/ } -name ${library_name##*/} 2>/dev/null |
    grep -E "$library_name\$" |
    head -n1
}

bash+:die() {
  local msg="${1:-Died}"
  printf "${msg//\\n/$'\n'}" >&2
  local trailing_newline_re=$'\n''$'
  [[ "$msg" =~ $trailing_newline_re ]] && exit 1

  local c=($(caller ${DIE_STACK_LEVEL:-${2:-0}}))
  [ ${#c[@]} -eq 2 ] &&
    msg=" at line %d of %s" ||
    msg=" at line %d in %s of %s"
  printf "$msg\n" ${c[@]} >&2
  exit 1
}

bash+:warn() {
  local msg="${1:-Warning}"
  printf "${msg//\\n/$'\n'}\n" >&2
}

bash+:can() {
  [ "$(type -t "${1:?bash+:can requires a function name}")" == function ]
}