Resolve Pipfile location for hash caculation

This should prevent the lookup loop most of the time, especially for new
virtualenvs created from now on.
This commit is contained in:
Tzu-ping Chung
2018-04-11 22:46:58 +08:00
parent e750927a5f
commit a895218013
+37 -14
View File
@@ -11,11 +11,15 @@ import hashlib
import contoml
import delegator
from pipenv.vendor.first import first
import pipfile
import pipfile.api
import toml
try:
import pathlib
except ImportError:
import pathlib2 as pathlib
from pip9 import ConfigOptionParser
from .cmdparse import Script
from .utils import (
@@ -43,12 +47,19 @@ from .environments import (
PIPENV_PYTHON,
)
def _normalized(p):
if p is None:
return None
return normalize_drive(str(pathlib.Path(p).resolve()))
if PIPENV_PIPFILE:
if not os.path.isfile(PIPENV_PIPFILE):
raise RuntimeError('Given PIPENV_PIPFILE is not found!')
else:
PIPENV_PIPFILE = normalize_drive(os.path.abspath(PIPENV_PIPFILE))
PIPENV_PIPFILE = _normalized(PIPENV_PIPFILE)
# (path, file contents) => TOMLFile
# keeps track of pipfiles that we've seen so we do not need to re-parse 'em
_pipfile_cache = {}
@@ -235,20 +246,32 @@ class Project(object):
name = self._sanitize(name)
hash = hashlib.sha256(location.encode()).digest()[:6]
encoded_hash = base64.urlsafe_b64encode(hash).decode()
return name, encoded_hash
pipfile = self.pipfile_location
clean_name, encoded_hash = get_name(name, pipfile)
return name, encoded_hash[:8]
clean_name, encoded_hash = get_name(name, self.pipfile_location)
venv_name = '{0}-{1}'.format(clean_name, encoded_hash)
# Check for different capitalization of the same project on windows
if os.name == 'nt' and not PIPENV_VENV_IN_PROJECT and not self._get_virtualenv_location(venv_name):
from pipenv.patched.pew.pew import lsenvs
env_name = first([env for env in lsenvs() if env.lower().startswith(name.lower())])
if env_name:
env_name = env_name[:-9]
pipfile = self.pipfile_location.replace(name, env_name)
clean_name, encoded_hash = get_name(env_name, pipfile)
# This should work most of the time, for non-WIndows, in-project venv,
# or "proper" path casing (on Windows).
if (os.name != 'nt' or
PIPENV_VENV_IN_PROJECT or
self._get_virtualenv_location(venv_name)):
return clean_name, encoded_hash
# Check for different capitalization of the same project.
from pipenv.patched.pew.pew import lsenvs
for env in lsenvs():
env_name = env[:-9]
if not (env[-9] != '-' and
env[-8:].isalpha() and
env_name.lower() != name.lower()):
continue
return get_name(env_name, self.pipfile_location.replace(name, env_name))
# Use the default if no matching env exists.
return clean_name, encoded_hash
@property
def virtualenv_name(self):
sanitized, encoded_hash = self._get_virtualenv_hash(self.name)
@@ -326,7 +349,7 @@ class Project(object):
loc = pipfile.Pipfile.find(max_depth=PIPENV_MAX_DEPTH)
except RuntimeError:
loc = None
self._pipfile_location = normalize_drive(loc)
self._pipfile_location = _normalized(loc)
return self._pipfile_location
@property