Skip to content
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
2 changes: 1 addition & 1 deletion commitizen/bump.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from packaging.version import Version

from commitizen.git import GitCommit
from commitizen.defaults import (
MAJOR,
MINOR,
Expand All @@ -15,6 +14,7 @@
bump_message,
bump_pattern,
)
from commitizen.git import GitCommit


def find_increment(
Expand Down
9 changes: 7 additions & 2 deletions commitizen/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,18 @@
"arguments": [
{
"name": "--commit-msg-file",
"required": True,
"help": (
"ask for the name of the temporal file that contains "
"the commit message. "
"Using it in a git hook script: MSG_FILE=$1"
),
}
"exclusive_group": "group1",
},
{
"name": "--rev-range",
"help": ("a reange of git rev to check. e.g, master..HEAD"),
"exclusive_group": "group1",
},
],
},
{
Expand Down
3 changes: 1 addition & 2 deletions commitizen/commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
from .commit import Commit
from .example import Example
from .info import Info
from .init import Init
from .list_cz import ListCz
from .schema import Schema
from .version import Version
from .init import Init


__all__ = (
"Bump",
Expand Down
6 changes: 3 additions & 3 deletions commitizen/commands/bump.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from typing import Optional, List
from typing import List, Optional

import questionary
from packaging.version import Version

from commitizen import bump, factory, git, out
from commitizen.config import BaseConfig
from commitizen.error_codes import (
COMMIT_FAILED,
NO_COMMITS_FOUND,
NO_VERSION_SPECIFIED,
NO_PATTERN_MAP,
COMMIT_FAILED,
NO_VERSION_SPECIFIED,
TAG_FAILED,
)

Expand Down
57 changes: 40 additions & 17 deletions commitizen/commands/check.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import os
import re
from typing import Dict

from commitizen import factory, out
from commitizen import factory, git, out
from commitizen.config import BaseConfig
from commitizen.error_codes import INVALID_COMMIT_MSG


class Check:
"""Check if the current commit msg matches the commitizen format."""

def __init__(self, config: BaseConfig, arguments: dict, cwd=os.getcwd()):
def __init__(self, config: BaseConfig, arguments: Dict[str, str], cwd=os.getcwd()):
"""Init method.

Parameters
Expand All @@ -21,31 +22,53 @@ def __init__(self, config: BaseConfig, arguments: dict, cwd=os.getcwd()):
the flags provided by the user

"""
self.commit_msg_file: str = arguments.get("commit_msg_file")
self.rev_range: str = arguments.get("rev_range")

self._valid_command_argument()

self.config: BaseConfig = config
self.cz = factory.commiter_factory(self.config)
self.arguments: dict = arguments

def _valid_command_argument(self):
if bool(self.commit_msg_file) is bool(self.rev_range):
out.error("One and only one argument is required for check command!")
raise SystemExit()

def __call__(self):
"""Validate if a commit message follows the conventional pattern.
"""Validate if commit messages follows the conventional pattern.

Raises
------
SystemExit
if the commit provided not follows the conventional pattern

"""
commit_msg_content = self._get_commit_msg()
commit_msgs = self._get_commit_messages()
pattern = self.cz.schema_pattern()
if self._has_proper_format(pattern, commit_msg_content) is not None:
out.success("Commit validation: successful!")
else:
out.error("commit validation: failed!")
out.error("please enter a commit message in the commitizen format.")
raise SystemExit(INVALID_COMMIT_MSG)

def _get_commit_msg(self):
temp_filename: str = self.arguments.get("commit_msg_file")
return open(temp_filename, "r").read()

def _has_proper_format(self, pattern, commit_msg):
for commit_msg in commit_msgs:
if not Check.validate_commit_message(commit_msg, pattern):
out.error(
"commit validation: failed!\n"
"please enter a commit message in the commitizen format.\n"
f"commit: {commit_msg}\n"
f"pattern: {pattern}"
)
raise SystemExit(INVALID_COMMIT_MSG)
out.success("Commit validation: successful!")

def _get_commit_messages(self):
# Get commit message from file (--commit-msg-file)
if self.commit_msg_file:
with open(self.commit_msg_file, "r") as commit_file:
commit_msg = commit_file.read()
return [commit_msg]

# Get commit messages from git log (--rev-range)
return [commit.message for commit in git.get_commits(end=self.rev_range)]

@staticmethod
def validate_commit_message(commit_msg: str, pattern: str) -> bool:
if commit_msg.startswith("Merge") or commit_msg.startswith("Revert"):
return True
return re.match(pattern, commit_msg)
6 changes: 3 additions & 3 deletions commitizen/commands/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
import questionary

from commitizen import factory, git, out
from commitizen.cz.exceptions import CzException
from commitizen.config import BaseConfig
from commitizen.cz.exceptions import CzException
from commitizen.error_codes import (
NO_ANSWERS,
COMMIT_ERROR,
CUSTOM_ERROR,
NO_ANSWERS,
NO_COMMIT_BACKUP,
NOTHING_TO_COMMIT,
CUSTOM_ERROR,
)


Expand Down
7 changes: 3 additions & 4 deletions commitizen/commands/init.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
from packaging.version import Version

import questionary
from packaging.version import Version

from commitizen import factory, out
from commitizen.config import BaseConfig, IniConfig, TomlConfig
from commitizen.cz import registry
from commitizen.config import BaseConfig, TomlConfig, IniConfig
from commitizen.git import get_latest_tag_name, get_tag_names
from commitizen.defaults import long_term_support_config_files
from commitizen.git import get_latest_tag_name, get_tag_names


class Init:
Expand Down
2 changes: 1 addition & 1 deletion commitizen/commands/list_cz.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from commitizen import out
from commitizen.cz import registry
from commitizen.config import BaseConfig
from commitizen.cz import registry


class ListCz:
Expand Down
2 changes: 1 addition & 1 deletion commitizen/commands/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from commitizen import out
from commitizen.config import BaseConfig
from commitizen.__version__ import __version__
from commitizen.config import BaseConfig


class Version:
Expand Down
3 changes: 2 additions & 1 deletion commitizen/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

from commitizen import defaults, git, out
from commitizen.error_codes import NOT_A_GIT_PROJECT

from .base_config import BaseConfig
from .toml_config import TomlConfig
from .ini_config import IniConfig
from .toml_config import TomlConfig


def load_global_conf() -> Optional[IniConfig]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def schema(self) -> str:
def schema_pattern(self) -> str:
PATTERN = (
r"(build|ci|docs|feat|fix|perf|refactor|style|test|chore|revert|bump)"
r"(\([\w\-]+\))?:\s.*"
r"(\(\S+\))?:\s.*"
)
return PATTERN

Expand Down
2 changes: 1 addition & 1 deletion commitizen/cz/customize/customize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from string import Template

from commitizen import defaults
from commitizen.cz.base import BaseCommitizen
from commitizen.config import BaseConfig
from commitizen.cz.base import BaseCommitizen

__all__ = ["CustomizeCommitsCz"]

Expand Down
2 changes: 1 addition & 1 deletion commitizen/factory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from commitizen import BaseCommitizen, out
from commitizen.cz import registry
from commitizen.config import BaseConfig
from commitizen.cz import registry
from commitizen.error_codes import NO_COMMITIZEN_FOUND


Expand Down
4 changes: 2 additions & 2 deletions commitizen/git.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
from pathlib import Path
from tempfile import NamedTemporaryFile
from typing import Optional, List
from typing import List, Optional

from commitizen import cmd

Expand Down Expand Up @@ -64,7 +64,7 @@ def get_commits(
git_log_cmd = f"git log --pretty={log_format}{delimiter}"

if start:
c = cmd.run(f"{git_log_cmd} {start}...{end}")
c = cmd.run(f"{git_log_cmd} {start}..{end}")
else:
c = cmd.run(f"{git_log_cmd} {end}")

Expand Down
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ isort = "^4.3.21"
cz = "commitizen.cli:main"
git-cz = "commitizen.cli:main"

[tool.isort]
multi_line_output = 3
include_trailing_comma = true
force_grid_wrap = 0
combine_as_imports = true
line_length = 88

[tool.coverage]
[tool.coverage.report]
show_missing = true
Expand Down
4 changes: 2 additions & 2 deletions scripts/lint
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/bin/sh -e

export PREFIX=""
export PREFIX="poetry run python -m "
if [ -d 'venv' ] ; then
export PREFIX="venv/bin/"
fi

set -x

${PREFIX}isort --multi-line=3 --trailing-comma --force-grid-wrap=0 --combine-as --line-width 88 --recursive --apply commitizen tests
${PREFIX}isort --recursive --apply commitizen tests
${PREFIX}black commitizen tests
1 change: 1 addition & 0 deletions scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ fi

${PREFIX}pytest --cov-report term-missing --cov-report=xml:coverage.xml --cov=commitizen tests/
${PREFIX}black commitizen tests --check
${PREFIX}isort --recursive --check-only commitizen tests
${PREFIX}flake8 --max-line-length=88 commitizen/ tests/
84 changes: 81 additions & 3 deletions tests/commands/test_check_command.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,48 @@
import sys
from typing import List

import pytest

from commitizen import cli
from commitizen import commands
from commitizen import cli, commands, git

COMMIT_LOG = [
"refactor: A code change that neither fixes a bug nor adds a feature",
r"refactor(cz/connventional_commit): use \S to check scope",
"refactor(git): remove unnecessary dot between git range",
"bump: version 1.16.3 → 1.16.4",
(
"Merge pull request #139 from Lee-W/fix-init-clean-config-file\n"
"Fix init clean config file"
),
"ci(pyproject.toml): add configuration for coverage",
"fix(commands/init): fix clean up file when initialize commitizen config\n#138",
"refactor(defaults): split config files into long term support and deprecated ones",
"bump: version 1.16.2 → 1.16.3",
(
"Merge pull request #136 from Lee-W/remove-redundant-readme\n"
"Remove redundant readme"
),
"fix: replace README.rst with docs/README.md in config files",
(
"refactor(docs): remove README.rst and use docs/README.md\n"
"By removing README.rst, we no longer need to maintain "
"two document with almost the same content\n"
"Github can read docs/README.md as README for the project."
),
"docs(check): pin pre-commit to v1.16.2",
"docs(check): fix pre-commit setup",
"bump: version 1.16.1 → 1.16.2",
"Merge pull request #135 from Lee-W/fix-pre-commit-hook\nFix pre commit hook",
"docs(check): enforce cz check only whem committing",
(
'Revert "fix(pre-commit): set pre-commit check stage to commit-msg"\n'
"This reverts commit afc70133e4a81344928561fbf3bb20738dfc8a0b."
),
]


def _build_fake_git_commits(commit_msgs: List[str]) -> List[git.GitCommit]:
return [git.GitCommit("test_rev", commit_msg) for commit_msg in commit_msgs]


def test_check_jira_fails(mocker, capsys):
Expand Down Expand Up @@ -115,4 +154,43 @@ def test_check_conventional_commit(commit_msg, config, mocker, tmpdir):

def test_check_command_when_commit_file_not_found(config):
with pytest.raises(FileNotFoundError):
commands.Check(config=config, arguments={"commit_msg_file": ""})()
commands.Check(config=config, arguments={"commit_msg_file": "no_such_file"})()


def test_check_a_range_of_git_commits(config, mocker):
success_mock = mocker.patch("commitizen.out.success")
mocker.patch(
"commitizen.git.get_commits", return_value=_build_fake_git_commits(COMMIT_LOG)
)

check_cmd = commands.Check(
config=config, arguments={"rev_range": "HEAD~10..master"}
)

check_cmd()
success_mock.assert_called_once()


def test_check_a_range_of_git_commits_and_failed(config, mocker):
error_mock = mocker.patch("commitizen.out.error")
mocker.patch(
"commitizen.git.get_commits",
return_value=_build_fake_git_commits(["This commit does not follow rule"]),
)
check_cmd = commands.Check(
config=config, arguments={"rev_range": "HEAD~10..master"}
)

with pytest.raises(SystemExit):
check_cmd()
error_mock.assert_called_once()


@pytest.mark.parametrize(
"args", [{"rev_range": "HEAD~10..master", "commit_msg_file": "some_file"}, {}]
)
def test_check_command_with_invalid_argment(args, config, capsys):
with pytest.raises(SystemExit):
commands.Check(config=config, arguments=args)
_, err = capsys.readouterr()
assert "One and only one argument is required for check command!" in err
Loading