Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove yaspin spinner #5468

Merged
merged 13 commits into from
Nov 18, 2022
2 changes: 2 additions & 0 deletions news/5468.vendor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Replace yaspin spinner with rich spinner.
* Bump vistir version to 0.7.4
7 changes: 5 additions & 2 deletions pipenv/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ def cli(
site_packages=None,
**kwargs,
):
from pipenv.patched.pip._vendor import rich
from pipenv.utils.shell import system_which
from pipenv.utils.spinner import create_spinner

load_dot_env(state.project, quiet=state.quiet)

Expand Down Expand Up @@ -188,7 +188,10 @@ def cli(
)
)
)
with create_spinner(text="Running...", setting=state.project.s):

console = rich.console.Console()
# TODO: add state.project.s to spinner status
with console.status("Running..."):
# Remove the virtualenv.
cleanup_virtualenv(state.project, bare=True)
return 0
Expand Down
77 changes: 43 additions & 34 deletions pipenv/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
)
from pipenv.patched.pip._internal.req.req_file import parse_requirements
from pipenv.patched.pip._internal.utils.misc import split_auth_from_netloc
from pipenv.patched.pip._vendor import rich
from pipenv.patched.pip._vendor.packaging.utils import canonicalize_name
from pipenv.project import Project
from pipenv.utils.constants import MYPY_RUNNING
Expand Down Expand Up @@ -52,7 +53,6 @@
subprocess_run,
system_which,
)
from pipenv.utils.spinner import create_spinner
from pipenv.vendor import click, plette, vistir
from pipenv.vendor.requirementslib.models.requirements import Requirement

Expand Down Expand Up @@ -94,6 +94,10 @@
STARTING_LABEL = " "


console = rich.console.Console()
err = rich.console.Console(stderr=True)


def do_clear(project):
from pipenv.patched.pip._internal import locations

