Skip to content

Commit

Permalink
feat: enhanced error message
Browse files Browse the repository at this point in the history
- Removed old `commitlint.py`.
- Added new module `linter` for linting and validation.
- Added detailed validation on `linter` for message enhancement.
- Added new error messages.
- Added option `--quick` for quick linting.
- Moved old validation to quick linting.
- Added `pytest.ini` for adding src as a python path.
- Updated test for both detailed and quick with same test data.
  • Loading branch information
aj3sh committed Mar 14, 2024
1 parent 11040b0 commit 51f20e7
Show file tree
Hide file tree
Showing 25 changed files with 757 additions and 286 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ jobs:
uses: liskin/gh-problem-matcher-wrap@v3
with:
linters: isort
run: isort --line-length=88 --check src/
run: isort --line-length=88 --check --profile black src/
1 change: 1 addition & 0 deletions github_actions/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
This module relies on the presence of specific environment variables
set by GitHub Actions.
"""

import json
import os
from typing import Any, Dict
Expand Down
1 change: 1 addition & 0 deletions github_actions/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This script contains actions to be taken based on GitHub events,
specifically for push and pull_request events.
"""

import os
import subprocess
import sys
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[pytest]
pythonpath = src
6 changes: 3 additions & 3 deletions src/commitlint/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Main module for commitlint"""
"""Main module for commitlint."""

from .commitlint import check_commit_message
from .linter import lint_commit_message

__all__ = ["check_commit_message"]
__all__ = ["lint_commit_message"]
55 changes: 36 additions & 19 deletions src/commitlint/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
from typing import List

from .__version__ import __version__
from .commitlint import check_commit_message, remove_comments
from .exceptions import CommitlintException
from .git_helpers import get_commit_message_of_hash, get_commit_messages_of_hash_range
from .messages import VALIDATION_SUCCESSFUL
from .linter import lint_commit_message
from .linter.utils import remove_comments
from .messages import VALIDATION_FAILED, VALIDATION_SUCCESSFUL


def get_args() -> argparse.Namespace:
Expand Down Expand Up @@ -57,28 +58,43 @@ def get_args() -> argparse.Namespace:
# --to-hash is optional
parser.add_argument("--to-hash", type=str, help="To commit hash", default="HEAD")

# feature options
parser.add_argument(
"--quick", action="store_true", help="Check the commit message quickly."
)

# parsing args
args = parser.parse_args()

return args


def _show_errors(commit_message: str, errors: List[str]) -> None:
def _show_errors(
commit_message: str,
errors: List[str],
short: bool = False,
) -> None:
"""
Display a formatted error message for a list of errors.
Args:
commit_message (str): The commit message to display.
errors (List[str]): A list of error messages to be displayed.
short (bool): Display the error message in short.
"""
error_count = len(errors)
commit_message = remove_comments(commit_message)

sys.stderr.write(
f"⧗ Input:\n{commit_message}\n\n✖ Found {error_count} error(s).\n\n"
)
for index, error in enumerate(errors):
end_char = "" if index == error_count - 1 else "\n"
sys.stderr.write(f"- {error}\n{end_char}")
sys.stderr.write(f"⧗ Input:\n{commit_message}\n\n")

if short:
sys.stderr.write(f"{VALIDATION_FAILED}\n")
return

sys.stderr.write(f"✖ Found {error_count} error(s).\n")
for error in errors:
sys.stderr.write(f"- {error}\n")


def _get_commit_message_from_file(filepath: str) -> str:
Expand All @@ -101,26 +117,27 @@ def _get_commit_message_from_file(filepath: str) -> str:
return commit_message


def _handle_commit_message(commit_message: str) -> None:
def _handle_commit_message(commit_message: str, quick: bool) -> None:
"""
Handles a single commit message, checks its validity, and prints the result.
Args:
commit_message (str): The commit message to be handled.
quick (bool): True for quick linting.
Raises:
SystemExit: If the commit message is invalid.
"""
success, errors = check_commit_message(commit_message)
success, errors = lint_commit_message(commit_message, quick=quick)

if success:
sys.stdout.write(f"{VALIDATION_SUCCESSFUL}\n")
else:
_show_errors(commit_message, errors)
_show_errors(commit_message, errors, short=quick)
sys.exit(1)


def _handle_multiple_commit_messages(commit_messages: List[str]) -> None:
def _handle_multiple_commit_messages(commit_messages: List[str], quick: bool) -> None:
"""
Handles multiple commit messages, checks their validity, and prints the result.
Expand All @@ -132,10 +149,10 @@ def _handle_multiple_commit_messages(commit_messages: List[str]) -> None:
"""
has_error = False
for commit_message in commit_messages:
success, errors = check_commit_message(commit_message)
success, errors = lint_commit_message(commit_message, quick=quick)
if not success:
has_error = True
_show_errors(commit_message, errors)
_show_errors(commit_message, errors, short=quick)
sys.stderr.write("\n")

if has_error:
Expand All @@ -153,18 +170,18 @@ def main() -> None:
try:
if args.file:
commit_message = _get_commit_message_from_file(args.file)
_handle_commit_message(commit_message)
_handle_commit_message(commit_message, quick=args.quick)
elif args.hash:
commit_message = get_commit_message_of_hash(args.hash)
_handle_commit_message(commit_message)
_handle_commit_message(commit_message, quick=args.quick)
elif args.from_hash:
commit_messages = get_commit_messages_of_hash_range(
args.from_hash, args.to_hash
)
_handle_multiple_commit_messages(commit_messages)
_handle_multiple_commit_messages(commit_messages, quick=args.quick)
else:
commit_message = args.commit_message.strip()
_handle_commit_message(commit_message)
_handle_commit_message(commit_message, quick=args.quick)
except CommitlintException as ex:
sys.stderr.write(f"{ex}\n")
sys.exit(1)
Expand Down
124 changes: 0 additions & 124 deletions src/commitlint/commitlint.py

This file was deleted.

25 changes: 25 additions & 0 deletions src/commitlint/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
"""This module defines constants used throughout the application."""

COMMIT_HEADER_MAX_LENGTH = 72

COMMIT_TYPES = (
"build",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"style",
"test",
"chore",
"revert",
"bump",
)

IGNORE_COMMIT_PATTERNS = (
r"^((Merge pull request)|(Merge (.*?) into (.*?)|(Merge branch (.*?)))(?:\r?\n)*$)|"
r"^(Merge tag (.*?))(?:\r?\n)*$|"
r"^(R|r)evert (.*)|"
r"^(Merged (.*?)(in|into) (.*)|Merged PR (.*): (.*))$|"
r"^Merge remote-tracking branch(\s*)(.*)$|"
r"^Automatic merge(.*)$|"
r"^Auto-merged (.*?) into (.*)$"
)
1 change: 1 addition & 0 deletions src/commitlint/git_helpers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
This module contains the git related helper functions.
"""

import subprocess
from typing import List

Expand Down
7 changes: 7 additions & 0 deletions src/commitlint/linter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""Main module for commit linters and validators"""

from ._linter import lint_commit_message

__all__ = [
"lint_commit_message",
]
Loading

0 comments on commit 51f20e7

Please sign in to comment.