Skip to content

Commit

Permalink
Add --no-progress <progress_bar> to pip download and ``pip inst…
Browse files Browse the repository at this point in the history
…all`` to suppress progress bar in the console
  • Loading branch information
AvnerCohen authored and xavfernandez committed Jan 30, 2017
1 parent 672e88a commit 0552ffe
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 17 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
* Add `--exclude-editable` to ``pip freeze`` to exclude editable packages
from installed package list.

* Add `--progress-bar <progress_bar>` to ``pip download``, ``pip install``
and ``pip wheel`` to suppress progress bar in the console (:pull:`4194`)


**9.0.1 (2016-11-06)**

* Correct the deprecation message when not specifying a --format so that it
Expand Down
12 changes: 12 additions & 0 deletions pip/_vendor/progress/bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ def update(self):
self.writeln(line)


class SilentBar(Bar):
def update(self):
pass


class ChargingBar(Bar):
suffix = '%(percent)d%%'
bar_prefix = ' '
Expand Down Expand Up @@ -81,3 +86,10 @@ def update(self):

class ShadyBar(IncrementalBar):
phases = (u' ', u'░', u'▒', u'▓', u'█')


class BlueEmojiBar(IncrementalBar):
suffix = '%(percent)d%%'
bar_prefix = ' '
bar_suffix = ' '
phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535")
12 changes: 12 additions & 0 deletions pip/cmdoptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pip.models import PyPI
from pip.locations import USER_CACHE_DIR, src_prefix
from pip.utils.hashes import STRONG_HASHES
from pip.utils.ui import BAR_TYPES


def make_option_group(group, parser):
Expand Down Expand Up @@ -119,6 +120,16 @@ def getname(n):
' levels).')
)

progress_bar = partial(
Option,
'--progress-bar',
dest='progress_bar',
type='choice',
choices=list(BAR_TYPES.keys()),
default='on',
help='Specify type of progress to be displayed [' +
'|'.join(BAR_TYPES.keys()) + '] (default: %default)')

log = partial(
Option,
"--log", "--log-file", "--local-log",
Expand Down Expand Up @@ -529,6 +540,7 @@ def only_binary():
help="Don't periodically check PyPI to determine whether a new version "
"of pip is available for download. Implied with --no-index.")