Expand Down Expand Up @@ -245,14 +249,16 @@ def ensure_pipfile(project, validate=True, skip_requirements=False, system=False
)
# Create a Pipfile...
project.create_pipfile(python=python)
with create_spinner("Importing requirements...", project.s) as sp:
with console.status(
"Importing requirements...", spinner=project.s.PIPENV_SPINNER
) as st:
# Import requirements.txt.
try:
import_requirements(project)
except Exception:
sp.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Failed..."))
err.print(environments.PIPENV_SPINNER_FAIL_TEXT.format("Failed..."))
else:
sp.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
st.update(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
# Warn the user of side-effects.
click.echo(
"{0}: Your {1} now contains pinned versions, if your {2} did. \n"
Expand Down Expand Up @@ -398,17 +404,18 @@ def abort(msg=""):
click.style("...", bold=True),
)
)
with create_spinner("Installing python...", project.s) as sp:
# TOOD: pass project settings to console.status
with console.status("Installing python...") as st:
try:
c = installer.install(version)
except InstallerError as e:
sp.fail(
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format("Failed...")
)
click.echo(fix_utf8("Something went wrong..."), err=True)
click.secho(e.err, fg="cyan", err=True)
else:
sp.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
st(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
# Print the results, in a beautiful blue...
click.secho(c.stdout, fg="cyan", err=True)
# Clear the pythonfinder caches
Expand Down Expand Up @@ -1003,20 +1010,22 @@ def do_create_virtualenv(project, python=None, site_packages=None, pypi_mirror=N

# Actually create the virtualenv.
error = None
with create_spinner("Creating virtual environment...", project.s) as sp:
with console.status(
"Creating virtual environment...", spinner=project.s.PIPENV_SPINNER
):
c = subprocess_run(cmd, env=pip_config)
click.secho(f"{c.stdout}", fg="cyan", err=True)
if c.returncode != 0:
error = (
c.stderr if project.s.is_verbose() else exceptions.prettify_exc(c.stderr)
)
sp.fail(
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Failed creating virtual environment"
)
)
else:
sp.green.ok(
console.print(
environments.PIPENV_SPINNER_OK_TEXT.format(
"Successfully created virtual environment!"
)
Expand Down Expand Up @@ -2277,36 +2286,37 @@ def do_install(
extra_pip_args=extra_pip_args,
categories=categories,
)

for pkg_line in pkg_list:
click.secho(
fix_utf8(f"Installing {pkg_line}..."),
fg="green",
bold=True,
)
# pip install:
with vistir.contextmanagers.temp_environ(), create_spinner(
"Installing...", project.s
) as sp:
with vistir.contextmanagers.temp_environ(), console.status(
"Installing...", spinner=project.s.PIPENV_SPINNER
) as st:
if not system:
os.environ["PIP_USER"] = "0"
if "PYTHONHOME" in os.environ:
del os.environ["PYTHONHOME"]
sp.text = f"Resolving {pkg_line}..."
st.update(f"Resolving {pkg_line}...")
try:
pkg_requirement = Requirement.from_line(pkg_line)
except ValueError as e:
sp.write_err("{}: {}".format(click.style("WARNING", fg="red"), e))
sp.red.fail(
err.print("{}: {}".format(click.style("WARNING", fg="red"), e))
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Installation Failed"
)
)
sys.exit(1)
sp.text = "Installing..."
st.update("Installing...")
try:
sp.text = f"Installing {pkg_requirement.name}..."
st.update(f"Installing {pkg_requirement.name}...")
if project.s.is_verbose():
sp.hide_and_write(
st.update(
f"Installing package: {pkg_requirement.as_line(include_hashes=False)}"
)
c = pip_install(
Expand All @@ -2325,34 +2335,32 @@ def do_install(
extra_pip_args=extra_pip_args,
)
if c.returncode:
sp.write_err(
err.print(
"{} An error occurred while installing {}!".format(
click.style("Error: ", fg="red", bold=True),
click.style(pkg_line, fg="green"),
),
)
sp.write_err(f"Error text: {c.stdout}")
sp.write_err(click.style(format_pip_error(c.stderr), fg="cyan"))
err.print(f"Error text: {c.stdout}")
err.print(click.style(format_pip_error(c.stderr), fg="cyan"))
if project.s.is_verbose():
sp.write_err(
click.style(format_pip_output(c.stdout), fg="cyan")
)
err.print(click.style(format_pip_output(c.stdout), fg="cyan"))
if "setup.py egg_info" in c.stderr:
sp.write_err(
err.print(
"This is likely caused by a bug in {}. "
"Report this to its maintainers.".format(
click.style(pkg_requirement.name, fg="green")
)
)
sp.red.fail(
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Installation Failed"
)
)
sys.exit(1)
except (ValueError, RuntimeError) as e:
sp.write_err("{}: {}".format(click.style("WARNING", fg="red"), e))
sp.red.fail(
err.print("{}: {}".format(click.style("WARNING", fg="red"), e))
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Installation Failed",
)
Expand All @@ -2364,7 +2372,7 @@ def do_install(
and not pkg_requirement.editable
and not project.s.PIPENV_RESOLVE_VCS
):
sp.write_err(
err.print(
"{}: You installed a VCS dependency in non-editable mode. "
"This will work fine, but sub-dependencies will not be resolved by {}."
"\n To enable this sub-dependency functionality, specify that this dependency is editable."
Expand All @@ -2381,7 +2389,7 @@ def do_install(
pipfile_sections = "[dev-packages]"
else:
pipfile_sections = "[packages]"
sp.write(
st.update(
"{} {} {} {}{}".format(
click.style("Adding", bold=True),
click.style(f"{pkg_requirement.name}", fg="green", bold=True),
Expand Down Expand Up @@ -2409,18 +2417,19 @@ def do_install(
except ValueError:
import traceback

sp.write_err(
err.print(
"{} {}".format(
click.style("Error:", fg="red", bold=True),
traceback.format_exc(),
)
)
sp.fail(
err.print(
environments.PIPENV_SPINNER_FAIL_TEXT.format(
"Failed adding package to Pipfile"
)
)
sp.ok(
# ok has a nice v in front, should do something similir with rich
st.update(
environments.PIPENV_SPINNER_OK_TEXT.format("Installation Succeeded")
)
# Update project settings with pre preference.
Expand Down
19 changes: 13 additions & 6 deletions pipenv/environments.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,21 @@ def __init__(self) -> None:
if PIPENV_IS_CI:
self.PIPENV_NOSPIN = True

pipenv_spinner = "dots" if not os.name == "nt" else "bouncingBar"
self.PIPENV_SPINNER = get_from_env(
"SPINNER", check_for_negation=False, default=pipenv_spinner
)
if self.PIPENV_NOSPIN:
from pipenv.patched.pip._vendor.rich import _spinners

_spinners.SPINNERS[None] = {"interval": 80, "frames": " "}
self.PIPENV_SPINNER = None
else:
pipenv_spinner = "dots" if not os.name == "nt" else "bouncingBar"
self.PIPENV_SPINNER = get_from_env(
"SPINNER", check_for_negation=False, default=pipenv_spinner
)
"""Sets the default spinner type.

Spinners are identical to the ``node.js`` spinners and can be found at
https://github.com/sindresorhus/cli-spinners
You can see which spinners are available by running::

$ python -m pipenv.patched.pip._vendor.rich.spinner
"""

pipenv_pipfile = get_from_env("PIPFILE", check_for_negation=False)
Expand Down
29 changes: 13 additions & 16 deletions pipenv/utils/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from typing import Dict, List, Optional, Set, Tuple, Union

from pipenv import environments
from pipenv._compat import decode_for_output
from pipenv.exceptions import RequirementError, ResolutionFailure
from pipenv.patched.pip._internal.cache import WheelCache
from pipenv.patched.pip._internal.commands.install import InstallCommand
Expand All @@ -27,7 +26,7 @@
from pipenv.patched.pip._internal.req.req_file import parse_requirements
from pipenv.patched.pip._internal.utils.hashes import FAVORITE_HASH
from pipenv.patched.pip._internal.utils.temp_dir import global_tempdir_manager
from pipenv.patched.pip._vendor import pkg_resources
from pipenv.patched.pip._vendor import pkg_resources, rich
from pipenv.project import Project
from pipenv.vendor import click
from pipenv.vendor.requirementslib import Requirement
Expand Down Expand Up @@ -59,7 +58,9 @@
from .internet import _get_requests_session, is_pypi_url
from .locking import format_requirement_for_lockfile, prepare_lockfile
from .shell import make_posix, subprocess_run, temp_environ
from .spinner import create_spinner

console = rich.console.Console()
err = rich.console.Console(stderr=True)


def get_package_finder(
Expand Down Expand Up @@ -911,7 +912,7 @@ def actually_resolve_deps(
return (results, hashes, resolver.markers_lookup, resolver, resolver.skipped)


def resolve(cmd, sp, project):
def resolve(cmd, st, project):
from pipenv._compat import decode_output
from pipenv.cmdparse import Script
from pipenv.vendor.vistir.misc import echo
Expand All @@ -925,13 +926,13 @@ def resolve(cmd, sp, project):
continue
err += line
if is_verbose:
sp.hide_and_write(line.rstrip())
st.update(line.rstrip())

c.wait()
returncode = c.poll()
out = c.stdout.read()
if returncode != 0:
sp.red.fail(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!"))
st.update(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!"))
echo(out.strip(), err=True)
if not is_verbose:
echo(err, err=True)
Expand Down Expand Up @@ -1026,14 +1027,12 @@ def venv_resolve_deps(
os.environ.pop("PIPENV_SITE_DIR", None)
if keep_outdated:
os.environ["PIPENV_KEEP_OUTDATED"] = "1"
with create_spinner(
text=decode_for_output("Locking..."), setting=project.s
) as sp:
with console.status("Locking...", spinner=project.s.PIPENV_SPINNER) as st:
# This conversion is somewhat slow on local and file-type requirements since
# we now download those requirements / make temporary folders to perform
# dependency resolution on them, so we are including this step inside the
# spinner context manager for the UX improvement
sp.write(decode_for_output("Building requirements..."))
st.update("Building requirements...")
deps = convert_deps_to_pip(deps, project, include_index=True)
constraints = set(deps)
with tempfile.NamedTemporaryFile(
Expand All @@ -1042,16 +1041,14 @@ def venv_resolve_deps(
constraints_file.write(str("\n".join(constraints)))
cmd.append("--constraints-file")
cmd.append(constraints_file.name)
sp.write(decode_for_output("Resolving dependencies..."))
c = resolve(cmd, sp, project=project)
st.update("Resolving dependencies...")
c = resolve(cmd, st, project=project)
if c.returncode == 0:
sp.green.ok(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
st.update(environments.PIPENV_SPINNER_OK_TEXT.format("Success!"))
if not project.s.is_verbose() and c.stderr.strip():
click.echo(click.style(f"Warning: {c.stderr.strip()}"), err=True)
else:
sp.red.fail(
environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!")
)
st.update(environments.PIPENV_SPINNER_FAIL_TEXT.format("Locking Failed!"))
click.echo(f"Output: {c.stdout.strip()}", err=True)
click.echo(f"Error: {c.stderr.strip()}", err=True)
try:
Expand Down
18 changes: 0 additions & 18 deletions pipenv/utils/spinner.py

This file was deleted.

2 changes: 1 addition & 1 deletion pipenv/vendor/vendor.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ shellingham==1.5.0
termcolor==1.1.0
toml==0.10.2
tomlkit==0.9.2
vistir==0.6.1
vistir==0.7.4
wheel==0.37.1
yaspin==2.0.0
Loading