Merge pull request #3386 from pypa/improve-message

Decouple project from the existence of Pipfile.
This commit is contained in:
Frost Ming
2019-04-01 16:46:26 +08:00
committed by GitHub
5 changed files with 32 additions and 31 deletions
+1
View File
@@ -0,0 +1 @@
Do not touch Pipfile early and rely on it so that one can do ``pipenv sync`` without a Pipfile.
+1
View File
@@ -0,0 +1 @@
Improve the error message when one tries to initialize a Pipenv project under ``/``.
+5 -1
View File
@@ -152,7 +152,11 @@ def cli(
# There is no virtualenv yet.
if not project.virtualenv_exists:
echo(
crayons.red("No virtualenv has been created for this project yet!"),
"{}({}){}".format(
crayons.red("No virtualenv has been created for this project"),
crayons.white(project.project_directory, bold=True),
crayons.red(" yet!")
),
err=True,
)
ctx.abort()
+16 -12
View File
@@ -539,11 +539,16 @@ def ensure_project(
# Automatically use an activated virtualenv.
if PIPENV_USE_SYSTEM:
system = True
if not project.pipfile_exists:
if deploy is True:
raise exceptions.PipfileNotFound
else:
project.touch_pipfile()
if not project.pipfile_exists and deploy:
raise exceptions.PipfileNotFound
# Fail if working under /
if not project.name:
click.echo(
"{0}: Pipenv is not intended to work under the root directory, "
"please choose another path.".format(crayons.red("ERROR")),
err=True
)
sys.exit(1)
# Skip virtualenv creation when --system was used.
if not system:
ensure_virtualenv(
@@ -606,24 +611,23 @@ def shorten_path(location, bold=False):
def do_where(virtualenv=False, bare=True):
"""Executes the where functionality."""
if not virtualenv:
location = project.pipfile_location
# Shorten the virtual display of the path to the virtualenv.
if not bare:
location = shorten_path(location)
if not location:
if not project.pipfile_exists:
click.echo(
"No Pipfile present at project home. Consider running "
"{0} first to automatically generate a Pipfile for you."
"".format(crayons.green("`pipenv install`")),
err=True,
)
elif not bare:
return
location = project.pipfile_location
# Shorten the virtual display of the path to the virtualenv.
if not bare:
location = shorten_path(location)
click.echo(
"Pipfile found at {0}.\n Considering this to be the project home."
"".format(crayons.green(location)),
err=True,
)
pass
else:
click.echo(project.project_directory)
else:
+9 -18
View File
@@ -54,7 +54,7 @@ def _normalized(p):
path_str = matches and matches[0] or str(loc)
else:
path_str = str(loc)
return normalize_drive(path_str)
return normalize_drive(os.path.abspath(path_str))
DEFAULT_NEWLINES = u"\n"
@@ -226,7 +226,7 @@ class Project(object):
@property
def pipfile_exists(self):
return bool(self.pipfile_location)
return os.path.isfile(self.pipfile_location)
@property
def required_python_version(self):
@@ -241,11 +241,7 @@ class Project(object):
@property
def project_directory(self):
if self.pipfile_location is not None:
return os.path.abspath(os.path.join(self.pipfile_location, os.pardir))
else:
return None
return os.path.abspath(os.path.join(self.pipfile_location, os.pardir))
@property
def requirements_exists(self):
@@ -259,8 +255,7 @@ class Project(object):
@property
def virtualenv_exists(self):
# TODO: Decouple project from existence of Pipfile.
if self.pipfile_exists and os.path.exists(self.virtualenv_location):
if os.path.exists(self.virtualenv_location):
if os.name == "nt":
extra = ["Scripts", "activate.bat"]
else:
@@ -478,7 +473,7 @@ class Project(object):
try:
loc = pipfile.Pipfile.find(max_depth=PIPENV_MAX_DEPTH)
except RuntimeError:
loc = None
loc = "Pipfile"
self._pipfile_location = _normalized(loc)
return self._pipfile_location
@@ -507,6 +502,8 @@ class Project(object):
def read_pipfile(self):
# Open the pipfile, read it into memory.
if not self.pipfile_exists:
return ""
with io.open(self.pipfile_location) as f:
contents = f.read()
self._pipfile_newlines = preferred_newlines(f)
@@ -664,11 +661,6 @@ class Project(object):
"""Returns a list of dev-packages, for pip-tools to consume."""
return self._build_package_list("dev-packages")
def touch_pipfile(self):
"""Simply touches the Pipfile, for later use."""
with open("Pipfile", "a"):
os.utime("Pipfile", None)
@property
def pipfile_is_empty(self):
if not self.pipfile_exists:
@@ -685,8 +677,7 @@ class Project(object):
ConfigOptionParser, make_option_group, index_group
)
name = self.name if self.name is not None else "Pipfile"
config_parser = ConfigOptionParser(name=name)
config_parser = ConfigOptionParser(name=self.name)
config_parser.add_option_group(make_option_group(index_group, config_parser))
install = config_parser.option_groups[0]
indexes = (
@@ -839,7 +830,7 @@ class Project(object):
@property
def pipfile_sources(self):
if "source" not in self.parsed_pipfile:
if self.pipfile_is_empty or "source" not in self.parsed_pipfile:
return [DEFAULT_SOURCE]
# We need to make copies of the source info so we don't
# accidentally modify the cache. See #2100 where values are