Skip to content

Commit 0fe4f91

Browse files
authored
Merge pull request #713 from hone/sqlite3
Update SQLite3
2 parents f7e5930 + 221722f commit 0fe4f91

File tree

7 files changed

+173
-4
lines changed

7 files changed

+173
-4
lines changed

bin/compile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ cp -R "$CACHE_DIR/.heroku/python" .heroku/ &> /dev/null || true
160160
cp -R "$CACHE_DIR/.heroku/python-stack" .heroku/ &> /dev/null || true
161161
# A plain text file which contains the current python version being used (used for cache busting).
162162
cp -R "$CACHE_DIR/.heroku/python-version" .heroku/ &> /dev/null || true
163+
# A plain text file which contains the current sqlite3 version being used (used for cache busting).
164+
cp -R "$CACHE_DIR/.heroku/python-sqlite3-version" .heroku/ &> /dev/null || true
163165
# Any pre-compiled binaries, provided by the buildpack.
164166
cp -R "$CACHE_DIR/.heroku/vendor" .heroku/ &> /dev/null || true
165167
# "editable" installations of code repositories, via pip or pipenv.
@@ -274,6 +276,16 @@ sub_env "$BIN_DIR/steps/geo-libs"
274276
# shellcheck source=bin/steps/gdal
275277
source "$BIN_DIR/steps/gdal"
276278

279+
# SQLite3 support.
280+
# This sets up and installs sqlite3 dev headers and the sqlite3 binary but not the
281+
# libsqlite3-0 library since that exists on the stack image.
282+
# Note: This only applies to Python 2.7.15+ and Python 3.6.6+
283+
(( start=$(nowms) ))
284+
# shellcheck source=bin/steps/sqlite3
285+
source "$BIN_DIR/steps/sqlite3"
286+
buildpack_sqlite3_install
287+
mtime "sqlite3.install.time" "${start}"
288+
277289
# pip install
278290
# -----------
279291

bin/steps/python

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,15 @@ fi
2929

3030
if [[ "$STACK" != "$CACHED_PYTHON_STACK" ]]; then
3131
puts-step "Stack has changed from $CACHED_PYTHON_STACK to $STACK, clearing cache"
32-
rm -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor
32+
rm -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor .heroku/python .heroku/python-sqlite3-version
33+
fi
34+
35+
# need to clear the cache for first time installing SQLite3,
36+
# since the version is changing and could lead to runtime errors
37+
# with compiled extensions.
38+
if [ -d .heroku/python ] && [ ! -f .heroku/python-sqlite3-version ] && python_sqlite3_check "$PYTHON_VERSION"; then
39+
puts-step "Need to update SQLite3, clearing cache"
40+
rm -fr .heroku/python-stack .heroku/python-version .heroku/python .heroku/vendor
3341
fi
3442

3543
if [ -f .heroku/python-version ]; then

