Skip to content
Snippets Groups Projects
Commit 9b185f99 authored by David Lord's avatar David Lord Committed by Kenneth Reitz
Browse files

use pkg_resources to check for distributions (#395)

more accurate than parsing requirements.txt
fixes #359
parent e8a79bbd
No related branches found
No related tags found
No related merge requests found
# Python Buildpack Changelog # Python Buildpack Changelog
# 104
unreleased
- Use `pkg_resources` to check if a distribution is installed instead of
parsing `requirements.txt`. ([#395][395])
[395]: https://github.com/heroku/heroku-buildpack-python/pull/395
## 103 ## 103
Bug fixes and improvements. Bug fixes and improvements.
......
...@@ -20,7 +20,7 @@ MANAGE_FILE=${MANAGE_FILE:-fakepath} ...@@ -20,7 +20,7 @@ MANAGE_FILE=${MANAGE_FILE:-fakepath}
[ -f .heroku/collectstatic_disabled ] && DISABLE_COLLECTSTATIC=1 [ -f .heroku/collectstatic_disabled ] && DISABLE_COLLECTSTATIC=1
# Ensure that Django is explicitly specified in requirements.txt # Ensure that Django is explicitly specified in requirements.txt
pip-grep -s requirements.txt django Django && DJANGO_INSTALLED=1 pip-grep -s Django && DJANGO_INSTALLED=1
if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALLED" ]; then if [ ! "$DISABLE_COLLECTSTATIC" ] && [ -f "$MANAGE_FILE" ] && [ "$DJANGO_INSTALLED" ]; then
......
...@@ -18,7 +18,7 @@ PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH" ...@@ -18,7 +18,7 @@ PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH"
source $BIN_DIR/utils source $BIN_DIR/utils
# If a package using cffi exists within requirements, use vendored libffi. # If a package using cffi exists within requirements, use vendored libffi.
if (pip-grep -s requirements.txt argon2-cffi bcrypt cffi cryptography django[argon2] Django[argon2] django[bcrypt] Django[bcrypt] PyNaCl pyOpenSSL PyOpenSSL requests[security] misaka &> /dev/null) then if (pip-grep -s argon2-cffi bcrypt cffi cryptography PyNaCl pyOpenSSL PyOpenSSL misaka &> /dev/null) then
if [ ! -d ".heroku/vendor/lib/libffi-3.1" ]; then if [ ! -d ".heroku/vendor/lib/libffi-3.1" ]; then
echo "-----> Noticed cffi. Bootstrapping libffi." echo "-----> Noticed cffi. Bootstrapping libffi."
......
...@@ -18,7 +18,7 @@ PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH" ...@@ -18,7 +18,7 @@ PKG_CONFIG_PATH="/app/.heroku/vendor/lib/pkgconfig:$PKG_CONFIG_PATH"
source $BIN_DIR/utils source $BIN_DIR/utils
# If GDAL exists within requirements, use vendored gdal. # If GDAL exists within requirements, use vendored gdal.
if (pip-grep -s requirements.txt GDAL gdal pygdal &> /dev/null) then if (pip-grep -s GDAL pygdal &> /dev/null) then
if [ ! -f ".heroku/vendor/bin/gdalserver" ]; then if [ ! -f ".heroku/vendor/bin/gdalserver" ]; then
echo "-----> Noticed GDAL. Bootstrapping gdal." echo "-----> Noticed GDAL. Bootstrapping gdal."
......
...@@ -17,7 +17,7 @@ source $BIN_DIR/utils ...@@ -17,7 +17,7 @@ source $BIN_DIR/utils
# If pylibmc exists within requirements, use vendored libmemcached. # If pylibmc exists within requirements, use vendored libmemcached.
if (pip-grep -s requirements.txt pylibmc &> /dev/null) then if (pip-grep -s pylibmc &> /dev/null) then
if [ ! -d ".heroku/vendor/lib/sasl2" ]; then if [ ! -d ".heroku/vendor/lib/sasl2" ]; then
echo "-----> Noticed pylibmc. Bootstrapping libmemcached." echo "-----> Noticed pylibmc. Bootstrapping libmemcached."
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Syntax sugar. # Syntax sugar.
source $BIN_DIR/utils source $BIN_DIR/utils
if (pip-grep -s requirements.txt setuptools distribute &> /dev/null) then if (pip-grep -s setuptools distribute &> /dev/null) then
puts-warn 'The package setuptools/distribute is listed in requirements.txt.' puts-warn 'The package setuptools/distribute is listed in requirements.txt.'
puts-warn 'Please remove to ensure expected behavior. ' puts-warn 'Please remove to ensure expected behavior. '
......
...@@ -2,58 +2,26 @@ ...@@ -2,58 +2,26 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Usage: """Usage:
pip-grep [-s] <reqfile> <package>... pip-grep [-s] <package>...
Options: Options:
-h --help Show this screen. -h --help Show this screen.
""" """
import os
from docopt import docopt from docopt import docopt
from pip.req import parse_requirements from pkg_resources import DistributionNotFound, get_distribution
from pip.index import PackageFinder
from pip._vendor.requests import session
requests = session()
def has_any_distribution(names, silent=False):
for name in names:
try:
get_distribution(name)
except DistributionNotFound:
continue
class Requirements(object):
def __init__(self, reqfile=None):
super(Requirements, self).__init__()
self.path = reqfile
self.requirements = []
if reqfile:
self.load(reqfile)
def __repr__(self):
return '<Requirements \'{}\'>'.format(self.path)
def load(self, reqfile):
if not os.path.exists(reqfile):
raise ValueError('The given requirements file does not exist.')
finder = PackageFinder([], [], session=requests)
for requirement in parse_requirements(reqfile, finder=finder, session=requests):
if requirement.req:
if not getattr(requirement.req, 'name', None):
# Prior to pip 8.1.2 the attribute `name` did not exist.
requirement.req.name = requirement.req.project_name
self.requirements.append(requirement.req)
def grep(reqfile, packages, silent=False):
try:
r = Requirements(reqfile)
except ValueError:
if not silent: if not silent:
print('There was a problem loading the given requirement file.') print('Package {name} found!'.format(name=name))
exit(os.EX_NOINPUT)
for req in r.requirements: exit(0)
if req.name in packages:
if not silent:
print('Package {} found!'.format(req.name))
exit(0)
if not silent: if not silent:
print('Not found.') print('Not found.')
...@@ -63,10 +31,7 @@ def grep(reqfile, packages, silent=False): ...@@ -63,10 +31,7 @@ def grep(reqfile, packages, silent=False):
def main(): def main():
args = docopt(__doc__, version='pip-grep') args = docopt(__doc__, version='pip-grep')
has_any_distribution(names=args['<package>'], silent=args['-s'])
kwargs = {'reqfile': args['<reqfile>'], 'packages': args['<package>'], 'silent': args['-s']}
grep(**kwargs)
if __name__ == '__main__': if __name__ == '__main__':
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment