mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 22:50:18 +00:00
pyenv and asdf installers
This commit is contained in:
committed by
Tzu-ping Chung
parent
181c9648a0
commit
232e076e26
+24
-16
@@ -24,9 +24,9 @@ from ._compat import decode_for_output, fix_utf8
|
||||
from .cmdparse import Script
|
||||
from .environments import (
|
||||
PIP_EXISTS_ACTION, PIPENV_CACHE_DIR, PIPENV_COLORBLIND,
|
||||
PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_DONT_USE_PYENV, PIPENV_HIDE_EMOJIS,
|
||||
PIPENV_MAX_SUBPROCESS, PIPENV_PYUP_API_KEY, PIPENV_RESOLVE_VCS,
|
||||
PIPENV_SHELL_FANCY, PIPENV_SKIP_VALIDATION, PIPENV_YES,
|
||||
PIPENV_DEFAULT_PYTHON_VERSION, PIPENV_DONT_USE_PYENV, PIPENV_DONT_USE_ASDF,
|
||||
PIPENV_HIDE_EMOJIS, PIPENV_MAX_SUBPROCESS, PIPENV_PYUP_API_KEY,
|
||||
PIPENV_RESOLVE_VCS, PIPENV_SHELL_FANCY, PIPENV_SKIP_VALIDATION, PIPENV_YES,
|
||||
SESSION_IS_INTERACTIVE, is_type_checking
|
||||
)
|
||||
from .patched import crayons
|
||||
@@ -392,28 +392,36 @@ def ensure_python(three=None, python=None):
|
||||
),
|
||||
err=True,
|
||||
)
|
||||
# Pyenv is installed
|
||||
from .vendor.pythonfinder.environment import PYENV_INSTALLED
|
||||
# check for python installers
|
||||
from .vendor.pythonfinder.environment import PYENV_INSTALLED, ASDF_INSTALLED
|
||||
from .installers import Pyenv, Asdf, InstallerError
|
||||
|
||||
if not PYENV_INSTALLED:
|
||||
# prefer pyenv if both pyenv and asdf are installed as it's
|
||||
# dedicated to python installs so probably the preferred
|
||||
# method of the user for new python installs.
|
||||
if PYENV_INSTALLED and not PIPENV_DONT_USE_PYENV:
|
||||
installer = Pyenv("pyenv")
|
||||
elif ASDF_INSTALLED and not PIPENV_DONT_USE_ASDF:
|
||||
installer = Asdf("asdf")
|
||||
else:
|
||||
installer = None
|
||||
|
||||
if not installer:
|
||||
abort()
|
||||
else:
|
||||
if (not PIPENV_DONT_USE_PYENV) and (SESSION_IS_INTERACTIVE or PIPENV_YES):
|
||||
from .pyenv import Runner, PyenvError
|
||||
|
||||
pyenv = Runner("pyenv")
|
||||
if SESSION_IS_INTERACTIVE or PIPENV_YES:
|
||||
try:
|
||||
version = pyenv.find_version_to_install(python)
|
||||
version = installer.find_version_to_install(python)
|
||||
except ValueError:
|
||||
abort()
|
||||
except PyenvError as e:
|
||||
except InstallerError as e:
|
||||
click.echo(fix_utf8("Something went wrong…"))
|
||||
click.echo(crayons.blue(e.err), err=True)
|
||||
abort()
|
||||
s = "{0} {1} {2}".format(
|
||||
"Would you like us to install",
|
||||
crayons.green("CPython {0}".format(version)),
|
||||
"with pyenv?",
|
||||
"with {0}?".format(installer),
|
||||
)
|
||||
# Prompt the user to continue…
|
||||
if not (PIPENV_YES or click.confirm(s, default=True)):
|
||||
@@ -424,15 +432,15 @@ def ensure_python(three=None, python=None):
|
||||
u"{0} {1} {2} {3}{4}".format(
|
||||
crayons.normal(u"Installing", bold=True),
|
||||
crayons.green(u"CPython {0}".format(version), bold=True),
|
||||
crayons.normal(u"with pyenv", bold=True),
|
||||
crayons.normal(u"with {}".format(installer), bold=True),
|
||||
crayons.normal(u"(this may take a few minutes)"),
|
||||
crayons.normal(fix_utf8("…"), bold=True),
|
||||
)
|
||||
)
|
||||
with create_spinner("Installing python...") as sp:
|
||||
try:
|
||||
c = pyenv.install(version)
|
||||
except PyenvError as e:
|
||||
c = installer.install(version)
|
||||
except InstallerError as e:
|
||||
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format(
|
||||
"Failed...")
|
||||
)
|
||||
|
||||
@@ -68,6 +68,12 @@ PIPENV_DONT_USE_PYENV = bool(os.environ.get("PIPENV_DONT_USE_PYENV"))
|
||||
Default is to install Python automatically via pyenv when needed, if possible.
|
||||
"""
|
||||
|
||||
PIPENV_DONT_USE_ASDF = bool(os.environ.get("PIPENV_DONT_USE_ASDF"))
|
||||
"""If set, Pipenv does not attempt to install Python with asdf.
|
||||
|
||||
Default is to install Python automatically via asdf when needed, if possible.
|
||||
"""
|
||||
|
||||
PIPENV_DOTENV_LOCATION = os.environ.get("PIPENV_DOTENV_LOCATION")
|
||||
"""If set, Pipenv loads the ``.env`` file at the specified location.
|
||||
|
||||
|
||||
@@ -48,19 +48,22 @@ class Version(object):
|
||||
return (self.major, self.minor) == (other.major, other.minor)
|
||||
|
||||
|
||||
class PyenvError(RuntimeError):
|
||||
class InstallerError(RuntimeError):
|
||||
def __init__(self, desc, c):
|
||||
super(PyenvError, self).__init__(desc)
|
||||
super(InstallerError, self).__init__(desc)
|
||||
self.out = c.out
|
||||
self.err = c.err
|
||||
|
||||
|
||||
class Runner(object):
|
||||
class Installer(object):
|
||||
|
||||
def __init__(self, pyenv):
|
||||
self._cmd = pyenv
|
||||
def __init__(self, cmd):
|
||||
self._cmd = cmd
|
||||
|
||||
def _pyenv(self, *args, **kwargs):
|
||||
def __str__(self):
|
||||
return self._cmd
|
||||
|
||||
def _run(self, *args, **kwargs):
|
||||
timeout = kwargs.pop('timeout', delegator.TIMEOUT)
|
||||
if kwargs:
|
||||
k = list(kwargs.keys())[0]
|
||||
@@ -69,21 +72,16 @@ class Runner(object):
|
||||
c = delegator.run(args, block=False, timeout=timeout)
|
||||
c.block()
|
||||
if c.return_code != 0:
|
||||
raise PyenvError('faild to run {0}'.format(args), c)
|
||||
raise InstallerError('faild to run {0}'.format(args), c)
|
||||
return c
|
||||
|
||||
def iter_installable_versions(self):
|
||||
"""Iterate through CPython versions available for Pipenv to install.
|
||||
"""
|
||||
for name in self._pyenv('install', '--list').out.splitlines():
|
||||
try:
|
||||
version = Version.parse(name.strip())
|
||||
except ValueError:
|
||||
continue
|
||||
yield version
|
||||
raise NotImplementedError
|
||||
|
||||
def find_version_to_install(self, name):
|
||||
"""Find a version in pyenv from the version supplied.
|
||||
"""Find a version in the installer from the version supplied.
|
||||
|
||||
A ValueError is raised if a matching version cannot be found.
|
||||
"""
|
||||
@@ -103,16 +101,64 @@ class Runner(object):
|
||||
return best_match
|
||||
|
||||
def install(self, version):
|
||||
"""Install the given version with pyenv.
|
||||
"""Install the given version with runner implementation.
|
||||
|
||||
The version must be a ``Version`` instance representing a version
|
||||
found in pyenv.
|
||||
found in the Installer.
|
||||
|
||||
A ValueError is raised if the given version does not have a match in
|
||||
pyenv. A PyenvError is raised if the pyenv command fails.
|
||||
the runner. A InstallerError is raised if the runner command fails.
|
||||
"""
|
||||
c = self._pyenv(
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Pyenv(Installer):
|
||||
|
||||
def iter_installable_versions(self):
|
||||
"""Iterate through CPython versions available for Pipenv to install.
|
||||
"""
|
||||
for name in self._run('install', '--list').out.splitlines():
|
||||
try:
|
||||
version = Version.parse(name.strip())
|
||||
except ValueError:
|
||||
continue
|
||||
yield version
|
||||
|
||||
def install(self, version):
|
||||
"""Install the given version with pyenv.
|
||||
The version must be a ``Version`` instance representing a version
|
||||
found in pyenv.
|
||||
A ValueError is raised if the given version does not have a match in
|
||||
pyenv. A InstallerError is raised if the pyenv command fails.
|
||||
"""
|
||||
c = self._run(
|
||||
'install', '-s', str(version),
|
||||
timeout=PIPENV_INSTALL_TIMEOUT,
|
||||
)
|
||||
return c
|
||||
|
||||
|
||||
class Asdf(Installer):
|
||||
|
||||
def iter_installable_versions(self):
|
||||
"""Iterate through CPython versions available for asdf to install.
|
||||
"""
|
||||
for name in self._run('list-all', 'python').out.splitlines():
|
||||
try:
|
||||
version = Version.parse(name.strip())
|
||||
except ValueError:
|
||||
continue
|
||||
yield version
|
||||
|
||||
def install(self, version):
|
||||
"""Install the given version with asdf.
|
||||
The version must be a ``Version`` instance representing a version
|
||||
found in asdf.
|
||||
A ValueError is raised if the given version does not have a match in
|
||||
asdf. A InstallerError is raised if the asdf command fails.
|
||||
"""
|
||||
c = self._run(
|
||||
'install', 'python', str(version),
|
||||
timeout=PIPENV_INSTALL_TIMEOUT,
|
||||
)
|
||||
return c
|
||||
Reference in New Issue
Block a user