Skip to content

Commit

Permalink
Add tests for Pipenv local editable dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
edmorley committed Jan 4, 2024
1 parent d1ca05a commit a8f6147
Show file tree
Hide file tree
Showing 19 changed files with 271 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ name: CI
on:
push:
# Avoid duplicate builds on PRs.
branches:
- main
# branches:
# - main
pull_request:

permissions:
Expand Down
9 changes: 9 additions & 0 deletions spec/fixtures/pipenv_editable/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
local-package-pyproject-toml = {file = "packages/local_package_pyproject_toml", editable = false}
local-package-setup-py = {file = "packages/local_package_setup_py", editable = true}
gunicorn = {git = "git+https://github.com/benoitc/gunicorn", ref = "20.1.0", editable = true}
41 changes: 41 additions & 0 deletions spec/fixtures/pipenv_editable/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions spec/fixtures/pipenv_editable/bin/compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash

# This file is run by the inline buildpack, and tests that editable requirements are
# usable by buildpacks that run after the Python buildpack during the build.

set -euo pipefail

BUILD_DIR="${1}"

cd "${BUILD_DIR}"

exec bin/test-entrypoints
7 changes: 7 additions & 0 deletions spec/fixtures/pipenv_editable/bin/detect
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

# This file is run by the inline buildpack.

set -euo pipefail

echo "Inline"
5 changes: 5 additions & 0 deletions spec/fixtures/pipenv_editable/bin/post_compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -euo pipefail

exec bin/test-entrypoints
16 changes: 16 additions & 0 deletions spec/fixtures/pipenv_editable/bin/test-entrypoints
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

set -euo pipefail

# List the filenames and contents of all .egg-link, .pth, and finder files in site-packages.
find .heroku/python/lib/python*/site-packages/ -type f -and \( -name '*.egg-link' -or -name '*.pth' -or -name '__editable___*_finder.py' \) | sort | xargs -exec tail -n +1
echo

echo -n "Running entrypoint for the pyproject.toml-based local package: "
local_package_pyproject_toml

echo -n "Running entrypoint for the setup.py-based local package: "
local_package_setup_py

echo -n "Running entrypoint for the VCS package: "
gunicorn --version
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Metadata-Version: 2.1
Name: local_package_pyproject_toml
Version: 0.0.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pyproject.toml
local_package_pyproject_toml/__init__.py
local_package_pyproject_toml.egg-info/PKG-INFO
local_package_pyproject_toml.egg-info/SOURCES.txt
local_package_pyproject_toml.egg-info/dependency_links.txt
local_package_pyproject_toml.egg-info/entry_points.txt
local_package_pyproject_toml.egg-info/top_level.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[console_scripts]
local_package_pyproject_toml = local_package_pyproject_toml:hello
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
local_package_pyproject_toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def hello():
print("Hello pyproject.toml!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[project]
name = "local_package_pyproject_toml"
version = "0.0.1"

[project.scripts]
local_package_pyproject_toml = "local_package_pyproject_toml:hello"
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def hello():
print("Hello setup.py!")
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[metadata]
name = local_package_setup_py
version = 0.0.1

[options]
packages = local_package_setup_py

[options.entry_points]
console_scripts =
local_package_setup_py = local_package_setup_py:hello
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from setuptools import setup

setup()
2 changes: 1 addition & 1 deletion spec/fixtures/requirements_editable/bin/test-entrypoints
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -euo pipefail

# List the filenames and contents of all .egg-link, .pth, and finder files in site-packages.
find .heroku/python/lib*/*/site-packages/ -type f -and \( -name '*.egg-link' -or -name '*.pth' -or -name '__editable___*_finder.py' \) | sort | xargs -exec tail -n +1
find .heroku/python/lib/python*/site-packages/ -type f -and \( -name '*.egg-link' -or -name '*.pth' -or -name '__editable___*_finder.py' \) | sort | xargs -exec tail -n +1
echo

echo -n "Running entrypoint for the pyproject.toml-based local package: "
Expand Down
141 changes: 141 additions & 0 deletions spec/hatchet/pipenv_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,145 @@
end
end
end

context 'when Pipfile contains editable requirements' do
let(:buildpacks) { [:default, 'heroku-community/inline'] }
let(:app) { Hatchet::Runner.new('spec/fixtures/pipenv_editable', buildpacks:) }

it 'rewrites .pth, .egg-link and finder paths correctly for hooks, later buildpacks, runtime and cached builds' do
app.deploy do |app|
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX, Regexp::MULTILINE))
remote: -----> Running post-compile hook
remote: ==> .heroku/python/lib/python.*/site-packages/distutils-precedence.pth <==
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/easy-install.pth <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: /tmp/build_.*/src/gunicorn
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable___local_package_pyproject_toml_0_0_1_finder.py <==
remote: .*
remote: MAPPING = \\{'local_package_pyproject_toml': '/tmp/build_.*/packages/local_package_pyproject_toml/local_package_pyproject_toml'\\}
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable__.local_package_pyproject_toml-0.0.1.pth <==
remote: import __editable___.*
remote: ==> .heroku/python/lib/python.*/site-packages/gunicorn.egg-link <==
remote: /tmp/build_.*/src/gunicorn
remote: .
remote: ==> .heroku/python/lib/python.*/site-packages/local-package-setup-py.egg-link <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: .
remote: Running entrypoint for the pyproject.toml-based local package: Hello pyproject.toml!
remote: Running entrypoint for the setup.py-based local package: Hello setup.py!
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
remote: -----> Inline app detected
remote: ==> .heroku/python/lib/python.*/site-packages/distutils-precedence.pth <==
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/easy-install.pth <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: /tmp/build_.*/src/gunicorn
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable___local_package_pyproject_toml_0_0_1_finder.py <==
remote: .*
remote: MAPPING = \\{'local_package_pyproject_toml': '/tmp/build_.*/packages/local_package_pyproject_toml/local_package_pyproject_toml'\\}
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable__.local_package_pyproject_toml-0.0.1.pth <==
remote: import __editable___.*
remote: ==> .heroku/python/lib/python.*/site-packages/gunicorn.egg-link <==
remote: /tmp/build_.*/gunicorn
remote: .
remote: ==> .heroku/python/lib/python.*/site-packages/local-package-setup-py.egg-link <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: .
remote: Running entrypoint for the pyproject.toml-based local package: Hello pyproject.toml!
remote: Running entrypoint for the setup.py-based local package: Hello setup.py!
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
REGEX

