Skip to content

Commit

Permalink
Merge pull request #5468 from pypa/remove-yaspin-spinner
Browse files Browse the repository at this point in the history
Remove yaspin spinner
  • Loading branch information
oz123 authored Nov 18, 2022
2 parents d7e3292 + baf1124 commit f95b671
Show file tree
Hide file tree
Showing 18 changed files with 163 additions and 556 deletions.
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 @@ -2284,36 +2293,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 @@ -2332,34 +2342,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 @@ -2371,7 +2379,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 @@ -2388,7 +2396,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 @@ -2416,18 +2424,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

0 comments on commit f95b671

Please sign in to comment.