From 9a83015e60a1a477f5714595dff70ec102b0fa7f Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 23 Apr 2016 21:45:03 -0700 Subject: [PATCH] Fix path munging funcs and usage Our `realpath` and `readlink -f` functions (required only because of MacOS, thanks Steve) were poor substitutes at best. Mostly they were downright broken. This thoroughly overhauls them and adds a test (in comments, since we don't seem to have shell tests). For all the interesting cases I could think of, the fakes act just like the real thing. Then use those and canonicalize KUBE_ROOT. In order to make recursive calls of our shell tool not additively grow `pwd` we have to essentially make the sourcing of init.sh idempotent. --- build/common.sh | 7 +--- hack/lib/golang.sh | 2 +- hack/lib/init.sh | 95 ++++++++++++++++++++++++++++++++++++++-------- hack/lib/util.sh | 6 --- 4 files changed, 82 insertions(+), 28 deletions(-) diff --git a/build/common.sh b/build/common.sh index 046b609870e..3c5c7d51903 100755 --- a/build/common.sh +++ b/build/common.sh @@ -26,11 +26,8 @@ DOCKER_HOST=${DOCKER_HOST:-""} DOCKER_MACHINE_NAME=${DOCKER_MACHINE_NAME:-"kube-dev"} readonly DOCKER_MACHINE_DRIVER=${DOCKER_MACHINE_DRIVER:-"virtualbox --virtualbox-memory 4096 --virtualbox-cpu-count -1"} -KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. -cd "${KUBE_ROOT}" - -# This'll canonicalize the path -KUBE_ROOT=$PWD +# This will canonicalize the path +KUBE_ROOT=$(cd $(dirname "${BASH_SOURCE}")/.. && pwd -P) source hack/lib/init.sh diff --git a/hack/lib/golang.sh b/hack/lib/golang.sh index 0aa1a3d3d95..95e1ce8c790 100755 --- a/hack/lib/golang.sh +++ b/hack/lib/golang.sh @@ -309,7 +309,7 @@ kube::golang::setup_env() { # resultant binaries. Go will not let us use GOBIN with `go install` and # cross-compiling, and `go install -o ` only works for a single pkg. local subdir - subdir=$(pwd | sed "s|$KUBE_ROOT||") + subdir=$(kube::realpath . | sed "s|$KUBE_ROOT||") cd "${KUBE_GOPATH}/src/${KUBE_GO_PACKAGE}/${subdir}" # Unset GOBIN in case it already exists in the current session. diff --git a/hack/lib/init.sh b/hack/lib/init.sh index eaacbdae9e4..0ef514d5d5a 100644 --- a/hack/lib/init.sh +++ b/hack/lib/init.sh @@ -19,12 +19,7 @@ set -o nounset set -o pipefail # The root of the build/dist directory -KUBE_ROOT=$( - unset CDPATH - kube_root=$(dirname "${BASH_SOURCE}")/../.. - cd "${kube_root}" - pwd -) +KUBE_ROOT=$(cd $(dirname "${BASH_SOURCE}")/../.. && pwd -P) KUBE_OUTPUT_SUBPATH="${KUBE_OUTPUT_SUBPATH:-_output/local}" KUBE_OUTPUT="${KUBE_ROOT}/${KUBE_OUTPUT_SUBPATH}" @@ -44,15 +39,83 @@ KUBE_GIT_UPSTREAM="${KUBE_GIT_UPSTREAM:-upstream}" KUBE_OUTPUT_HOSTBIN="${KUBE_OUTPUT_BINPATH}/$(kube::util::host_platform)" -# emulates "readlink -f" which is not available on BSD (OS X). -function readlinkdashf { - path=$1 - # Follow links until there are no more links to follow. - while readlink "$path"; do - path="$(readlink $path)" - done - # Convert to canonical path. - path=$(cd "$(dirname "${path}")" && pwd -P) - echo "$path" +# This emulates "readlink -f" which is not available on MacOS X. +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(readlink -f $1 2>&1) +# Y=$(kube::readlinkdashf $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo readlinkdashf $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +function kube::readlinkdashf { + # run in a subshell for simpler 'cd' + ( + if [[ -d "$1" ]]; then # This also catch symlinks to dirs. + cd "$1" + pwd -P + else + cd $(dirname "$1") + local f + f=$(basename "$1") + if [[ -L "$f" ]]; then + readlink "$f" + else + echo "$(pwd -P)/${f}" + fi + fi + ) } +# This emulates "realpath" which is not available on MacOS X +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(realpath $1 2>&1) +# Y=$(kube::realpath $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo realpath $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +kube::realpath() { + if [[ ! -e "$1" ]]; then + echo "$1: No such file or directory" >&2 + return 1 + fi + kube::readlinkdashf "$1" +} diff --git a/hack/lib/util.sh b/hack/lib/util.sh index 6a7e34749ce..c2c5d16075d 100755 --- a/hack/lib/util.sh +++ b/hack/lib/util.sh @@ -18,12 +18,6 @@ kube::util::sortable_date() { date "+%Y%m%d-%H%M%S" } -# this mimics the behavior of linux realpath which is not shipped by default with -# mac OS X -kube::util::realpath() { - [[ $1 = /* ]] && echo "$1" | sed 's/\/$//' || echo "$PWD/${1#./}" | sed 's/\/$//' -} - kube::util::wait_for_url() { local url=$1 local prefix=${2:-}