bin/steps/sqlite3

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env bash
2+
3+
# shellcheck source=bin/utils
4+
source "$BIN_DIR/utils"
5+
6+
sqlite3_version() {
7+
SQLITE3_VERSION=${SQLITE3_VERSION:-$(dpkg -s libsqlite3-0 | grep Version | sed 's/Version: //')}
8+
9+
export SQLITE3_VERSION
10+
}
11+
12+
sqlite3_install() {
13+
HEROKU_PYTHON_DIR="$1"
14+
SQLITE3_VERSION="$2"
15+
HEADERS_ONLY="$3"
16+
17+
mkdir -p "$HEROKU_PYTHON_DIR"
18+
19+
APT_CACHE_DIR="$HEROKU_PYTHON_DIR/apt/cache"
20+
APT_STATE_DIR="$HEROKU_PYTHON_DIR/apt/state"
21+
22+
mkdir -p "$APT_CACHE_DIR/archives/partial"
23+
mkdir -p "$APT_STATE_DIR/lists/partial"
24+
25+
APT_OPTIONS="-o debug::nolocking=true"
26+
APT_OPTIONS="$APT_OPTIONS -o dir::cache=$APT_CACHE_DIR"
27+
APT_OPTIONS="$APT_OPTIONS -o dir::state=$APT_STATE_DIR"
28+
APT_OPTIONS="$APT_OPTIONS -o dir::etc::sourcelist=/etc/apt/sources.list"
29+
30+
apt-get $APT_OPTIONS update > /dev/null 2>&1
31+
if [ -z "$HEADERS_ONLY" ]; then
32+
apt-get $APT_OPTIONS -y -d --reinstall install libsqlite3-dev="$SQLITE3_VERSION" sqlite3="$SQLITE3_VERSION" > /dev/null 2>&1
33+
else
34+
apt-get $APT_OPTIONS -y -d --reinstall install libsqlite3-dev="$SQLITE3_VERSION"
35+
fi
36+
37+
find "$APT_CACHE_DIR/archives/" -name "*.deb" -exec dpkg -x {} "$HEROKU_PYTHON_DIR/sqlite3/" \;
38+
39+
mkdir -p "$HEROKU_PYTHON_DIR/include"
40+
mkdir -p "$HEROKU_PYTHON_DIR/lib"
41+
42+
# remove old sqlite3 libraries/binaries
43+
find "$HEROKU_PYTHON_DIR/include/" -name "sqlite3*.h" -exec rm -f {} \;
44+
find "$HEROKU_PYTHON_DIR/lib/" -name "libsqlite3.*" -exec rm -f {} \;
45+
rm -f "$HEROKU_PYTHON_DIR/lib/pkgconfig/sqlite3.pc"
46+
rm -f "$HEROKU_PYTHON_DIR/bin/sqlite3"
47+
48+
# copy over sqlite3 headers & bins and setup linking against the stack image library
49+
mv "$HEROKU_PYTHON_DIR/sqlite3/usr/include/"* "$HEROKU_PYTHON_DIR/include/"
50+
mv "$HEROKU_PYTHON_DIR/sqlite3/usr/lib/x86_64-linux-gnu"/libsqlite3.*a "$HEROKU_PYTHON_DIR/lib/"
51+
mkdir -p "$HEROKU_PYTHON_DIR/lib/pkgconfig"
52+
# set the right prefix/lib directories
53+
sed -e 's/prefix=\/usr/prefix=\/app\/.heroku\/python/' -e 's/\/x86_64-linux-gnu//' "$HEROKU_PYTHON_DIR/sqlite3/usr/lib/x86_64-linux-gnu/pkgconfig/sqlite3.pc" > "$HEROKU_PYTHON_DIR/lib/pkgconfig/sqlite3.pc"
54+
# need to point the libsqlite3.so to the stack image library for /usr/bin/ld -lsqlite3
55+
SQLITE3_LIBFILE="/usr/lib/x86_64-linux-gnu/$(readlink -n "$HEROKU_PYTHON_DIR/sqlite3/usr/lib/x86_64-linux-gnu/libsqlite3.so")"
56+
ln -s "$SQLITE3_LIBFILE" "$HEROKU_PYTHON_DIR/lib/libsqlite3.so"
57+
if [ -z "$HEADERS_ONLY" ]; then
58+
mv "$HEROKU_PYTHON_DIR/sqlite3/usr/bin"/* "$HEROKU_PYTHON_DIR/bin/"
59+
fi
60+
61+
# cleanup
62+
rm -rf "$HEROKU_PYTHON_DIR/sqlite3/"
63+
rm -rf "$HEROKU_PYTHON_DIR/apt/"
64+
}
65+
66+
buildpack_sqlite3_install() {
67+
sqlite3_version
68+
HEROKU_PYTHON_DIR="$BUILD_DIR/.heroku/python"
69+
70+
SQLITE3_VERSION_FILE="$BUILD_DIR/.heroku/python-sqlite3-version"
71+
if [ -f "$SQLITE3_VERSION_FILE" ]; then
72+
INSTALLED_SQLITE3_VERSION=$(cat "$SQLITE3_VERSION_FILE")
73+
fi
74+
75+
# python version check
76+
if python_sqlite3_check "$PYTHON_VERSION"; then
77+
# only install if the sqlite3 version has changed
78+
if [ "$INSTALLED_SQLITE3_VERSION" != "$SQLITE3_VERSION" ]; then
79+
puts-step "Installing SQLite3"
80+
sqlite3_install "$BUILD_DIR/.heroku/python" "$SQLITE3_VERSION"
81+
82+
# save version installed
83+
mkdir -p "$CACHE_DIR/.heroku/"
84+
echo "$SQLITE3_VERSION" > "$CACHE_DIR/.heroku/python-sqlite3-version"
85+
fi
86+
fi
87+
}

bin/utils

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,41 @@ measure-size() {
5858
echo "$(du -s .heroku/python 2>/dev/null || echo 0) | awk '{print $1}')"
5959
}
6060

61+
# Python version operator >
62+
version_gt() {
63+
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1";
64+
}
65+
66+
# Python verison operator >=
67+
version_gte() {
68+
if [ "$1" == "$2" ]; then
69+
return 0
70+
fi
71+
72+
version_gt "$1" "$2"
73+
}
74+
75+
# Check if Python 2
76+
python2_check() {
77+
VERSION="$1"
78+
79+
version_gte "$VERSION" "python-2.7.0" && version_gt "python-3.0.0" "$VERSION"
80+
}
81+
82+
# Check if Python 3
83+
python3_check() {
84+
VERSION="$1"
85+
86+
version_gte "$VERSION" "python-3.0.0" && version_gt "python-4.0.0" "$VERSION"
87+
}
88+
89+
# Check if Python version needs to install SQLite3
90+
python_sqlite3_check() {
91+
VERSION="$1"
92+
MIN_PYTHON_3="python-3.6.6"
93+
MIN_PYTHON_2="python-2.7.15"
94+
95+
( python2_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_2" ) \
96+
|| ( python3_check "$VERSION" && version_gte "$VERSION" "$MIN_PYTHON_3" ) \
97+
|| ( version_gte "$VERSION" "3.7.0" )
98+
}

builds/runtimes/python-2.7.15

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#!/usr/bin/env bash
22
# Build Path: /app/.heroku/python/
3-
# Build Deps: libraries/sqlite
43

54
OUT_PREFIX=$1
5+
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
6+
export BIN_DIR
7+
8+
# shellcheck source=bin/utils
9+
source "$BIN_DIR/steps/sqlite3"
10+
11+
sqlite3_version
12+
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
13+
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
614

715
echo "Building Python…"
816
SOURCE_TARBALL='https://python.org/ftp/python/2.7.15/Python-2.7.15.tgz'

builds/runtimes/python-3.6.6

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#!/usr/bin/env bash
22
# Build Path: /app/.heroku/python/
3-
# Build Deps: libraries/sqlite
43

54
OUT_PREFIX=$1
5+
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
6+
export BIN_DIR
7+
8+
# shellcheck source=bin/utils
9+
source "$BIN_DIR/steps/sqlite3"
10+
11+
sqlite3_version
12+
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
13+
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
614

715
echo "Building Python…"
816
SOURCE_TARBALL='https://python.org/ftp/python/3.6.6/Python-3.6.6.tgz'

builds/runtimes/python-3.7.0

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
#!/usr/bin/env bash
22
# Build Path: /app/.heroku/python/
3-
# Build Deps: libraries/sqlite
43

54
OUT_PREFIX=$1
5+
BIN_DIR="$(cd "$(dirname "$0")"/../.. || exit; pwd)/bin"
6+
export BIN_DIR
7+
8+
# shellcheck source=bin/utils
9+
source "$BIN_DIR/steps/sqlite3"
10+
11+
sqlite3_version
12+
echo "Setting up SQLite3 Headers for $SQLITE3_VERSION"
13+
sqlite3_install "$OUT_PREFIX" "$SQLITE3_VERSION" 1
614

715
echo "Building Python…"
816
SOURCE_TARBALL='https://python.org/ftp/python/3.7.0/Python-3.7.0.tgz'

0 commit comments

Comments
 (0)