Merge pull request #328 from kennethreitz/requirements

pipfile importing (work in progress)
This commit is contained in:
2017-04-26 15:40:56 -04:00
committed by GitHub
4 changed files with 95 additions and 6 deletions
+2
View File
@@ -1,3 +1,5 @@
3.6.1:
- pipenv install now works if only a requirements.txt is present.
3.6.0:
- Make --two/--three handling more consistent.
- Update vendored delegator.py.
+30 -5
View File
@@ -38,6 +38,9 @@ else:
# |_| |_|| _/|___>|_|_||__/
# |_|
# Packages that should be ignored later.
BAD_PACKAGES = ['setuptools', 'pip', 'wheel', 'six', 'packaging', 'pyparsing', 'appdirs']
# Enable shell completion.
click_completion.init()
@@ -90,10 +93,33 @@ def ensure_pipfile(validate=True):
# Assert Pipfile exists.
if not project.pipfile_exists:
click.echo(crayons.yellow('Creating a Pipfile for this project...'), err=True)
# If there's a requirements file, but no Pipfile...
if project.requirements_exists:
click.echo(crayons.yellow('Requirements file found, instead of Pipfile! Converting...'))
# Create a Pipfile...
project.create_pipfile()
# Create the pipfile if it doesn't exist.
project.create_pipfile()
click.echo(crayons.yellow('Installing dependencies from \'requirements.txt\'...'))
# Install everything from the requirements.txt.
delegator.run('{0} install -r {1}'.format(which('pip'), project.requirements_location))
installed = delegator.run('{0} freeze'.format(which('pip'))).out.split('\n')
# Remove setuptools and friends from installed, if present.
for package_name in BAD_PACKAGES:
for i, package in enumerate(installed):
if package.startswith(package_name):
del installed[i]
for package in installed:
if package:
project.add_package_to_pipfile(package)
else:
click.echo(crayons.yellow('Creating a Pipfile for this project...'), err=True)
# Create the pipfile if it doesn't exist.
project.create_pipfile()
# Validate the Pipfile's contents.
if validate and project.virtualenv_exists:
@@ -530,7 +556,6 @@ def do_activate_virtualenv(bare=False):
else:
click.echo(activate_virtualenv())
def do_purge(bare=False, downloads=False, allow_global=False):
"""Executes the purge functionality."""
@@ -544,7 +569,7 @@ def do_purge(bare=False, downloads=False, allow_global=False):
installed = freeze.split()
# Remove setuptools and friends from installed, if present.
for package_name in ['setuptools', 'pip', 'wheel', 'six', 'packaging', 'pyparsing', 'appdirs']:
for package_name in BAD_PACKAGES:
for i, package in enumerate(installed):
if package.startswith(package_name):
del installed[i]
+17 -1
View File
@@ -12,7 +12,7 @@ import delegator
from requests.compat import OrderedDict
from .utils import (format_toml, mkdir_p, convert_deps_from_pip,
pep423_name, recase_file)
pep423_name, recase_file, find_requirements)
from .environments import PIPENV_MAX_DEPTH, PIPENV_VENV_IN_PROJECT
@@ -25,6 +25,7 @@ class Project(object):
self._download_location = None
self._proper_names_location = None
self._pipfile_location = None
self._requirements_location = None
@property
def name(self):
@@ -36,6 +37,10 @@ class Project(object):
def pipfile_exists(self):
return bool(self.pipfile_location)
@property
def requirements_exists(self):
return bool(self.requirements_location)
@property
def virtualenv_exists(self):
# TODO: Decouple project from existence of Pipfile.
@@ -128,6 +133,17 @@ class Project(object):
return self._pipfile_location
@property
def requirements_location(self):
if self._requirements_location is None:
try:
loc = find_requirements(max_depth=PIPENV_MAX_DEPTH)
except RuntimeError:
loc = None
self._requirements_location = loc
return self._requirements_location
@property
def parsed_pipfile(self):
with open(self.pipfile_location) as f:
+46
View File
@@ -235,3 +235,49 @@ def recase_file(file_dict):
file_section[cased_key] = file_section.pop(key)
return file_dict
def walk_up(bottom):
"""mimic os.walk, but walk 'up' instead of down the directory tree.
From: https://gist.github.com/zdavkeos/1098474
"""
bottom = os.path.realpath(bottom)
# get files in current dir
try:
names = os.listdir(bottom)
except Exception as e:
return
dirs, nondirs = [], []
for name in names:
if os.path.isdir(os.path.join(bottom, name)):
dirs.append(name)
else:
nondirs.append(name)
yield bottom, dirs, nondirs
new_path = os.path.realpath(os.path.join(bottom, '..'))
# see if we are at the top
if new_path == bottom:
return
for x in walk_up(new_path):
yield x
def find_requirements(max_depth=3):
"""Returns the path of a Pipfile in parent directories."""
i = 0
for c, d, f in walk_up(os.getcwd()):
i += 1
if i < max_depth:
if 'requirements.txt':
r = os.path.join(c, 'requirements.txt')
if os.path.isfile(r):
return r
raise RuntimeError('No requirements.txt found!')