Skip to content

Commit

Permalink
Make --diff usable with --check
Browse files Browse the repository at this point in the history
This follows black's behaviour.
  • Loading branch information
BlankSpruce committed Feb 14, 2025
1 parent b05e29d commit 9550b55
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .gersemirc.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/0.19.0/gersemi/configuration.schema.json
# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/0.19.1/gersemi/configuration.schema.json

definitions: []
disable_formatting: false
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Changelog
## [0.19.1] 2025-02-14
### Fixed
- Make `--diff` usable with `--check`. (#58)

## [0.19.0] 2025-02-10
### Added
- Add `--warnings-as-errors`. (#57)
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ positional arguments:
modes:
-c, --check Check if files require reformatting. Return 0 when there's
nothing to reformat. Return 1 when some files would be
reformatted.
reformatted. It can be used together with --diff.
-i, --in-place Format files in-place.
--diff Show diff on stdout for each formatted file instead.
--diff Show diff on stdout for each formatted file instead. It can be
used together with --check.
--print-config {minimal,verbose,default}
Print configuration for files. With "minimal" prints source of
outcome configuration (configuration file or defaults) and the
Expand Down Expand Up @@ -134,7 +135,7 @@ You can use gersemi with a pre-commit hook by adding the following to `.pre-comm
```yaml
repos:
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.19.0
rev: 0.19.1
hooks:
- id: gersemi
```
Expand All @@ -150,7 +151,7 @@ If you want to use extensions with pre-commit list them with [`additional_depend
```yaml
repos:
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.19.0
rev: 0.19.1
hooks:
- id: gersemi
additional_dependencies:
Expand Down
6 changes: 5 additions & 1 deletion gersemi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def create_argparser():
Check if files require reformatting.
Return {SUCCESS} when there's nothing to reformat.
Return {FAIL} when some files would be reformatted.
It can be used together with --diff.
""",
)
modes_group.add_argument(
Expand All @@ -81,7 +82,10 @@ def create_argparser():
"--diff",
dest="show_diff",
action="store_true",
help="Show diff on stdout for each formatted file instead.",
help="""
Show diff on stdout for each formatted file instead.
It can be used together with --check.
""",
)
modes_group.add_argument(
"--print-config",
Expand Down
2 changes: 1 addition & 1 deletion gersemi/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
__license__ = "MPL 2.0"
__title__ = "gersemi"
__url__ = "https://github.com/BlankSpruce/gersemi"
__version__ = "0.19.0"
__version__ = "0.19.1"
3 changes: 3 additions & 0 deletions gersemi/mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ class Mode(Enum):
CheckFormatting = 2
ShowDiff = 3
PrintConfig = 4
CheckFormattingAndShowDiff = 5


def get_mode(args) -> Mode:
if args.check_formatting and args.show_diff:
return Mode.CheckFormattingAndShowDiff
if args.show_diff:
return Mode.ShowDiff
if args.check_formatting:
Expand Down
34 changes: 23 additions & 11 deletions gersemi/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@
from gersemi.return_codes import FAIL, INTERNAL_ERROR, SUCCESS
from gersemi.task_result import TaskResult
from gersemi.tasks.check_formatting import check_formatting
from gersemi.tasks.check_and_show_diff import check_and_show_diff
from gersemi.tasks.do_nothing import do_nothing
from gersemi.tasks.forward_to_stdout import forward_to_stdout
from gersemi.tasks.format_file import format_file
from gersemi.tasks.rewrite_in_place import rewrite_in_place
from gersemi.tasks.show_diff import show_colorized_diff, show_diff
from gersemi.tasks.show_diff import show_diff
from gersemi.utils import fromfile, smart_open
from gersemi.keywords import Keywords
from gersemi.warnings import UnknownCommandWarning
Expand All @@ -58,11 +59,16 @@ class WarningSink:
def __init__(self, quiet):
self.quiet = quiet
self.at_least_one_warning_issued = False
self.records = []

def __call__(self, *args, **kwargs):
def __call__(self, s: str):
self.at_least_one_warning_issued = True
if not self.quiet:
print_to_stderr(*args, **kwargs)
self.records.append(s)

def flush(self):
for s in self.records:
print_to_stderr(s)


class StatusCode:
Expand Down Expand Up @@ -162,13 +168,14 @@ def find_all_custom_command_definitions(

def select_task(mode: Mode, configuration: Configuration):
return {
Mode.ForwardToStdout: lambda _: forward_to_stdout,
Mode.RewriteInPlace: lambda _: rewrite_in_place,
Mode.CheckFormatting: lambda _: check_formatting,
Mode.ShowDiff: lambda config: (
show_colorized_diff if config.control.color else show_diff
Mode.ForwardToStdout: forward_to_stdout,
Mode.RewriteInPlace: rewrite_in_place,
Mode.CheckFormatting: check_formatting,
Mode.ShowDiff: partial(show_diff, configuration.control.color),
Mode.CheckFormattingAndShowDiff: partial(
check_and_show_diff, configuration.control.color
),
}[mode](configuration)
}[mode]


def run_task(
Expand Down Expand Up @@ -257,7 +264,11 @@ def split_files_by_formatting_state(
def store_files_in_cache(
mode: Mode, cache, configuration_summary: str, files: Iterable[Path]
) -> None:
if mode in [Mode.CheckFormatting, Mode.RewriteInPlace]:
if mode in [
Mode.CheckFormatting,
Mode.CheckFormattingAndShowDiff,
Mode.RewriteInPlace,
]:
cache.store_files(configuration_summary, files)


Expand Down Expand Up @@ -335,7 +346,7 @@ def __init__(
self.warning_sink = warning_sink

def _warn(self, item: NotSupportedKeys, text: str):
self.warning_sink(f"{item.path}:", text)
self.warning_sink(f"{item.path}: {text}")

def _inform_about_not_supported_keys(self, item: NotSupportedKeys):
if item.path in self.processed_configuration_files:
Expand Down Expand Up @@ -442,4 +453,5 @@ def run(args: argparse.Namespace):
if (control.warnings_as_errors and warning_sink.at_least_one_warning_issued)
else SUCCESS
)
warning_sink.flush()
return status_code.value
12 changes: 12 additions & 0 deletions gersemi/tasks/check_and_show_diff.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from gersemi.formatted_file import FormattedFile
from gersemi.task_result import TaskResult
from gersemi.tasks.check_formatting import check_formatting
from gersemi.tasks.show_diff import get_diff


def check_and_show_diff(
should_colorize: bool, formatted_file: FormattedFile
) -> TaskResult:
result = check_formatting(formatted_file)
result.to_stdout = get_diff(should_colorize, formatted_file)
return result
21 changes: 7 additions & 14 deletions gersemi/tasks/show_diff.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from difflib import unified_diff
from typing import Iterator
from gersemi.formatted_file import FormattedFile
from gersemi.return_codes import SUCCESS
from gersemi.task_result import TaskResult
Expand Down Expand Up @@ -29,29 +28,23 @@ def colorize(diff):
yield from diff


def get_diff(formatted_file: FormattedFile) -> Iterator[str]:
return unified_diff(
def get_diff(should_colorize: bool, formatted_file: FormattedFile) -> str:
result = unified_diff(
a=f"{formatted_file.before}\n".splitlines(keepends=True),
b=f"{formatted_file.after}\n".splitlines(keepends=True),
fromfile=fromfile(formatted_file.path),
tofile=tofile(formatted_file.path),
n=5,
)
if should_colorize:
result = colorize(result)
return "".join(result)


def show_diff(formatted_file: FormattedFile) -> TaskResult:
def show_diff(should_colorize: bool, formatted_file: FormattedFile) -> TaskResult:
return TaskResult(
path=formatted_file.path,
return_code=SUCCESS,
to_stdout="".join(get_diff(formatted_file)),
warnings=formatted_file.warnings,
)


def show_colorized_diff(formatted_file: FormattedFile) -> TaskResult:
return TaskResult(
path=formatted_file.path,
return_code=SUCCESS,
to_stdout="".join(colorize(get_diff(formatted_file))),
to_stdout=get_diff(should_colorize, formatted_file),
warnings=formatted_file.warnings,
)
27 changes: 26 additions & 1 deletion tests/test_executable.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,32 @@ def test_check_on_formatted_file_should_return_zero(app, testfiles):


def test_check_on_not_formatted_file_should_return_one(app, testfiles):
assert app("--check", testfiles / "not_formatted_file.cmake") == fail()
target = (testfiles / "not_formatted_file.cmake").resolve()
assert app("--check", target) == fail(
stdout="",
stderr=f"""{target} would be reformatted
""",
)


def test_diff_on_not_formatted_files_should_return_zero(app, testfiles):
target = testfiles / "directory_with_not_formatted_files"
assert app("--diff", target) == success(stdout=match_not(""), stderr="")


def test_check_with_diff_on_not_formatted_files_should_return_one(app, testfiles):
target = testfiles / "directory_with_not_formatted_files"
file1 = (target / "file1.cmake").resolve()
file2 = (target / "file2.cmake").resolve()
file3 = (target / "file3.cmake").resolve()

assert app("--check", "--diff", target) == fail(
stdout=match_not(""),
stderr=f"""{file1} would be reformatted
{file2} would be reformatted
{file3} would be reformatted
""",
)


def test_format_file_in_place(app, testfiles):
Expand Down

0 comments on commit 9550b55

Please sign in to comment.