Spaces:
Runtime error
Runtime error
""" | |
Summarize Black runs to users. | |
""" | |
from dataclasses import dataclass | |
from enum import Enum | |
from pathlib import Path | |
from click import style | |
from black.output import err, out | |
class Changed(Enum): | |
NO = 0 | |
CACHED = 1 | |
YES = 2 | |
class NothingChanged(UserWarning): | |
"""Raised when reformatted code is the same as source.""" | |
class Report: | |
"""Provides a reformatting counter. Can be rendered with `str(report)`.""" | |
check: bool = False | |
diff: bool = False | |
quiet: bool = False | |
verbose: bool = False | |
change_count: int = 0 | |
same_count: int = 0 | |
failure_count: int = 0 | |
def done(self, src: Path, changed: Changed) -> None: | |
"""Increment the counter for successful reformatting. Write out a message.""" | |
if changed is Changed.YES: | |
reformatted = "would reformat" if self.check or self.diff else "reformatted" | |
if self.verbose or not self.quiet: | |
out(f"{reformatted} {src}") | |
self.change_count += 1 | |
else: | |
if self.verbose: | |
if changed is Changed.NO: | |
msg = f"{src} already well formatted, good job." | |
else: | |
msg = f"{src} wasn't modified on disk since last run." | |
out(msg, bold=False) | |
self.same_count += 1 | |
def failed(self, src: Path, message: str) -> None: | |
"""Increment the counter for failed reformatting. Write out a message.""" | |
err(f"error: cannot format {src}: {message}") | |
self.failure_count += 1 | |
def path_ignored(self, path: Path, message: str) -> None: | |
if self.verbose: | |
out(f"{path} ignored: {message}", bold=False) | |
def return_code(self) -> int: | |
"""Return the exit code that the app should use. | |
This considers the current state of changed files and failures: | |
- if there were any failures, return 123; | |
- if any files were changed and --check is being used, return 1; | |
- otherwise return 0. | |
""" | |
# According to http://tldp.org/LDP/abs/html/exitcodes.html starting with | |
# 126 we have special return codes reserved by the shell. | |
if self.failure_count: | |
return 123 | |
elif self.change_count and self.check: | |
return 1 | |
return 0 | |
def __str__(self) -> str: | |
"""Render a color report of the current state. | |
Use `click.unstyle` to remove colors. | |
""" | |
if self.check or self.diff: | |
reformatted = "would be reformatted" | |
unchanged = "would be left unchanged" | |
failed = "would fail to reformat" | |
else: | |
reformatted = "reformatted" | |
unchanged = "left unchanged" | |
failed = "failed to reformat" | |
report = [] | |
if self.change_count: | |
s = "s" if self.change_count > 1 else "" | |
report.append( | |
style(f"{self.change_count} file{s} ", bold=True, fg="blue") | |
+ style(f"{reformatted}", bold=True) | |
) | |
if self.same_count: | |
s = "s" if self.same_count > 1 else "" | |
report.append(style(f"{self.same_count} file{s} ", fg="blue") + unchanged) | |
if self.failure_count: | |
s = "s" if self.failure_count > 1 else "" | |
report.append(style(f"{self.failure_count} file{s} {failed}", fg="red")) | |
return ", ".join(report) + "." | |