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

update the color scheme #159

Merged
merged 11 commits into from
Oct 17, 2022
42 changes: 21 additions & 21 deletions blackdoc/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .console import err, out
from .diff import unified_diff
from .files import collect_files
from .report import report_changes, report_possible_changes, statistics
from .report import Report

diff_highlighter = DiffHighlighter()

Expand Down Expand Up @@ -41,13 +41,15 @@ def format_and_overwrite(path, mode):
if new_content == content:
result = "unchanged"
else:
err.print(f"reformatted {path}", style="bold white")
err.print(f"reformatted {path}", style="bold", highlight=False)
result = "reformatted"

with open(path, "w", encoding=encoding, newline=newline) as f:
f.write(new_content)
except (black.InvalidInput, formats.InvalidFormatError) as e:
err.print(f"error: cannot format {path.absolute()}: {e}", style="red")
err.print(
f"error: cannot format {path.absolute()}: {e}", style="red", highlight=False
)
result = "error"

return result
Expand All @@ -65,7 +67,7 @@ def format_and_check(path, mode, diff=False, color=False):
if new_content == content:
result = "unchanged"
else:
err.print(f"would reformat {path}", style="bold white")
err.print(f"would reformat {path}", style="bold", highlight=False)

if diff:
diff_ = unified_diff(content, new_content, path)
Expand All @@ -79,15 +81,17 @@ def format_and_check(path, mode, diff=False, color=False):

result = "reformatted"
except (black.InvalidInput, formats.InvalidFormatError) as e:
err.print(f"error: cannot format {path.absolute()}: {e}", style="red")
err.print(
f"error: cannot format {path.absolute()}: {e}", style="red", highlight=False
)
result = "error"

return result


def process(args):
if not args.src:
err.print("No Path provided. Nothing to do :sleeping:", style="bold white")
err.print("No Path provided. Nothing to do :sleeping:", style="bold")
return 0

selected_formats = getattr(args, "formats", None)
Expand Down Expand Up @@ -153,7 +157,7 @@ def process(args):
if len(sources) == 0:
err.print(
"No files are present to be formatted. Nothing to do :sleeping:",
style="bold white",
style="bold",
)
return 0

Expand All @@ -178,29 +182,25 @@ def process(args):
changed_sources = {
source: action(source, mode, **action_kwargs) for source in sorted(sources)
}
n_reformatted, n_unchanged, n_error = statistics(changed_sources)

report_formatters = {
"inplace": report_changes,
"check": report_possible_changes,
}

report = report_formatters.get(args.action)(n_reformatted, n_unchanged, n_error)
conditional = args.action == "check"
report = Report.from_sources(changed_sources, conditional=conditional)

if n_error > 0:
if report.n_error > 0:
return_code = 123
elif args.action == "check" and n_reformatted > 0:
elif args.action == "check" and report.n_reformatted > 0:
return_code = 1
else:
return_code = 0

reformatted_message = "Oh no! :boom: :broken_heart: :boom:"
no_reformatting_message = "All done! :sparkles: :cake: :sparkles:"
error_message = "Oh no! :boom: :broken_heart: :boom:"
no_error_message = "All done! :sparkles: :cake: :sparkles:"
err.print()
err.print(
reformatted_message if return_code else no_reformatting_message,
style="bold white",
error_message if report.n_error > 0 else no_error_message,
style="bold",
)
err.print(report)
err.print(report, highlight=False)
return return_code


Expand Down
14 changes: 13 additions & 1 deletion blackdoc/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

def line_style(lineno, line):
if line.startswith("+++") or line.startswith("---"):
yield lineno, (0, len(line)), "bold white"
yield lineno, (0, len(line)), "bold"
elif line.startswith("@@"):
yield lineno, (0, len(line)), "cyan"
elif line.startswith("+"):
Expand Down Expand Up @@ -52,3 +52,15 @@ def diff_styles(text):

for (start, end), style in diff_styles(text.plain):
text.stylize(style, start=start, end=end)


class FileHighlighter(Highlighter):
highlights = {
r"[0-9]+ files?(?!.*fail)": "blue",
r"^.+reformatted$": "bold",
r"^.+fail.+$": "red",
}

def highlight(self, text):
for highlight_re, style in self.highlights.items():
text.highlight_regex(highlight_re, style=style)
99 changes: 63 additions & 36 deletions blackdoc/report.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,8 @@
def report_changes(n_reformatted, n_unchanged, n_error):
def noun(n):
return "file" if n < 2 else "files"
from rich.text import Text

reports = []
if n_reformatted > 0:
reports.append(
f"[bold white]{n_reformatted} {noun(n_reformatted)} reformatted[/]",
)
from .colors import FileHighlighter

if n_unchanged > 0:
reports.append(f"[white]{n_unchanged} {noun(n_unchanged)} left unchanged[/]")

if n_error > 0:
reports.append(f"[red]{n_error} {noun(n_error)} fails to reformat[/]")

return ", ".join(reports) + "."


def report_possible_changes(n_reformatted, n_unchanged, n_error):
def noun(n):
return "file" if n < 2 else "files"

