#!/usr/bin/env bash set -euo pipefail #### Convenient IO methods ##### export COLOR_RED='\033[0;31m' export COLOR_ORANGE='\033[0;33m' export COLOR_GREEN='\033[0;32m' export COLOR_LIGHTCYAN='\033[0;36m' export COLOR_BLUE='\033[0;94m' export COLOR_BOLD='\033[1m' export COLOR_MAGENTA='\033[95m' export COLOR_NONE='\033[0m' # No Color function log_error { >&2 echo -n -e "${COLOR_BOLD}${COLOR_RED}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } function log_warning { >&2 echo -n -e "${COLOR_ORANGE}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } function log_callout { >&2 echo -n -e "${COLOR_LIGHTCYAN}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } function log_cmd { >&2 echo -n -e "${COLOR_BLUE}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } function log_success { >&2 echo -n -e "${COLOR_GREEN}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } function log_info { >&2 echo -n -e "${COLOR_NONE}" >&2 echo "$@" >&2 echo -n -e "${COLOR_NONE}" } # From http://stackoverflow.com/a/12498485 function relativePath { # both $1 and $2 are absolute paths beginning with / # returns relative path to $2 from $1 local source=$1 local target=$2 local commonPart=$source local result="" while [[ "${target#"$commonPart"}" == "${target}" ]]; do # no match, means that candidate common part is not correct # go up one level (reduce common part) commonPart="$(dirname "$commonPart")" # and record that we went back, with correct / handling if [[ -z $result ]]; then result=".." else result="../$result" fi done if [[ $commonPart == "/" ]]; then # special case for root (no common path) result="$result/" fi # since we now have identified the common part, # compute the non-common part local forwardPart="${target#"$commonPart"}" # and now stick all parts together if [[ -n $result ]] && [[ -n $forwardPart ]]; then result="$result$forwardPart" elif [[ -n $forwardPart ]]; then # extra slash removal result="${forwardPart:1}" fi echo "$result" }