Skip to content

Commit

Permalink
Merge pull request #1750 from legau/formatoutput
Browse files Browse the repository at this point in the history
add format-errors and format-success options
  • Loading branch information
timothycrosley committed Jun 18, 2021
2 parents 5c0f120 + 80e3c91 commit e864272
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 15 deletions.
28 changes: 28 additions & 0 deletions docs/configuration/options.md
Expand Up @@ -1312,6 +1312,34 @@ Tells isort to format the given files according to an extensions formatting rule

- --ext-format

## Format Errors

Define the format used to print errors.

**NOTE** Variables are `error` and `message`.
The `error` variable prints `ERROR` with color depending on the --color option.

**Type:** String
**Default:** `{error}: {message}`
**Python & Config File Name:** format_errors
**CLI Flags:**

- --format-errors

## Format Success

Define the format used to print successes.

**NOTE** Variables are `success` and `message`.
The `success` variable prints `SUCCESS` with color depending on the --color option.

**Type:** String
**Default:** `{success}: {message}`
**Python & Config File Name:** format_success
**CLI Flags:**

- --format-success

## Deprecated Flags

==SUPPRESS==
Expand Down
4 changes: 3 additions & 1 deletion isort/api.py
Expand Up @@ -242,7 +242,9 @@ def check_stream(
file_path=file_path,
disregard_skip=disregard_skip,
)
printer = create_terminal_printer(color=config.color_output)
printer = create_terminal_printer(
color=config.color_output, error=config.format_error, success=config.format_success
)
if not changed:
if config.verbose and not config.only_modified:
printer.success(f"{file_path or ''} Everything Looks Good!")
Expand Down
20 changes: 13 additions & 7 deletions isort/format.py
Expand Up @@ -95,22 +95,24 @@ class BasicPrinter:
ERROR = "ERROR"
SUCCESS = "SUCCESS"

def __init__(self, output: Optional[TextIO] = None):
def __init__(self, error: str, success: str, output: Optional[TextIO] = None):
self.output = output or sys.stdout
self.success_message = success
self.error_message = error

def success(self, message: str) -> None:
print(f"{self.SUCCESS}: {message}", file=self.output)
print(self.success_message.format(success=self.SUCCESS, message=message), file=self.output)

def error(self, message: str) -> None:
print(f"{self.ERROR}: {message}", file=sys.stderr)
print(self.error_message.format(error=self.ERROR, message=message), file=sys.stderr)

def diff_line(self, line: str) -> None:
self.output.write(line)


class ColoramaPrinter(BasicPrinter):
def __init__(self, output: Optional[TextIO] = None):
super().__init__(output=output)
def __init__(self, error: str, success: str, output: Optional[TextIO]):
super().__init__(error, success, output=output)

# Note: this constants are instance variables instead ofs class variables
# because they refer to colorama which might not be installed.
Expand All @@ -134,7 +136,9 @@ def diff_line(self, line: str) -> None:
self.output.write(self.style_text(line, style))


def create_terminal_printer(color: bool, output: Optional[TextIO] = None):
def create_terminal_printer(
color: bool, output: Optional[TextIO] = None, error: str = "", success: str = ""
):
if color and colorama_unavailable:
no_colorama_message = (
"\n"
Expand All @@ -147,4 +151,6 @@ def create_terminal_printer(color: bool, output: Optional[TextIO] = None):
print(no_colorama_message, file=sys.stderr)
sys.exit(1)

return ColoramaPrinter(output) if color else BasicPrinter(output)
return (
ColoramaPrinter(error, success, output) if color else BasicPrinter(error, success, output)
)
26 changes: 22 additions & 4 deletions isort/main.py
Expand Up @@ -127,7 +127,9 @@ def _print_hard_fail(
"This should NEVER happen.\n"
"If encountered, please open an issue: https://github.com/PyCQA/isort/issues/new"
)
printer = create_terminal_printer(color=config.color_output)
printer = create_terminal_printer(
color=config.color_output, error=config.format_error, success=config.format_success
)
printer.error(message)


Expand Down Expand Up @@ -297,6 +299,16 @@ def _build_arg_parser() -> argparse.ArgumentParser:
action="store_true",
help="Tells isort to apply changes interactively.",
)
general_group.add_argument(
"--format-error",
dest="format_error",
help="Override the format used to print errors.",
)
general_group.add_argument(
"--format-success",
dest="format_success",
help="Override the format used to print success.",
)

