Skip to content

Commit ae5b3cd

Browse files
committed
Install pinned dependencies from poetry.lock
If a poetry.lock file is present, use the Poetry CLI to export the pinned requirements to a requirements.txt file. If the project already contains a requirements.txt, use that and ignore poetry.lock. Poetry is not used to install the project because it does not clean up stale requirements. This means that requirements need to be exported anyway, for the `pip-uninstall` step. Since we only use Poetry to export a requirements.txt file, ignore the Poetry version specified in pyproject.toml. Install a pre-release of 1.0.0 because the export command is not available before 1.0.0a0. Note that supporting pyproject.toml-based installations is not enough to handle pinned requirements: When pip installs a pyproject.toml-style project using the process described in PEP 517, it only uses Poetry to build a wheel. The wheel contains the version constraints from pyproject.toml, not the pinned versions from poetry.lock.
1 parent e6fdadd commit ae5b3cd

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

bin/compile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ mtime "python.install.time" "${start}"
254254
# shellcheck source=bin/steps/pipenv
255255
source "$BIN_DIR/steps/pipenv"
256256

257+
# Export requirements.txt from poetry.lock, if present.
258+
# shellcheck source=bin/steps/poetry
259+
source "$BIN_DIR/steps/poetry"
260+
257261
# Uninstall removed dependencies with Pip.
258262
# The buildpack will automatically remove any declared dependencies (in requirements.txt)
259263
# that were explicitly removed. This machinery is a bit complex, but it is not complicated.

bin/steps/poetry

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# shellcheck source=bin/utils
6+
source "$BIN_DIR/utils"
7+
8+
if [ ! -f requirements.txt ] && [ -f pyproject.toml ] && [ -f poetry.lock ]; then
9+
# Measure that we're using Poetry.
10+
mcount "tool.poetry"
11+
12+
# Hash poetry.lock to detect changes.
13+
POETRY_LOCK_SHA=$(openssl dgst -sha256 poetry.lock)
14+
15+
# Use cached requirements.txt if poetry.lock is unchanged.
16+
CACHED_REQUIREMENTS=$CACHE_DIR/requirements.txt
17+
CACHED_POETRY_LOCK_SHA=$CACHE_DIR/poetry.lock.sha256
18+
19+
if [ -f "$CACHED_REQUIREMENTS" ] && [ -f "$CACHED_POETRY_LOCK_SHA" ] &&
20+
[ "$POETRY_LOCK_SHA" == "$(cat "$CACHED_POETRY_LOCK_SHA")" ]; then
21+
echo "Skipping requirements export, as poetry.lock hasn't changed since last deploy." | indent
22+
cp "$CACHED_REQUIREMENTS" requirements.txt
23+
else
24+
# Set environment variables for pip
25+
# This reads certain environment variables set on the Heroku app config
26+
# and makes them accessible to the pip install process.
27+
#
28+
# PIP_EXTRA_INDEX_URL allows for an alternate pypi URL to be used.
29+
if [[ -r "$ENV_DIR/PIP_EXTRA_INDEX_URL" ]]; then
30+
PIP_EXTRA_INDEX_URL="$(cat "$ENV_DIR/PIP_EXTRA_INDEX_URL")"
31+
export PIP_EXTRA_INDEX_URL
32+
mcount "buildvar.PIP_EXTRA_INDEX_URL"
33+
fi
34+
35+
# Set SLUGIFY_USES_TEXT_UNIDECODE, required for Airflow versions >=1.10
36+
if [[ -r "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE" ]]; then
37+
SLUGIFY_USES_TEXT_UNIDECODE="$(cat "$ENV_DIR/SLUGIFY_USES_TEXT_UNIDECODE")"
38+
export SLUGIFY_USES_TEXT_UNIDECODE
39+
mcount "buildvar.SLUGIFY_USES_TEXT_UNIDECODE"
40+
fi
41+
42+
# Install Poetry.
43+
#
44+
# Poetry is not used to install the project because it does not clean up
45+
# stale requirements (see sdispater/poetry#648), so we need to export
46+
# requirements.txt anyway for the pip-uninstall step.
47+
#
48+
# Since we only use Poetry to export a requirements.txt file, ignore the
49+
# Poetry version specified in pyproject.toml. Install a pre-release of
50+
# 1.0.0 because the export command is not available before 1.0.0a0.
51+
export POETRY_VERSION="1.0.0b1"
52+
puts-step "Exporting requirements with Poetry $POETRY_VERSION"
53+
/app/.heroku/python/bin/pip install "poetry==$POETRY_VERSION" \
54+
--disable-pip-version-check &> /dev/null
55+
56+
# Export requirements.
57+
/app/.heroku/python/bin/poetry export -f requirements.txt > requirements.txt
58+
59+
# Write SHA and requirements.txt to cache dir.
60+
echo "$POETRY_LOCK_SHA" > "$CACHED_POETRY_LOCK_SHA"
61+
cp requirements.txt "$CACHED_REQUIREMENTS"
62+
fi
63+
fi

0 commit comments

Comments
 (0)