Skip to content

Commit

Permalink
Indent logs with a context manager
Browse files Browse the repository at this point in the history
Introduces new context manager `LogContext.intentation()`. Usage:

```python
from piptools.loggin import log

log.debug("Hello")

with log.indentation():
  log.debug("World!")
```

Output:

```
Hello
  World!
```
  • Loading branch information
atugushev committed Apr 19, 2020
1 parent 6847146 commit fa9fd3c
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 28 deletions.
27 changes: 24 additions & 3 deletions piptools/logging.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# coding: utf-8
from __future__ import absolute_import, division, print_function, unicode_literals

import contextlib
import logging

from . import click
Expand All @@ -11,12 +12,15 @@


class LogContext(object):
def __init__(self, verbosity=0):
def __init__(self, verbosity=0, indent_width=2):
self.verbosity = verbosity
self.current_indent = 0
self._indent_width = indent_width

def log(self, *args, **kwargs):
def log(self, message, *args, **kwargs):
kwargs.setdefault("err", True)
click.secho(*args, **kwargs)
prefix = " " * self.current_indent
click.secho(prefix + message, *args, **kwargs)

def debug(self, *args, **kwargs):
if self.verbosity >= 1:
Expand All @@ -34,5 +38,22 @@ def error(self, *args, **kwargs):
kwargs.setdefault("fg", "red")
self.log(*args, **kwargs)

def _indent(self):
self.current_indent += self._indent_width

def _dedent(self):
self.current_indent -= self._indent_width

@contextlib.contextmanager
def indentation(self):
"""
Increase indentation.
"""
self._indent()
try:
yield
finally:
self._dedent()


log = LogContext()
18 changes: 12 additions & 6 deletions piptools/repositories/pypi.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,15 @@ def get_hashes(self, ireq):
)
matching_candidates = candidates_by_version[matching_versions[0]]

log.debug(" {}".format(ireq.name))
log.debug(ireq.name)

return {
self._get_file_hash(candidate.link) for candidate in matching_candidates
}
with log.indentation():
return {
self._get_file_hash(candidate.link) for candidate in matching_candidates
}

def _get_file_hash(self, link):
log.debug(" Hashing {}".format(link.url_without_fragment))
log.debug("Hashing {}".format(link.url_without_fragment))
h = hashlib.new(FAVORITE_HASH)
with open_local_or_remote_file(link, self.session) as f:
# Chunks to iterate
Expand All @@ -283,7 +284,12 @@ def _get_file_hash(self, link):
# Choose a context manager depending on verbosity
if log.verbosity >= 1:
iter_length = f.size / FILE_CHUNK_SIZE if f.size else None
context_manager = progressbar(chunks, length=iter_length, label=" ")
bar_template = "{prefix}[%(bar)s] %(info)s".format(
prefix=" " * log.current_indent
)
context_manager = progressbar(
chunks, length=iter_length, bar_template=bar_template
)
else:
context_manager = contextlib.nullcontext(chunks)

Expand Down
33 changes: 18 additions & 15 deletions piptools/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def resolve_hashes(self, ireqs):
"""
log.debug("")
log.debug("Generating hashes:")
with self.repository.allow_all_wheels():
with self.repository.allow_all_wheels(), log.indentation():
return {ireq: self.repository.get_hashes(ireq) for ireq in ireqs}

def resolve(self, max_rounds=10):
Expand Down Expand Up @@ -238,20 +238,23 @@ def _resolve_one_round(self):
constraints = sorted(self.constraints, key=key_from_ireq)

log.debug("Current constraints:")
for constraint in constraints:
log.debug(" {}".format(constraint))
with log.indentation():
for constraint in constraints:
log.debug(str(constraint))

log.debug("")
log.debug("Finding the best candidates:")
best_matches = {self.get_best_match(ireq) for ireq in constraints}
with log.indentation():
best_matches = {self.get_best_match(ireq) for ireq in constraints}

# Find the new set of secondary dependencies
log.debug("")
log.debug("Finding secondary dependencies:")

their_constraints = []
for best_match in best_matches:
their_constraints.extend(self._iter_dependencies(best_match))
with log.indentation():
for best_match in best_matches:
their_constraints.extend(self._iter_dependencies(best_match))
# Grouping constraints to make clean diff between rounds
theirs = set(self._group_constraints(sorted(their_constraints, key=str)))

Expand All @@ -268,11 +271,13 @@ def _resolve_one_round(self):
if has_changed:
log.debug("")
log.debug("New dependencies found in this round:")
for new_dependency in sorted(diff, key=key_from_ireq):
log.debug(" adding {}".format(new_dependency))
with log.indentation():
for new_dependency in sorted(diff, key=key_from_ireq):
log.debug("adding {}".format(new_dependency))
log.debug("Removed dependencies in this round:")
for removed_dependency in sorted(removed, key=key_from_ireq):
log.debug(" removing {}".format(removed_dependency))
with log.indentation():
for removed_dependency in sorted(removed, key=key_from_ireq):
log.debug("removing {}".format(removed_dependency))

# Store the last round's results in the their_constraints
self.their_constraints = theirs
Expand Down Expand Up @@ -308,7 +313,7 @@ def get_best_match(self, ireq):

# Format the best match
log.debug(
" found candidate {} (constraint was {})".format(
"found candidate {} (constraint was {})".format(
format_requirement(best_match), format_specifier(ireq)
)
)
Expand Down Expand Up @@ -352,9 +357,7 @@ def _iter_dependencies(self, ireq):
# from there
if ireq not in self.dependency_cache:
log.debug(
" {} not in cache, need to check index".format(
format_requirement(ireq)
),
"{} not in cache, need to check index".format(format_requirement(ireq)),
fg="yellow",
)
dependencies = self.repository.get_dependencies(ireq)
Expand All @@ -363,7 +366,7 @@ def _iter_dependencies(self, ireq):
# Example: ['Werkzeug>=0.9', 'Jinja2>=2.4']
dependency_strings = self.dependency_cache[ireq]
log.debug(
" {:25} requires {}".format(
"{:25} requires {}".format(
format_requirement(ireq),
", ".join(sorted(dependency_strings, key=lambda s: s.lower())) or "-",
)
Expand Down
10 changes: 6 additions & 4 deletions piptools/scripts/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,14 +369,16 @@ def cli(
]

log.debug("Using indexes:")
for index_url in dedup(repository.finder.index_urls):
log.debug(" {}".format(index_url))
with log.indentation():
for index_url in dedup(repository.finder.index_urls):
log.debug(index_url)

if repository.finder.find_links:
log.debug("")
log.debug("Configuration:")
for find_link in dedup(repository.finder.find_links):
log.debug(" -f {}".format(find_link))
with log.indentation():
for find_link in dedup(repository.finder.find_links):
log.debug("-f {}".format(find_link))

try:
resolver = Resolver(
Expand Down
25 changes: 25 additions & 0 deletions tests/test_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from piptools.logging import LogContext


def test_indentation(runner):
"""
Test LogContext.indentation() context manager increases indentation.
"""
log = LogContext(indent_width=2)

with runner.isolation() as (_, stderr):
log.log("Test message 1")
with log.indentation():
log.log("Test message 2")
with log.indentation():
log.log("Test message 3")
log.log("Test message 4")
log.log("Test message 5")

assert stderr.getvalue().decode().splitlines() == [
"Test message 1",
" Test message 2",
" Test message 3",
" Test message 4",
"Test message 5",
]

0 comments on commit fa9fd3c

Please sign in to comment.