target_group.add_argument(
"files", nargs="*", help="One or more Python source files that need their imports sorted."
Expand Down Expand Up @@ -1094,13 +1106,17 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] =
raise_on_skip=False,
)
elif "/" in file_names and not allow_root:
printer = create_terminal_printer(color=config.color_output)
printer = create_terminal_printer(
color=config.color_output, error=config.format_error, success=config.format_success
)
printer.error("it is dangerous to operate recursively on '/'")
printer.error("use --allow-root to override this failsafe")
sys.exit(1)
else:
if stream_filename:
printer = create_terminal_printer(color=config.color_output)
printer = create_terminal_printer(
color=config.color_output, error=config.format_error, success=config.format_success
)
printer.error("Filename override is intended only for stream (-) sorting.")
sys.exit(1)
skipped: List[str] = []
Expand Down Expand Up @@ -1222,7 +1238,9 @@ def main(argv: Optional[Sequence[str]] = None, stdin: Optional[TextIOWrapper] =
sys.exit(1)

if no_valid_encodings:
printer = create_terminal_printer(color=config.color_output)
printer = create_terminal_printer(
color=config.color_output, error=config.format_error, success=config.format_success
)
printer.error("No valid encodings.")
sys.exit(1)

Expand Down
2 changes: 2 additions & 0 deletions isort/settings.py
Expand Up @@ -217,6 +217,8 @@ class _Config:
star_first: bool = False
import_dependencies = Dict[str, str]
git_ignore: Dict[Path, Set[Path]] = field(default_factory=dict)
format_error: str = "{error}: {message}"
format_success: str = "{success}: {message}"

def __post_init__(self):
py_version = self.py_version
Expand Down
18 changes: 15 additions & 3 deletions tests/unit/test_format.py
Expand Up @@ -21,14 +21,26 @@ def test_ask_whether_to_apply_changes_to_file():


def test_basic_printer(capsys):
printer = isort.format.create_terminal_printer(color=False)
printer = isort.format.create_terminal_printer(
color=False, success="{success}: {message}", error="{error}: {message}"
)
printer.success("All good!")
out, _ = capsys.readouterr()
assert out == "SUCCESS: All good!\n"
printer.error("Some error")
_, err = capsys.readouterr()
assert err == "ERROR: Some error\n"

printer = isort.format.create_terminal_printer(
color=False, success="success: {message}: {success}", error="error: {message}: {error}"
)
printer.success("All good!")
out, _ = capsys.readouterr()
assert out == "success: All good!: SUCCESS\n"
printer.error("Some error")
_, err = capsys.readouterr()
assert err == "error: Some error: ERROR\n"


def test_basic_printer_diff(capsys):
printer = isort.format.create_terminal_printer(color=False)
Expand All @@ -40,7 +52,7 @@ def test_basic_printer_diff(capsys):


def test_colored_printer_success(capsys):
printer = isort.format.create_terminal_printer(color=True)
printer = isort.format.create_terminal_printer(color=True, success="{success}: {message}")
printer.success("All good!")
out, _ = capsys.readouterr()
assert "SUCCESS" in out
Expand All @@ -49,7 +61,7 @@ def test_colored_printer_success(capsys):


def test_colored_printer_error(capsys):
printer = isort.format.create_terminal_printer(color=True)
printer = isort.format.create_terminal_printer(color=True, error="{error}: {message}")
printer.error("Some error")
_, err = capsys.readouterr()
assert "ERROR" in err
Expand Down

0 comments on commit e864272

Please sign in to comment.