# Test rewritten paths work at runtime.
expect(app.run('bin/test-entrypoints')).to match(Regexp.new(<<~REGEX, Regexp::MULTILINE))
==> .heroku/python/lib/python.*/site-packages/distutils-precedence.pth <==
.*
==> .heroku/python/lib/python.*/site-packages/easy-install.pth <==
/app/packages/local_package_setup_py
/app/src/gunicorn
==> .heroku/python/lib/python.*/site-packages/__editable___local_package_pyproject_toml_0_0_1_finder.py <==
.*
MAPPING = \\{'local_package_pyproject_toml': '/app/packages/local_package_pyproject_toml/local_package_pyproject_toml'\\}
.*
==> .heroku/python/lib/python.*/site-packages/__editable__.local_package_pyproject_toml-0.0.1.pth <==
import __editable___.*
==> .heroku/python/lib/python.*/site-packages/gunicorn.egg-link <==
/app/src/gunicorn
.
==> .heroku/python/lib/python.*/site-packages/local-package-setup-py.egg-link <==
/app/packages/local_package_setup_py
.
Running entrypoint for the pyproject.toml-based local package: Hello pyproject.toml!
Running entrypoint for the setup.py-based local package: Hello setup.py!
Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
REGEX

# Test that the cached .pth files work correctly.
app.commit!
app.push!
expect(clean_output(app.output)).to match(Regexp.new(<<~REGEX, Regexp::MULTILINE))
remote: -----> Running post-compile hook
remote: ==> .heroku/python/lib/python.*/site-packages/distutils-precedence.pth <==
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/easy-install.pth <==
remote: /tmp/build_.*/src/gunicorn
remote: /tmp/build_.*/packages/local_package_setup_py
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable___local_package_pyproject_toml_0_0_1_finder.py <==
remote: .*
remote: MAPPING = \\{'local_package_pyproject_toml': '/tmp/build_.*/packages/local_package_pyproject_toml/local_package_pyproject_toml'\\}
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable__.local_package_pyproject_toml-0.0.1.pth <==
remote: import __editable___.*
remote: ==> .heroku/python/lib/python.*/site-packages/gunicorn.egg-link <==
remote: /tmp/build_.*/src/gunicorn
remote: .
remote: ==> .heroku/python/lib/python.*/site-packages/local-package-setup-py.egg-link <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: .
remote: Running entrypoint for the pyproject.toml-based local package: Hello pyproject.toml!
remote: Running entrypoint for the setup.py-based local package: Hello setup.py!
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
remote: -----> Inline app detected
remote: ==> .heroku/python/lib/python.*/site-packages/distutils-precedence.pth <==
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/easy-install.pth <==
remote: /tmp/build_.*/src/gunicorn
remote: /tmp/build_.*/packages/local_package_setup_py
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable___local_package_pyproject_toml_0_0_1_finder.py <==
remote: .*
remote: MAPPING = \\{'local_package_pyproject_toml': '/tmp/build_.*/packages/local_package_pyproject_toml/local_package_pyproject_toml'\\}
remote: .*
remote:
remote: ==> .heroku/python/lib/python.*/site-packages/__editable__.local_package_pyproject_toml-0.0.1.pth <==
remote: import __editable___.*
remote: ==> .heroku/python/lib/python.*/site-packages/gunicorn.egg-link <==
remote: /tmp/build_.*/src/gunicorn
remote: .
remote: ==> .heroku/python/lib/python.*/site-packages/local-package-setup-py.egg-link <==
remote: /tmp/build_.*/packages/local_package_setup_py
remote: .
remote: Running entrypoint for the pyproject.toml-based local package: Hello pyproject.toml!
remote: Running entrypoint for the setup.py-based local package: Hello setup.py!
remote: Running entrypoint for the VCS package: gunicorn \\(version 20.1.0\\)
REGEX
end
end
end
end

0 comments on commit a8f6147

Please sign in to comment.