# Deprecated, Remove later
always_unzip = partial(
Option,
Expand Down
4 changes: 3 additions & 1 deletion pip/commands/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def __init__(self, *args, **kw):
cmd_opts.add_option(cmdoptions.pre())
cmd_opts.add_option(cmdoptions.no_clean())
cmd_opts.add_option(cmdoptions.require_hashes())
cmd_opts.add_option(cmdoptions.progress_bar())

cmd_opts.add_option(
'-d', '--dest', '--destination-dir', '--destination-directory',
Expand Down Expand Up @@ -180,7 +181,8 @@ def run(self, options, args):
ignore_dependencies=options.ignore_dependencies,
session=session,
isolated=options.isolated_mode,
require_hashes=options.require_hashes
require_hashes=options.require_hashes,
progress_bar=options.progress_bar
)
self.populate_requirement_set(
requirement_set,
Expand Down
2 changes: 2 additions & 0 deletions pip/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ def __init__(self, *args, **kw):
cmd_opts.add_option(cmdoptions.only_binary())
cmd_opts.add_option(cmdoptions.no_clean())
cmd_opts.add_option(cmdoptions.require_hashes())
cmd_opts.add_option(cmdoptions.progress_bar())

index_opts = cmdoptions.make_option_group(
cmdoptions.index_group,
Expand Down Expand Up @@ -303,6 +304,7 @@ def run(self, options, args):
isolated=options.isolated_mode,
wheel_cache=wheel_cache,
require_hashes=options.require_hashes,
progress_bar=options.progress_bar,
)

self.populate_requirement_set(
Expand Down
4 changes: 3 additions & 1 deletion pip/commands/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def __init__(self, *args, **kw):
cmd_opts.add_option(cmdoptions.ignore_requires_python())
cmd_opts.add_option(cmdoptions.no_deps())
cmd_opts.add_option(cmdoptions.build_dir())
cmd_opts.add_option(cmdoptions.progress_bar())

cmd_opts.add_option(
'--global-option',
Expand Down Expand Up @@ -177,7 +178,8 @@ def run(self, options, args):
session=session,
wheel_cache=wheel_cache,
wheel_download_dir=options.wheel_dir,
require_hashes=options.require_hashes
require_hashes=options.require_hashes,
progress_bar=options.progress_bar
)

self.populate_requirement_set(
Expand Down
24 changes: 13 additions & 11 deletions pip/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
from pip.utils.logging import indent_log
from pip.utils.setuptools_build import SETUPTOOLS_SHIM
from pip.utils.glibc import libc_ver
from pip.utils.ui import DownloadProgressBar, DownloadProgressSpinner
from pip.utils.ui import DownloadProgressProvider
from pip.locations import write_delete_marker_file
from pip.vcs import vcs
from pip._vendor import requests, six
Expand Down Expand Up @@ -514,14 +514,13 @@ def _progress_indicator(iterable, *args, **kwargs):
return iterable


def _download_url(resp, link, content_file, hashes):
def _download_url(resp, link, content_file, hashes, progress_bar):
try:
total_length = int(resp.headers['content-length'])
except (ValueError, KeyError, TypeError):
total_length = 0

cached_resp = getattr(resp, "from_cache", False)

if logger.getEffectiveLevel() > logging.INFO:
show_progress = False
elif cached_resp:
Expand Down Expand Up @@ -585,12 +584,12 @@ def written_chunks(chunks):
url = link.url_without_fragment

if show_progress: # We don't show progress on cached responses
progress_indicator = DownloadProgressProvider(progress_bar,
max=total_length)
if total_length:
logger.info("Downloading %s (%s)", url, format_size(total_length))
progress_indicator = DownloadProgressBar(max=total_length).iter
else:
logger.info("Downloading %s", url)
progress_indicator = DownloadProgressSpinner().iter
elif cached_resp:
logger.info("Using cached %s", url)
else:
Expand Down Expand Up @@ -638,7 +637,7 @@ def _copy_file(filename, location, link):


def unpack_http_url(link, location, download_dir=None,
session=None, hashes=None):
session=None, hashes=None, progress_bar="on"):
if session is None:
raise TypeError(
"unpack_http_url() missing 1 required keyword argument: 'session'"
Expand All @@ -661,7 +660,8 @@ def unpack_http_url(link, location, download_dir=None,
from_path, content_type = _download_http_url(link,
session,
temp_dir,
hashes)
hashes,
progress_bar)

# unpack the archive to the build dir location. even when only downloading
# archives, they have to be unpacked to parse dependencies
Expand Down Expand Up @@ -790,7 +790,8 @@ def request(self, host, handler, request_body, verbose=False):


def unpack_url(link, location, download_dir=None,
only_download=False, session=None, hashes=None):
only_download=False, session=None, hashes=None,
progress_bar="on"):
"""Unpack link.
If link is a VCS link:
if only_download, export into download_dir and ignore location
Expand Down Expand Up @@ -823,13 +824,14 @@ def unpack_url(link, location, download_dir=None,
location,
download_dir,
session,
hashes=hashes
hashes=hashes,
progress_bar=progress_bar
)
if only_download:
write_delete_marker_file(location)


def _download_http_url(link, session, temp_dir, hashes):
def _download_http_url(link, session, temp_dir, hashes, progress_bar):
"""Download link url into temp_dir using provided session"""
target_url = link.url.split('#', 1)[0]
try:
Expand Down Expand Up @@ -884,7 +886,7 @@ def _download_http_url(link, session, temp_dir, hashes):
filename += ext
file_path = os.path.join(temp_dir, filename)
with open(file_path, 'wb') as content_file:
_download_url(resp, link, content_file, hashes)
_download_url(resp, link, content_file, hashes, progress_bar)
return file_path, content_type


Expand Down
6 changes: 4 additions & 2 deletions pip/req/req_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def __init__(self, build_dir, src_dir, download_dir, upgrade=False,
force_reinstall=False, use_user_site=False, session=None,
pycompile=True, isolated=False, wheel_download_dir=None,
wheel_cache=None, require_hashes=False,
ignore_requires_python=False):
ignore_requires_python=False, progress_bar="on"):
"""Create a RequirementSet.
:param wheel_download_dir: Where still-packed .whl files should be
Expand Down Expand Up @@ -182,6 +182,7 @@ def __init__(self, build_dir, src_dir, download_dir, upgrade=False,
self.unnamed_requirements = []
self.ignore_dependencies = ignore_dependencies
self.ignore_requires_python = ignore_requires_python
self.progress_bar = progress_bar
self.successfully_downloaded = []
self.successfully_installed = []
self.reqs_to_cleanup = []
Expand Down Expand Up @@ -618,7 +619,8 @@ def _prepare_file(self,
unpack_url(
req_to_install.link, req_to_install.source_dir,
download_dir, autodelete_unpacked,
session=self.session, hashes=hashes)
session=self.session, hashes=hashes,
progress_bar=self.progress_bar)
except requests.HTTPError as exc:
logger.critical(
'Could not install requirement %s because '
Expand Down
57 changes: 55 additions & 2 deletions pip/utils/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
from pip.utils import format_size
from pip.utils.logging import get_indentation
from pip._vendor import six

from pip._vendor.progress.bar import Bar, IncrementalBar
from pip._vendor.progress.bar import FillingCirclesBar, FillingSquaresBar
from pip._vendor.progress.bar import ChargingBar, ShadyBar
from pip._vendor.progress.bar import BlueEmojiBar, SilentBar

from pip._vendor.progress.helpers import (WritelnMixin,
HIDE_CURSOR, SHOW_CURSOR)
from pip._vendor.progress.spinner import Spinner
Expand Down Expand Up @@ -171,14 +176,46 @@ def __init__(self, *args, **kwargs):
self.file.flush = lambda: self.file.wrapped.flush()


class DownloadProgressBar(WindowsMixin, InterruptibleMixin,
DownloadProgressMixin, _BaseBar):
class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin,
DownloadProgressMixin):

file = sys.stdout
message = "%(percent)d%%"
suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s"


class DefaultDownloadProgressBar(BaseDownloadProgressBar, _BaseBar):
pass


class DownloadSilentBar(BaseDownloadProgressBar, SilentBar):
pass


class DownloadIncrementalBar(BaseDownloadProgressBar, IncrementalBar):
pass


class DownloadChargingBar(BaseDownloadProgressBar, ChargingBar):
pass


class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar):
pass


class DownloadFillingSquaresBar(BaseDownloadProgressBar, FillingSquaresBar):
pass


class DownloadFillingCirclesBar(BaseDownloadProgressBar, FillingCirclesBar):
pass


class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, BlueEmojiBar):
pass


class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin,
DownloadProgressMixin, WritelnMixin, Spinner):

Expand All @@ -205,6 +242,22 @@ def update(self):
self.writeln(line)


BAR_TYPES = {
"off": (DownloadSilentBar, DownloadSilentBar),
"on": (DefaultDownloadProgressBar, DownloadProgressSpinner),
"ascii": (DownloadIncrementalBar, DownloadProgressSpinner),
"pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner),
"emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner)
}


def DownloadProgressProvider(progress_bar, max=None):
if max is None or max == 0:
return BAR_TYPES[progress_bar][1]().iter
else:
return BAR_TYPES[progress_bar][0](max=max).iter


################################################################
# Generic "something is happening" spinners
#
Expand Down

0 comments on commit 0552ffe

Please sign in to comment.