This repository has been archived by the owner on Mar 29, 2023. It is now read-only.
forked from mikepack/heroku-buildpack-freetds
-
Notifications
You must be signed in to change notification settings - Fork 3
/
compile
executable file
·197 lines (164 loc) · 6.94 KB
/
compile
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/bin/bash
#
# Usage:
# bin/compile BUILD_DIR CACHE_DIR ENV_DIR
# Example
# BUILD_DIR is /tmp/build_5b72bfcaef1adfe4bb7a9e34d80201fc
# CACHE_DIR is app
# The contents of CACHE_DIR will be persisted between builds.
set -eou pipefail
IFS=$'\n\t'
unset CDPATH
# Always log finish, bash pseudo-signal: EXIT
# Usage:
# trap finish EXIT
finish() {
echo " END Running script: ${0##*/}"
}
# Log errors, if any, bash pseudo-signal: ERR
# Usage:
# trap 'finish_error $LINENO' ERR
finish_error() {
errcode=$?
echo " END ERROR Running script: ${0##*/}:$1: exited with '${errcode}'."
}
trap 'finish' EXIT
trap 'finish_error $LINENO' ERR
# Influenced by https://dev.to/thiht/shell-scripts-matter
# And see https://github.com/bf4/Notes/wiki/Shell-Scripting
logstamp() { printf "[%s]" "$(TZ='America/Chicago' date +'%Y-%m-%d %H:%M:%S')" ; }
topic() { echo "-----> $(logstamp) $*" ; }
info() { echo " $*" ; }
indent() { sed -u 's/^/ /' ; } # it always runs on linux. on darwin is 'sed -l'
BUILD_DIR="$1"
CACHE_DIR="$2"
mkdir -p "$BUILD_DIR" "$CACHE_DIR"
# shellcheck disable=SC2034
ENV_DIR="${3}"
# echo "$STACK"
# echo "$SOURCE_VERSION"
# See https://devcenter.heroku.com/articles/buildpack-api#bin-compile-summary
BIN_DIR="$(cd "$(dirname "$0")"; pwd)" # absolute path
LP_DIR="$(cd "$(dirname "$0")"; cd ..; pwd)"
ROOT_DIR="$(dirname "$BIN_DIR")"
info "BIN_DIR=${BIN_DIR}, ROOT_DIR=${ROOT_DIR}, BUILD_DIR=${BUILD_DIR}, CACHE_DIR=${CACHE_DIR}, pwd=$(pwd)"
load_env_vars() {
local env_var; env_var="${1:-}"
until [ -z "$env_var" ]; do [ -f "$ENV_DIR/$env_var" ] && export "$env_var=$(cat "$ENV_DIR/$env_var")"; shift ; env_var="${1:-}" ; done
}
load_env_vars "FREETDS_VERSION" "FREETDS_ARCHIVE_NAME" "TDS_VERSION" "FREETDS_REBUILD"
FREETDS_VERSION="${FREETDS_VERSION:-1.00.109}"
FREETDS_ARCHIVE_NAME="${FREETDS_ARCHIVE_NAME:-freetds-${FREETDS_VERSION}}"
TDS_VERSION="${TDS_VERSION:-7.3}" # or TDSVER
CACHED_TAR="${CACHE_DIR}/freetds-${FREETDS_VERSION}-heroku.tar.bz2"
# Default rebuild to true since I'm having issues linking the library to tiny_tds gem with a cached build.
if [ "${FREETDS_REBUILD:-}" = "true" ]; then
rm -f "$CACHED_TAR"
fi
# This installation target is in the BUILD_DIR, which means that
# it'll end up in the slug at runtime.
BUILD_TARGET_DIR="${BUILD_DIR}/freetds"
mkdir -p "${BUILD_TARGET_DIR}"
# This is the path that will be used at dyno runtime, and in which we build.
APP_TARGET_DIR="/app/freetds"
mkdir -p "${APP_TARGET_DIR}"
configure_app_env_vars() {
topic "Creating .profile.d entry"
mkdir -p "${BUILD_DIR}/.profile.d"
# These exports must point to /app, because the profile is
# executed in a running dyno, not the buildpack environment
cat <<EOF > "${BUILD_DIR}/.profile.d/freetds.sh"
export PATH="${APP_TARGET_DIR}/bin:$PATH"
# tiny_tds extconf.rb uses FREETDS_DIR
# https://github.com/rails-sqlserver/tiny_tds/blob/5046755ca91594003f8b3ca541d136f3ed859973/ext/tiny_tds/extconf.rb#L36-L38
export FREETDS_DIR="${APP_TARGET_DIR}"
export LD_LIBRARY_PATH="${APP_TARGET_DIR}/lib:${LD_LIBRARY_PATH:-/usr/local/lib}"
export LD_RUN_PATH="${APP_TARGET_DIR}/lib:${LD_RUN_PATH:-/usr/local/lib}"
export LIBRARY_PATH="${APP_TARGET_DIR}/lib:${LIBRARY_PATH:-/usr/local/lib}"
export SYBASE="${APP_TARGET_DIR}"
EOF
chmod +x "${BUILD_DIR}/.profile.d/freetds.sh"
echo "configured APP env vars:" | indent
indent < "${BUILD_DIR}/.profile.d/freetds.sh"
# shellcheck disable=SC1090
. "${BUILD_DIR}/.profile.d/freetds.sh"
}
configure_buildpack_env_vars() {
# These exports point to the build directory, not to /app, so that
# they work for later buildpacks.
export PATH="${BUILD_TARGET_DIR}/bin:$PATH"
export FREETDS_DIR="${BUILD_TARGET_DIR}"
export LD_LIBRARY_PATH="${BUILD_TARGET_DIR}/lib:${LD_LIBRARY_PATH:-/usr/local/lib}"
export LD_RUN_PATH="${BUILD_TARGET_DIR}/lib:${LD_RUN_PATH:-/usr/local/lib}"
export LIBRARY_PATH="${BUILD_TARGET_DIR}/lib:${LIBRARY_PATH:-/usr/local/lib}"
export SYBASE="${APP_TARGET_DIR}"
# give environment to later buildpacks
export | grep -E -e ' (PATH|LD_LIBRARY_PATH|LIBRARY_PATH|FREETDS_DIR|SYBASE)=' > "${LP_DIR}/export"
echo "configured BUILDPACK env vars:" | indent
indent < "${LP_DIR}/export"
}
download_and_extract_freetds_archive() {
FREETDS_FILE="$FREETDS_ARCHIVE_NAME.tar.gz"
FREETDS_URL="https://www.freetds.org/files/stable/${FREETDS_FILE}"
# TODO(BF): Print log when HEROKUR_FREETDS_BUILDPACK_DEBUG is set
# TODO(BF): Consider calculating and verifying SHA256: openssl dgst -sha256 < "$FREETDS_FILE"
curl -s "$FREETDS_URL" | tar xzvf - -C "${BUILD_DIR}" > "${BUILD_DIR}/build_log-unpack.log" # Can't write to the archive dir until it exists
mv "${BUILD_DIR}/build_log-unpack.log" "${BUILD_DIR}/${FREETDS_ARCHIVE_NAME}/"
}
build_and_install_freetds() {
topic "Building FreeTDS against OpenSSL $(openssl version)"
( # directory changes in subshells have no effect
cd "${BUILD_DIR}/${FREETDS_ARCHIVE_NAME}"
# We must build at /app/... rather than in the BUILD_DIR because
# the installation hardwires some paths and symlinks. In order for
# these to be in the right location at dyno runtime, we have to
# build using the same path that applies at dyno runtime.
# FreeTDS advises caching the build options as below
# adding --disable-odbc making linking easier and we don't need it
# adding --disable-debug to speed up compile
cat <<EOF > ".build_options"
./configure \
"--prefix=${APP_TARGET_DIR}" \
--disable-odbc \
--disable-debug \
"--with-tdsver=${TDS_VERSION}"
EOF
# TODO(BF): Print log when HEROKUR_FREETDS_BUILDPACK_DEBUG is set
/bin/bash .build_options > build_log-configure.stdout.log 2> build_log-configure.stderr.log
# Flush make output to log since a file will be faster than printing to the screen.
# TODO(BF): Print log when HEROKUR_FREETDS_BUILDPACK_DEBUG is set
{
make && make install && make clean
} > build_log-make_install.stdout.log 2> build_log-make_install.stderr.log
cp .build_options build_log-* "${APP_TARGET_DIR}/"
cd "$BUILD_DIR"
# shellcheck disable=SC2115
rm -rf "${BUILD_DIR}/${FREETDS_ARCHIVE_NAME}"
)
}
cache_build_artifacts_for_future_deploys() {
topic "Caching FreeTDS installation"
( # directory changes in subshells have no effect
cd "${APP_TARGET_DIR}"
# TODO(BF): Consider removing the documentation before tarring
# rm -rf share
tar cjf "${CACHED_TAR}" . | indent
)
}
main() {
topic "FreeTDS ${FREETDS_VERSION} building in ${BUILD_DIR}"
configure_app_env_vars
if [ ! -f "$CACHED_TAR" ]; then
info "Cached files not found - downloading and unpacking..."
download_and_extract_freetds_archive
build_and_install_freetds
topic "Testing build"
"$APP_TARGET_DIR/bin/tsql" -C | indent
cache_build_artifacts_for_future_deploys
fi
info "Unpacking cached files..."
tar xjf "${CACHED_TAR}" -C "${BUILD_TARGET_DIR}" | indent
configure_buildpack_env_vars
info "Install of FreeTDS ${FREETDS_VERSION} complete"
}
main