1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#!/usr/bin/env bash
## Commands defined by this file:
#
# * to_absolute <path>
# • Convert a given path into an absolute path. Relative paths are
# resolved relative to the working directory. Removes redundant directory
# separators.
# * native_path <path>
# • On MinGW/Cygwin/MSYS, convert the given Cygwin path to a Windows-native
# path. On other platforms, the argument is unmodified
#
## Variables set by this file:
#
# * TOOLS_DIR
# • The path to the directory containing this script file
# * MONGOC_DIR
# • The path to the top-level project directory
# * USER_CACHES_DIR (overridable)
# • A user-local directory in which to store cached data
# * BUILD_CACHE_DIR (overridable)
# • A user-local directory for caches related to these scripts
# * EXE_SUFFIX
# • Expands to “.exe” on Windows, otherwise an empty string
. "$(dirname "${BASH_SOURCE[0]}")/use.sh" platform base
# Check for Cygpath, used by various commands. Better to check once than check every time.
_HAVE_CYGPATH=false
if have-command cygpath; then
_HAVE_CYGPATH=true
fi
# Usage: native-path <path>
native-path() {
[[ "$#" -eq 1 ]] || fail "native_path expects exactly one argument"
local arg=$1
if $IS_WINDOWS; then
$_HAVE_CYGPATH || fail "No 'cygpath' command is available, but we require it to normalize file paths on Windows."
local ret
ret="$(cygpath -w "$arg")"
debug "Convert path [$arg] → [$ret]"
printf %s "$ret"
else
printf %s "$arg"
fi
}
# Usage: to_absolute <path>
to_absolute() {
[[ "$#" -eq 1 ]] || fail "to_absolute expects a single argument"
local ret
local arg="$1"
debug "Resolve path [$arg]"
# Cygpath can resolve the path in a single subprocess:
if $_HAVE_CYGPATH; then
# Ask Cygpath to resolve the path. It knows how to do it reliably and quickly:
ret=$(cygpath --absolute --mixed --long-name -- "$arg")
debug "Cygpath resolved: [$arg]"
printf %s "$ret"
return 0
fi
# If the given directory exists, we can ask the shell to resolve the path
# by going there and asking the PWD:
if is-dir "$arg"; then
ret=$(run-chdir "$arg" pwd)
debug "Resolved: [$arg]"
printf %s "$ret"
return 0
fi
# Do it the "slow" way:
# The parent path:
local _parent
_parent="$(dirname "$arg")"
# The filename part:
local _fname
_fname="$(basename "$arg")"
# There are four cases to consider from dirname:
if [[ $_parent = "." ]]; then # The parent is '.' as in './foo'
# Replace the leading '.' with the working directory
_parent="$(pwd)"
elif [[ $_parent = ".." ]]; then # The parent is '..' as in '../foo'
# Replace a leading '..' with the parent of the working directory
_parent="$(dirname "$(pwd)")"
elif [[ $arg == "$_parent" ]]; then # The parent is itself, as in '/'
# A root directory is its own parent according to 'dirname'
printf %s "$arg"
return 0
else # The parent is some other path, like 'foo' in 'foo/bar'
# Resolve the parent path
_parent="$(set +x; DEBUG=0 to_absolute "$_parent")"
fi
# At this point $_parent is an absolute path
if [[ $_fname = ".." ]]; then
# Strip one component
ret="$(dirname "$_parent")"
elif [[ $_fname = "." ]]; then
# Drop a '.' at the end of a path
ret="$_parent"
else
# Join the result
ret="$_parent/$_fname"
fi
# Remove duplicate dir separators
while [[ $ret =~ "//" ]]; do
ret="${ret//\/\///}"
done
debug "Resolved path: [$arg] → [$ret]"
printf %s "$ret"
}
# Get the TOOLS_DIR as a native absolute path. All other path vars are derived
# from this one, and will therefore remain as native pathsS
_this_file=$(to_absolute "${BASH_SOURCE[0]}")
_this_dir=$(dirname "$_this_file")
TOOLS_DIR=$(native-path "$_this_dir")
declare -r TOOLS_DIR=$TOOLS_DIR
MONGOC_DIR=$(dirname "$TOOLS_DIR")
declare -r MONGOC_DIR=$MONGOC_DIR
EXE_SUFFIX=""
if $IS_WINDOWS; then
EXE_SUFFIX=".exe"
fi
declare -r EXE_SUFFIX=$EXE_SUFFIX
if [[ "${USER_CACHES_DIR:=${XDG_CACHE_HOME:-}}" = "" ]]; then
if $IS_DARWIN; then
USER_CACHES_DIR=$HOME/Library/Caches
elif $IS_UNIX_LIKE; then
USER_CACHES_DIR=$HOME/.cache
elif $IS_WINDOWS; then
USER_CACHES_DIR=${LOCALAPPDATA:-$USERPROFILE/.cache}
else
log "Using ~/.cache as fallback user caching directory"
USER_CACHES_DIR="$(to_absolute ~/.cache)"
fi
fi
# Ensure we are dealing with a complete path
USER_CACHES_DIR="$(to_absolute "$USER_CACHES_DIR")"
declare -r USER_CACHES_DIR=$USER_CACHES_DIR
: "${BUILD_CACHE_BUST:=1}"
: "${BUILD_CACHE_DIR:="$USER_CACHES_DIR/mongoc/build.$BUILD_CACHE_BUST"}"
if is-main; then
# Just print the paths that we detected
log "Paths:"
log " • USER_CACHES_DIR=[$USER_CACHES_DIR]"
log " • BUILD_CACHE_DIR=[$BUILD_CACHE_DIR]"
log " • BUILD_CACHE_BUST=[$BUILD_CACHE_BUST]"
log " • EXE_SUFFIX=[$EXE_SUFFIX]"
log " • TOOLS_DIR=[$TOOLS_DIR]"
log " • MONGOC_DIR=[$MONGOC_DIR]"
fi
|