| #!/usr/bin/env bash |
| # Copyright 2025 The etcd Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| set -euo pipefail |
| |
| #### Convenient IO methods ##### |
| |
| COLOR_RED='' COLOR_ORANGE='' COLOR_GREEN='' COLOR_LIGHTCYAN='' |
| COLOR_BLUE='' COLOR_BOLD='' COLOR_MAGENTA='' COLOR_NONE='' |
| if [ -t 2 ]; then |
| COLOR_RED='\033[0;31m' |
| COLOR_ORANGE='\033[0;33m' |
| COLOR_GREEN='\033[0;32m' |
| COLOR_LIGHTCYAN='\033[0;36m' |
| COLOR_BLUE='\033[0;94m' |
| COLOR_BOLD='\033[1m' |
| COLOR_MAGENTA='\033[95m' |
| COLOR_NONE='\033[0m' # No Color |
| fi |
| export COLOR_RED COLOR_ORANGE COLOR_GREEN COLOR_LIGHTCYAN COLOR_BLUE COLOR_BOLD COLOR_MAGENTA COLOR_NONE |
| |
| |
| 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" |
| } |