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

fix: Handle unquoted pipes. #180

Merged
merged 1 commit into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions mreg_cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,8 @@ def parse(self, command: str) -> None:
# after it prints a help msg.
self.last_errno = e.code

except CliWarning as e:
print_formatted_text(HTML(f"<i>{e}</i>"))

except CliError as e:
print_formatted_text(HTML(f"<ansired>{e}</ansired>"))
except (CliWarning, CliError) as exc:
exc.print_self()

except CliExit:
from sys import exit
Expand Down
39 changes: 36 additions & 3 deletions mreg_cli/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
"""This module contains custom exceptions for the CLI."""

import sys

from prompt_toolkit import print_formatted_text
from prompt_toolkit.formatted_text import HTML


class CliException(Exception):
pass
"""Base exception class for the CLI."""

def formatted_exception(self) -> str:
"""Returns a formatted string representation of the exception.

:returns: Formatted string for the exception message.
"""
raise NotImplementedError("This method should be implemented by subclasses")

def print_self(self):
"""Prints the exception with appropriate formatting."""
print_formatted_text(HTML(self.formatted_exception()), file=sys.stdout)


class CliError(CliException):
pass
"""Exception class for CLI errors."""

def formatted_exception(self) -> str:
"""Formatted string with ANSI red color for the error message.

:returns: Formatted error message.
"""
return f"<ansired>{super().__str__()}</ansired>"


class CliWarning(CliException):
pass
"""Exception class for CLI warnings."""

def formatted_exception(self) -> str:
"""Formatted string with HTML italic tag for the warning message.

:returns: Formatted warning message.
"""
return f"<i>{super().__str__()}</i>"


class HostNotFoundWarning(CliWarning):
Expand Down
7 changes: 5 additions & 2 deletions mreg_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from . import config, log, recorder, util
from .cli import cli, source
from .exceptions import CliError, CliWarning
from .outputmanager import OutputManager

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -187,8 +188,10 @@ def main():
cli.parse(cmd)
# Render the output
output.render()
except ValueError as e:
print(e)
except (CliWarning, CliError) as exc:
exc.print_self()
except ValueError as exc:
print(exc)


if __name__ == "__main__":
Expand Down
17 changes: 15 additions & 2 deletions mreg_cli/outputmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import re
from typing import Any, List, Tuple

from mreg_cli.exceptions import CliError


class OutputManager:
"""Manages and formats output for display.
Expand Down Expand Up @@ -42,7 +44,7 @@ def from_command(self, command: str) -> str:
"""Adds the command that generated the output.

:param command: The command to add.

:raises CliError: If the command is invalid.
:return: The cleaned command, devoid of filters and other noise.
"""
self._command, self._filter_re, self._negate = self.get_filter(command)
Expand Down Expand Up @@ -113,6 +115,7 @@ def get_filter(self, command: str) -> Tuple[str, Any, bool]:
splitting.

:param command: The command to parse for the filter.
:raises CliError: If the filter is invalid.
:return: The command, the filter, and whether it is a negated filter.
"""
negate = False
Expand All @@ -129,7 +132,17 @@ def get_filter(self, command: str) -> Tuple[str, Any, bool]:
negate = True
filter_str = filter_str[1:].strip()

filter_re = re.compile(filter_str)
try:
filter_re = re.compile(filter_str)
except re.error as exc:
if "|" in filter_str:
raise CliError(
"ERROR: Command parts that contain a pipe ('|') must be quoted.",
) from exc
else:
raise CliError(
"ERROR: Unable to compile regex '{}': {}", filter_str, exc
) from exc

return (command, filter_re, negate)

Expand Down