reports = []
if n_reformatted > 0:
reports.append(
f"[bold white]{n_reformatted} {noun(n_reformatted)} would be reformatted[/]",
)

if n_unchanged > 0:
reports.append(
f"[white]{n_unchanged} {noun(n_unchanged)} would be left unchanged[/]"
)

if n_error > 0:
reports.append(f"[red]{n_error} {noun(n_error)} would fail to reformat[/]")

return ", ".join(reports) + "."
highlighter = FileHighlighter()


def statistics(sources):
Expand All @@ -51,3 +18,63 @@ def statistics(sources):
raise RuntimeError(f"unknown results: {statistics.keys()}")

return n_reformatted, n_unchanged, n_error


def noun(n):
return "file" if n < 2 else "files"


class Report:
def __init__(self, n_reformatted, n_unchanged, n_error, conditional=False):
self.n_reformatted = n_reformatted
self.n_unchanged = n_unchanged
self.n_error = n_error

self.conditional = conditional

@classmethod
def from_sources(cls, sources, conditional=False):
n_reformatted, n_unchanged, n_error = statistics(sources)

return cls(n_reformatted, n_unchanged, n_error, conditional=conditional)

def __repr__(self):
params = [
f"{name}={getattr(self, name)}"
for name in ["n_reformatted", "n_unchanged", "n_error", "conditional"]
]
return f"Report({', '.join(params)})"

@property
def _reformatted_report(self):
if self.conditional:
return (
f"{self.n_reformatted} {noun(self.n_reformatted)} would be reformatted"
)
else:
return f"{self.n_reformatted} {noun(self.n_reformatted)} reformatted"

@property
def _unchanged_report(self):
if self.conditional:
return (
f"{self.n_unchanged} {noun(self.n_unchanged)} would be left unchanged"
)
else:
return f"{self.n_unchanged} {noun(self.n_unchanged)} left unchanged"

@property
def _error_report(self):
if self.conditional:
return f"{self.n_error} {noun(self.n_error)} would fail to reformat"
else:
return f"{self.n_error} {noun(self.n_error)} failed to reformat"

def __rich__(self):
raw_parts = [
self._reformatted_report,
self._unchanged_report,
self._error_report,
]
parts = [highlighter(part) for part in raw_parts]
return Text(", ").join(parts) + Text(".")
74 changes: 73 additions & 1 deletion blackdoc/tests/test_colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
+++ file2 time2
"""
),
[Span(0, 15, "bold white"), Span(16, 31, "bold white")],
[Span(0, 15, "bold"), Span(16, 31, "bold")],
id="header",
),
pytest.param(
Expand All @@ -51,3 +51,75 @@ def test_diff_highlighter(text, spans):

actual = diff_highlighter(text)
assert actual.spans == spans


@pytest.mark.parametrize(
["text", "spans"],
(
pytest.param(
"1 file would be reformatted",
[Span(0, 6, "blue"), Span(0, 27, "bold")],
id="single file-reformatted-conditional",
),
pytest.param(
"1 file reformatted",
[Span(0, 6, "blue"), Span(0, 18, "bold")],
id="single file-reformatted",
),
pytest.param(
"26 files would be reformatted",
[Span(0, 8, "blue"), Span(0, 29, "bold")],
id="multiple files-reformatted-conditional",
),
pytest.param(
"26 files reformatted",
[Span(0, 8, "blue"), Span(0, 20, "bold")],
id="multiple files-reformatted",
),
pytest.param(
"1 file would be left unchanged",
[Span(0, 6, "blue")],
id="single file-unchanged-conditional",
),
pytest.param(
"1 file left unchanged",
[Span(0, 6, "blue")],
id="single file-unchanged",
),
pytest.param(
"26 files would be left unchanged",
[Span(0, 8, "blue")],
id="multiple files-unchanged-conditional",
),
pytest.param(
"26 files left unchanged",
[Span(0, 8, "blue")],
id="multiple files-unchanged",
),
pytest.param(
"1 file would fail to reformat",
[Span(0, 29, "red")],
id="single file-error-conditional",
),
pytest.param(
"1 file failed to reformat",
[Span(0, 25, "red")],
id="single file-error",
),
pytest.param(
"15 files would fail to reformat",
[Span(0, 31, "red")],
id="multiple files-error-conditional",
),
pytest.param(
"15 files failed to reformat",
[Span(0, 27, "red")],
id="multiple files-error",
),
),
)
def test_file_highlighter(text, spans):
highlighter = colors.FileHighlighter()

actual = highlighter(text)
assert actual.spans == spans
2 changes: 1 addition & 1 deletion doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ v0.3.8 (*unreleased*)
- drop support for ``python=3.6`` (:pull:`153`)
- split chained statements into multiple ``doctest`` lines (:issue:`143`, :pull:`155`, :pull:`158`)
- replace the custom color formatting code with `rich <https://github.com/textualize/rich>`_
(:issue:`146`, :pull:`157`).
(:issue:`146`, :pull:`157`, :pull:`159`).

v0.3.7 (13 September 2022)
--------------------------
Expand Down