conventional-pre-commit 3.2.0__tar.gz → 3.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.pre-commit-config.yaml +4 -4
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/PKG-INFO +8 -7
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/README.md +7 -6
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/format.py +23 -9
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/hook.py +11 -1
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/PKG-INFO +8 -7
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/SOURCES.txt +1 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/conftest.py +5 -0
- conventional_pre_commit-3.4.0/tests/messages/conventional_commit_with_multiple_scopes +1 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/run.sh +1 -1
- conventional_pre_commit-3.4.0/tests/test_format.py +586 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/test_hook.py +10 -0
- conventional_pre_commit-3.2.0/tests/test_format.py +0 -368
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.devcontainer/Dockerfile +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.devcontainer/compose.yml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.devcontainer/devcontainer.json +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.dockerignore +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.flake8 +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.github/dependabot.yaml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.github/workflows/release.yml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.github/workflows/tests.yml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.gitignore +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.pre-commit-hooks.yaml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.vscode/settings.json +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/LICENSE +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/__init__.py +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/dependency_links.txt +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/entry_points.txt +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/requires.txt +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit.egg-info/top_level.txt +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/pyproject.toml +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/setup.cfg +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/__init__.py +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/bad_commit +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit_bad_multi_line +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit_gbk +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit_multi_line +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit_utf-8 +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit_with_scope +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/custom_commit +0 -0
- {conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/fixup_commit +0 -0
|
@@ -8,7 +8,7 @@ default_install_hook_types:
|
|
|
8
8
|
|
|
9
9
|
repos:
|
|
10
10
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
11
|
-
rev: v4.
|
|
11
|
+
rev: v4.6.0
|
|
12
12
|
hooks:
|
|
13
13
|
- id: trailing-whitespace
|
|
14
14
|
- id: mixed-line-ending
|
|
@@ -18,21 +18,21 @@ repos:
|
|
|
18
18
|
- id: check-added-large-files
|
|
19
19
|
|
|
20
20
|
- repo: https://github.com/psf/black
|
|
21
|
-
rev: 24.
|
|
21
|
+
rev: 24.4.2
|
|
22
22
|
hooks:
|
|
23
23
|
- id: black
|
|
24
24
|
types:
|
|
25
25
|
- python
|
|
26
26
|
|
|
27
27
|
- repo: https://github.com/PyCQA/flake8
|
|
28
|
-
rev: 7.
|
|
28
|
+
rev: 7.1.0
|
|
29
29
|
hooks:
|
|
30
30
|
- id: flake8
|
|
31
31
|
types:
|
|
32
32
|
- python
|
|
33
33
|
|
|
34
34
|
- repo: https://github.com/pycqa/bandit
|
|
35
|
-
rev: 1.7.
|
|
35
|
+
rev: 1.7.9
|
|
36
36
|
hooks:
|
|
37
37
|
- id: bandit
|
|
38
38
|
args: ["-ll"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conventional_pre_commit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0
|
|
4
4
|
Summary: A pre-commit hook that checks commit messages for Conventional Commits formatting.
|
|
5
5
|
Author-email: Compiler LLC <dev@compiler.la>
|
|
6
6
|
License: Apache License
|
|
@@ -352,18 +352,19 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
352
352
|
|
|
353
353
|
```shell
|
|
354
354
|
$ conventional-pre-commit -h
|
|
355
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--strict] [types ...] input
|
|
355
|
+
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
356
356
|
|
|
357
357
|
Check a git commit message for Conventional Commits formatting.
|
|
358
358
|
|
|
359
359
|
positional arguments:
|
|
360
|
-
types
|
|
361
|
-
input
|
|
360
|
+
types Optional list of types to support
|
|
361
|
+
input A file containing a git commit message
|
|
362
362
|
|
|
363
363
|
options:
|
|
364
|
-
-h, --help
|
|
365
|
-
--force-scope
|
|
366
|
-
--
|
|
364
|
+
-h, --help show this help message and exit
|
|
365
|
+
--force-scope Force commit to have scope defined.
|
|
366
|
+
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
367
|
+
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
367
368
|
```
|
|
368
369
|
|
|
369
370
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
|
@@ -129,18 +129,19 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
129
129
|
|
|
130
130
|
```shell
|
|
131
131
|
$ conventional-pre-commit -h
|
|
132
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--strict] [types ...] input
|
|
132
|
+
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
133
133
|
|
|
134
134
|
Check a git commit message for Conventional Commits formatting.
|
|
135
135
|
|
|
136
136
|
positional arguments:
|
|
137
|
-
types
|
|
138
|
-
input
|
|
137
|
+
types Optional list of types to support
|
|
138
|
+
input A file containing a git commit message
|
|
139
139
|
|
|
140
140
|
options:
|
|
141
|
-
-h, --help
|
|
142
|
-
--force-scope
|
|
143
|
-
--
|
|
141
|
+
-h, --help show this help message and exit
|
|
142
|
+
--force-scope Force commit to have scope defined.
|
|
143
|
+
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
144
|
+
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/format.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
|
+
from typing import List, Optional
|
|
2
3
|
|
|
3
4
|
CONVENTIONAL_TYPES = ["feat", "fix"]
|
|
4
5
|
DEFAULT_TYPES = [
|
|
@@ -26,8 +27,20 @@ def r_types(types):
|
|
|
26
27
|
return "|".join(types)
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
def
|
|
30
|
+
def _get_scope_pattern(scopes: Optional[List[str]] = None):
|
|
31
|
+
scopes_str = r_types(scopes)
|
|
32
|
+
escaped_delimiters = list(map(re.escape, [":", ",", "-", "/"])) # type: ignore
|
|
33
|
+
delimiters_pattern = r_types(escaped_delimiters)
|
|
34
|
+
return rf"\(\s*(?:{scopes_str})(?:\s*(?:{delimiters_pattern})\s*(?:{scopes_str}))*\s*\)"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def r_scope(optional=True, scopes: Optional[List[str]] = None):
|
|
30
38
|
"""Regex str for an optional (scope)."""
|
|
39
|
+
|
|
40
|
+
if scopes:
|
|
41
|
+
scopes_pattern = _get_scope_pattern(scopes)
|
|
42
|
+
return scopes_pattern
|
|
43
|
+
|
|
31
44
|
if optional:
|
|
32
45
|
return r"(\([\w \/:,-]+\))?"
|
|
33
46
|
else:
|
|
@@ -54,13 +67,14 @@ def r_autosquash_prefixes():
|
|
|
54
67
|
return "|".join(AUTOSQUASH_PREFIXES)
|
|
55
68
|
|
|
56
69
|
|
|
57
|
-
def
|
|
58
|
-
"""Regex str for verbose
|
|
59
|
-
return r"
|
|
70
|
+
def r_verbose_commit_ignored():
|
|
71
|
+
"""Regex str for the ignored part of verbose commit message templates"""
|
|
72
|
+
return r"^# -{24} >8 -{24}\r?\n.*\Z"
|
|
60
73
|
|
|
61
74
|
|
|
62
|
-
def
|
|
63
|
-
|
|
75
|
+
def strip_verbose_commit_ignored(input):
|
|
76
|
+
"""Strip the ignored part of verbose commit message templates."""
|
|
77
|
+
return re.sub(r_verbose_commit_ignored(), "", input, flags=re.DOTALL | re.MULTILINE)
|
|
64
78
|
|
|
65
79
|
|
|
66
80
|
def r_comment():
|
|
@@ -79,17 +93,17 @@ def conventional_types(types=[]):
|
|
|
79
93
|
return types
|
|
80
94
|
|
|
81
95
|
|
|
82
|
-
def is_conventional(input, types=DEFAULT_TYPES, optional_scope=True):
|
|
96
|
+
def is_conventional(input, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
|
|
83
97
|
"""
|
|
84
98
|
Returns True if input matches Conventional Commits formatting
|
|
85
99
|
https://www.conventionalcommits.org
|
|
86
100
|
|
|
87
101
|
Optionally provide a list of additional custom types.
|
|
88
102
|
"""
|
|
89
|
-
input =
|
|
103
|
+
input = strip_verbose_commit_ignored(input)
|
|
90
104
|
input = strip_comments(input)
|
|
91
105
|
types = conventional_types(types)
|
|
92
|
-
pattern = f"^({r_types(types)}){r_scope(optional_scope)}{r_delim()}{r_subject()}{r_body()}"
|
|
106
|
+
pattern = f"^({r_types(types)}){r_scope(optional_scope, scopes=scopes)}{r_delim()}{r_subject()}{r_body()}"
|
|
93
107
|
regex = re.compile(pattern, re.MULTILINE)
|
|
94
108
|
|
|
95
109
|
result = regex.match(input)
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/hook.py
RENAMED
|
@@ -23,6 +23,12 @@ def main(argv=[]):
|
|
|
23
23
|
parser.add_argument(
|
|
24
24
|
"--force-scope", action="store_false", default=True, dest="optional_scope", help="Force commit to have scope defined."
|
|
25
25
|
)
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
"--scopes",
|
|
28
|
+
type=str,
|
|
29
|
+
default=None,
|
|
30
|
+
help="Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)",
|
|
31
|
+
)
|
|
26
32
|
parser.add_argument(
|
|
27
33
|
"--strict",
|
|
28
34
|
action="store_true",
|
|
@@ -51,12 +57,16 @@ See {Colors.LBLUE}https://git-scm.com/docs/git-commit/#_discussion{Colors.RESTOR
|
|
|
51
57
|
"""
|
|
52
58
|
)
|
|
53
59
|
return RESULT_FAIL
|
|
60
|
+
if args.scopes:
|
|
61
|
+
scopes = args.scopes.split(",")
|
|
62
|
+
else:
|
|
63
|
+
scopes = args.scopes
|
|
54
64
|
|
|
55
65
|
if not args.strict:
|
|
56
66
|
if format.has_autosquash_prefix(message):
|
|
57
67
|
return RESULT_SUCCESS
|
|
58
68
|
|
|
59
|
-
if format.is_conventional(message, args.types, args.optional_scope):
|
|
69
|
+
if format.is_conventional(message, args.types, args.optional_scope, scopes):
|
|
60
70
|
return RESULT_SUCCESS
|
|
61
71
|
else:
|
|
62
72
|
print(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conventional_pre_commit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.4.0
|
|
4
4
|
Summary: A pre-commit hook that checks commit messages for Conventional Commits formatting.
|
|
5
5
|
Author-email: Compiler LLC <dev@compiler.la>
|
|
6
6
|
License: Apache License
|
|
@@ -352,18 +352,19 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
352
352
|
|
|
353
353
|
```shell
|
|
354
354
|
$ conventional-pre-commit -h
|
|
355
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--strict] [types ...] input
|
|
355
|
+
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
356
356
|
|
|
357
357
|
Check a git commit message for Conventional Commits formatting.
|
|
358
358
|
|
|
359
359
|
positional arguments:
|
|
360
|
-
types
|
|
361
|
-
input
|
|
360
|
+
types Optional list of types to support
|
|
361
|
+
input A file containing a git commit message
|
|
362
362
|
|
|
363
363
|
options:
|
|
364
|
-
-h, --help
|
|
365
|
-
--force-scope
|
|
366
|
-
--
|
|
364
|
+
-h, --help show this help message and exit
|
|
365
|
+
--force-scope Force commit to have scope defined.
|
|
366
|
+
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
367
|
+
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
367
368
|
```
|
|
368
369
|
|
|
369
370
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
|
@@ -33,6 +33,7 @@ tests/messages/conventional_commit_bad_multi_line
|
|
|
33
33
|
tests/messages/conventional_commit_gbk
|
|
34
34
|
tests/messages/conventional_commit_multi_line
|
|
35
35
|
tests/messages/conventional_commit_utf-8
|
|
36
|
+
tests/messages/conventional_commit_with_multiple_scopes
|
|
36
37
|
tests/messages/conventional_commit_with_scope
|
|
37
38
|
tests/messages/custom_commit
|
|
38
39
|
tests/messages/fixup_commit
|
|
@@ -52,3 +52,8 @@ def conventional_commit_bad_multi_line_path():
|
|
|
52
52
|
@pytest.fixture
|
|
53
53
|
def conventional_commit_multi_line_path():
|
|
54
54
|
return get_message_path("conventional_commit_multi_line")
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.fixture
|
|
58
|
+
def conventional_commit_with_multiple_scopes_path():
|
|
59
|
+
return get_message_path("conventional_commit_with_multiple_scopes")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
feat(api,client): added new endpoint with client support
|
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from conventional_pre_commit import format
|
|
6
|
+
|
|
7
|
+
CUSTOM_TYPES = ["one", "two"]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_r_types():
|
|
11
|
+
result = format.r_types(CUSTOM_TYPES)
|
|
12
|
+
regex = re.compile(result)
|
|
13
|
+
|
|
14
|
+
assert regex.match("one")
|
|
15
|
+
assert regex.match("two")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_r_scope__optional():
|
|
19
|
+
result = format.r_scope()
|
|
20
|
+
regex = re.compile(result)
|
|
21
|
+
|
|
22
|
+
assert regex.match("")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_r_scope__not_optional():
|
|
26
|
+
result = format.r_scope(optional=False)
|
|
27
|
+
regex = re.compile(result)
|
|
28
|
+
|
|
29
|
+
# Assert not optional anymore
|
|
30
|
+
assert not regex.match("")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_r_scope__parenthesis_required():
|
|
34
|
+
result = format.r_scope()
|
|
35
|
+
regex = re.compile(result)
|
|
36
|
+
|
|
37
|
+
# without parens produces a match object with a 0 span
|
|
38
|
+
# since the (scope) is optional
|
|
39
|
+
without_parens = regex.match("something")
|
|
40
|
+
assert without_parens.span() == (0, 0)
|
|
41
|
+
|
|
42
|
+
# with parens produces a match object with a span
|
|
43
|
+
# that covers the input string
|
|
44
|
+
with_parens = regex.match("(something)")
|
|
45
|
+
assert with_parens.span() == (0, 11)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_r_scope__alphanumeric():
|
|
49
|
+
result = format.r_scope()
|
|
50
|
+
regex = re.compile(result)
|
|
51
|
+
|
|
52
|
+
assert regex.match("(50m3t41N6)")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_r_scope__special_chars():
|
|
56
|
+
result = format.r_scope()
|
|
57
|
+
regex = re.compile(result)
|
|
58
|
+
|
|
59
|
+
assert regex.match("(some-thing)")
|
|
60
|
+
assert regex.match("(some_thing)")
|
|
61
|
+
assert regex.match("(some/thing)")
|
|
62
|
+
assert regex.match("(some thing)")
|
|
63
|
+
assert regex.match("(some:thing)")
|
|
64
|
+
assert regex.match("(some,thing)")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_r_scope__scopes():
|
|
68
|
+
scopes_input = ["api", "client"]
|
|
69
|
+
result = format.r_scope(scopes=scopes_input)
|
|
70
|
+
regex = re.compile(result)
|
|
71
|
+
assert regex.match("(api)")
|
|
72
|
+
assert regex.match("(client)")
|
|
73
|
+
assert regex.match("(api, client)")
|
|
74
|
+
assert regex.match("(api: client)")
|
|
75
|
+
assert regex.match("(api/client)")
|
|
76
|
+
assert regex.match("(api-client)")
|
|
77
|
+
assert not regex.match("(test)")
|
|
78
|
+
assert not regex.match("(api; client)")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_r_delim():
|
|
82
|
+
result = format.r_delim()
|
|
83
|
+
regex = re.compile(result)
|
|
84
|
+
|
|
85
|
+
assert regex.match(":")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_r_delim__optional_breaking_indicator():
|
|
89
|
+
result = format.r_delim()
|
|
90
|
+
regex = re.compile(result)
|
|
91
|
+
|
|
92
|
+
assert regex.match("!:")
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_r_subject__starts_with_space():
|
|
96
|
+
result = format.r_subject()
|
|
97
|
+
regex = re.compile(result)
|
|
98
|
+
|
|
99
|
+
assert not regex.match("something")
|
|
100
|
+
assert regex.match(" something")
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_r_subject__alphanumeric():
|
|
104
|
+
result = format.r_subject()
|
|
105
|
+
regex = re.compile(result)
|
|
106
|
+
|
|
107
|
+
assert regex.match(" 50m3t41N6")
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def test_r_subject__special_chars():
|
|
111
|
+
result = format.r_subject()
|
|
112
|
+
regex = re.compile(result)
|
|
113
|
+
|
|
114
|
+
assert regex.match(" some-thing")
|
|
115
|
+
assert regex.match(" some_thing")
|
|
116
|
+
assert regex.match(" some/thing")
|
|
117
|
+
assert regex.match(" some thing")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_r_autosquash_prefixes():
|
|
121
|
+
result = format.r_autosquash_prefixes()
|
|
122
|
+
regex = re.compile(result)
|
|
123
|
+
|
|
124
|
+
for prefix in format.AUTOSQUASH_PREFIXES:
|
|
125
|
+
assert regex.match(prefix)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_conventional_types__default():
|
|
129
|
+
result = format.conventional_types()
|
|
130
|
+
|
|
131
|
+
assert result == format.CONVENTIONAL_TYPES
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_conventional_types__custom():
|
|
135
|
+
result = format.conventional_types(["custom"])
|
|
136
|
+
|
|
137
|
+
assert set(["custom", *format.CONVENTIONAL_TYPES]) == set(result)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def test_r_comment_single():
|
|
141
|
+
regex = re.compile(format.r_comment())
|
|
142
|
+
assert regex.match("# Some comment")
|
|
143
|
+
assert not regex.match("Some comment")
|
|
144
|
+
assert not regex.match(" # Some comment")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_strip_comments__consecutive():
|
|
148
|
+
input = """feat(scope): message
|
|
149
|
+
# Please enter the commit message for your changes.
|
|
150
|
+
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
151
|
+
"""
|
|
152
|
+
result = format.strip_comments(input)
|
|
153
|
+
assert result.count("\n") == 1
|
|
154
|
+
assert result.strip() == "feat(scope): message"
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_strip_comments__spaced():
|
|
158
|
+
input = """feat(scope): message
|
|
159
|
+
# Please enter the commit message for your changes.
|
|
160
|
+
|
|
161
|
+
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
162
|
+
"""
|
|
163
|
+
result = format.strip_comments(input)
|
|
164
|
+
assert result.count("\n") == 2
|
|
165
|
+
assert result.strip() == "feat(scope): message"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def test_r_verbose_commit_ignored__does_not_match_no_verbose():
|
|
169
|
+
regex = re.compile(format.r_verbose_commit_ignored(), re.DOTALL | re.MULTILINE)
|
|
170
|
+
input = """feat: some commit message
|
|
171
|
+
# Please enter the commit message for your changes. Lines starting
|
|
172
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
173
|
+
#
|
|
174
|
+
# On branch main
|
|
175
|
+
# Your branch is up to date with 'origin/main'.
|
|
176
|
+
#
|
|
177
|
+
# Changes to be committed:
|
|
178
|
+
# modified: README.md
|
|
179
|
+
#
|
|
180
|
+
# Changes not staged for commit:
|
|
181
|
+
# modified: README.md
|
|
182
|
+
#
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
assert not regex.search(input)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def test_r_verbose_commit_ignored__matches_single_verbose_ignored():
|
|
189
|
+
regex = re.compile(format.r_verbose_commit_ignored(), re.DOTALL | re.MULTILINE)
|
|
190
|
+
input = (
|
|
191
|
+
"""feat: some commit message
|
|
192
|
+
# Please enter the commit message for your changes. Lines starting
|
|
193
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
194
|
+
#
|
|
195
|
+
# On branch main
|
|
196
|
+
# Your branch is up to date with 'origin/main'.
|
|
197
|
+
#
|
|
198
|
+
# Changes to be committed:
|
|
199
|
+
# modified: README.md
|
|
200
|
+
#
|
|
201
|
+
# Changes not staged for commit:
|
|
202
|
+
# modified: README.md
|
|
203
|
+
#
|
|
204
|
+
# ------------------------ >8 ------------------------
|
|
205
|
+
# Do not modify or remove the line above.
|
|
206
|
+
# Everything below it will be ignored.
|
|
207
|
+
diff --git c/README.md i/README.md
|
|
208
|
+
index ea80a93..fe8a527 100644
|
|
209
|
+
--- c/README.md
|
|
210
|
+
+++ i/README.md
|
|
211
|
+
@@ -20,3 +20,4 @@ Some hunk header
|
|
212
|
+
Context 1
|
|
213
|
+
"""
|
|
214
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
215
|
+
+ """
|
|
216
|
+
Context 2
|
|
217
|
+
+Added line
|
|
218
|
+
"""
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
assert regex.search(input)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def test_r_verbose_commit_ignored__matches_double_verbose_ignored():
|
|
225
|
+
regex = re.compile(format.r_verbose_commit_ignored(), re.DOTALL | re.MULTILINE)
|
|
226
|
+
input = (
|
|
227
|
+
"""feat: some commit message
|
|
228
|
+
# Please enter the commit message for your changes. Lines starting
|
|
229
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
230
|
+
#
|
|
231
|
+
# On branch main
|
|
232
|
+
# Your branch is up to date with 'origin/main'.
|
|
233
|
+
#
|
|
234
|
+
# Changes to be committed:
|
|
235
|
+
# modified: README.md
|
|
236
|
+
#
|
|
237
|
+
# Changes not staged for commit:
|
|
238
|
+
# modified: README.md
|
|
239
|
+
#
|
|
240
|
+
# ------------------------ >8 ------------------------
|
|
241
|
+
# Do not modify or remove the line above.
|
|
242
|
+
# Everything below it will be ignored.
|
|
243
|
+
#
|
|
244
|
+
# Changes to be committed:
|
|
245
|
+
diff --git c/README.md i/README.md
|
|
246
|
+
index ea80a93..fe8a527 100644
|
|
247
|
+
--- c/README.md
|
|
248
|
+
+++ i/README.md
|
|
249
|
+
@@ -20,3 +20,4 @@ Some staged hunk header
|
|
250
|
+
Staged Context 1
|
|
251
|
+
"""
|
|
252
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
253
|
+
+ """
|
|
254
|
+
Staged Context 2
|
|
255
|
+
+Staged added line
|
|
256
|
+
# --------------------------------------------------
|
|
257
|
+
# Changes not staged for commit:
|
|
258
|
+
diff --git i/README.md w/README.md
|
|
259
|
+
index fe8a527..1c00c14 100644
|
|
260
|
+
--- i/README.md
|
|
261
|
+
+++ w/README.md
|
|
262
|
+
@@ -10,6 +10,7 @@ Some unstaged hunk header
|
|
263
|
+
Context 1
|
|
264
|
+
Context 2
|
|
265
|
+
Context 3
|
|
266
|
+
-Removed line
|
|
267
|
+
+Added line
|
|
268
|
+
"""
|
|
269
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
270
|
+
+ """
|
|
271
|
+
Context 4
|
|
272
|
+
"""
|
|
273
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
274
|
+
+ """
|
|
275
|
+
"""
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
assert regex.search(input)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def test_strip_verbose_commit_ignored__does_not_strip_no_verbose():
|
|
282
|
+
input = """feat: some commit message
|
|
283
|
+
# Please enter the commit message for your changes. Lines starting
|
|
284
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
285
|
+
#
|
|
286
|
+
# On branch main
|
|
287
|
+
# Your branch is up to date with 'origin/main'.
|
|
288
|
+
#
|
|
289
|
+
# Changes to be committed:
|
|
290
|
+
# modified: README.md
|
|
291
|
+
#
|
|
292
|
+
# Changes not staged for commit:
|
|
293
|
+
# modified: README.md
|
|
294
|
+
#
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
expected = """feat: some commit message
|
|
298
|
+
# Please enter the commit message for your changes. Lines starting
|
|
299
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
300
|
+
#
|
|
301
|
+
# On branch main
|
|
302
|
+
# Your branch is up to date with 'origin/main'.
|
|
303
|
+
#
|
|
304
|
+
# Changes to be committed:
|
|
305
|
+
# modified: README.md
|
|
306
|
+
#
|
|
307
|
+
# Changes not staged for commit:
|
|
308
|
+
# modified: README.md
|
|
309
|
+
#
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
result = format.strip_verbose_commit_ignored(input)
|
|
313
|
+
assert result == expected
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def test_strip_verbose_commit_ignored__strips_single_verbose_ignored():
|
|
317
|
+
input = (
|
|
318
|
+
"""feat: some commit message
|
|
319
|
+
# Please enter the commit message for your changes. Lines starting
|
|
320
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
321
|
+
#
|
|
322
|
+
# On branch main
|
|
323
|
+
# Your branch is up to date with 'origin/main'.
|
|
324
|
+
#
|
|
325
|
+
# Changes to be committed:
|
|
326
|
+
# modified: README.md
|
|
327
|
+
#
|
|
328
|
+
# Changes not staged for commit:
|
|
329
|
+
# modified: README.md
|
|
330
|
+
#
|
|
331
|
+
# ------------------------ >8 ------------------------
|
|
332
|
+
# Do not modify or remove the line above.
|
|
333
|
+
# Everything below it will be ignored.
|
|
334
|
+
diff --git c/README.md i/README.md
|
|
335
|
+
index ea80a93..fe8a527 100644
|
|
336
|
+
--- c/README.md
|
|
337
|
+
+++ i/README.md
|
|
338
|
+
@@ -20,3 +20,4 @@ Some hunk header
|
|
339
|
+
Context 1
|
|
340
|
+
"""
|
|
341
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
342
|
+
+ """
|
|
343
|
+
Context 2
|
|
344
|
+
+Added line
|
|
345
|
+
"""
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
expected = """feat: some commit message
|
|
349
|
+
# Please enter the commit message for your changes. Lines starting
|
|
350
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
351
|
+
#
|
|
352
|
+
# On branch main
|
|
353
|
+
# Your branch is up to date with 'origin/main'.
|
|
354
|
+
#
|
|
355
|
+
# Changes to be committed:
|
|
356
|
+
# modified: README.md
|
|
357
|
+
#
|
|
358
|
+
# Changes not staged for commit:
|
|
359
|
+
# modified: README.md
|
|
360
|
+
#
|
|
361
|
+
"""
|
|
362
|
+
|
|
363
|
+
result = format.strip_verbose_commit_ignored(input)
|
|
364
|
+
assert result == expected
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def test_strip_verbose_commit_ignored__strips_double_verbose_ignored():
|
|
368
|
+
input = (
|
|
369
|
+
"""feat: some commit message
|
|
370
|
+
# Please enter the commit message for your changes. Lines starting
|
|
371
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
372
|
+
#
|
|
373
|
+
# On branch main
|
|
374
|
+
# Your branch is up to date with 'origin/main'.
|
|
375
|
+
#
|
|
376
|
+
# Changes to be committed:
|
|
377
|
+
# modified: README.md
|
|
378
|
+
#
|
|
379
|
+
# Changes not staged for commit:
|
|
380
|
+
# modified: README.md
|
|
381
|
+
#
|
|
382
|
+
# ------------------------ >8 ------------------------
|
|
383
|
+
# Do not modify or remove the line above.
|
|
384
|
+
# Everything below it will be ignored.
|
|
385
|
+
#
|
|
386
|
+
# Changes to be committed:
|
|
387
|
+
diff --git c/README.md i/README.md
|
|
388
|
+
index ea80a93..fe8a527 100644
|
|
389
|
+
--- c/README.md
|
|
390
|
+
+++ i/README.md
|
|
391
|
+
@@ -20,3 +20,4 @@ Some staged hunk header
|
|
392
|
+
Staged Context 1
|
|
393
|
+
"""
|
|
394
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
395
|
+
+ """
|
|
396
|
+
Staged Context 2
|
|
397
|
+
+Staged added line
|
|
398
|
+
# --------------------------------------------------
|
|
399
|
+
# Changes not staged for commit:
|
|
400
|
+
diff --git i/README.md w/README.md
|
|
401
|
+
index fe8a527..1c00c14 100644
|
|
402
|
+
--- i/README.md
|
|
403
|
+
+++ w/README.md
|
|
404
|
+
@@ -10,6 +10,7 @@ Some unstaged hunk header
|
|
405
|
+
Context 1
|
|
406
|
+
Context 2
|
|
407
|
+
Context 3
|
|
408
|
+
-Removed line
|
|
409
|
+
+Added line
|
|
410
|
+
"""
|
|
411
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
412
|
+
+ """
|
|
413
|
+
Context 4
|
|
414
|
+
"""
|
|
415
|
+
+ " " # This is on purpose to preserve the space from overly eager stripping.
|
|
416
|
+
+ """
|
|
417
|
+
"""
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
expected = """feat: some commit message
|
|
421
|
+
# Please enter the commit message for your changes. Lines starting
|
|
422
|
+
# with '#' will be ignored, and an empty message aborts the commit.
|
|
423
|
+
#
|
|
424
|
+
# On branch main
|
|
425
|
+
# Your branch is up to date with 'origin/main'.
|
|
426
|
+
#
|
|
427
|
+
# Changes to be committed:
|
|
428
|
+
# modified: README.md
|
|
429
|
+
#
|
|
430
|
+
# Changes not staged for commit:
|
|
431
|
+
# modified: README.md
|
|
432
|
+
#
|
|
433
|
+
"""
|
|
434
|
+
|
|
435
|
+
result = format.strip_verbose_commit_ignored(input)
|
|
436
|
+
assert result == expected
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
@pytest.mark.parametrize("type", format.DEFAULT_TYPES)
|
|
440
|
+
def test_is_conventional__default_type(type):
|
|
441
|
+
input = f"{type}: message"
|
|
442
|
+
|
|
443
|
+
assert format.is_conventional(input)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
@pytest.mark.parametrize("type", format.CONVENTIONAL_TYPES)
|
|
447
|
+
def test_is_conventional__conventional_type(type):
|
|
448
|
+
input = f"{type}: message"
|
|
449
|
+
|
|
450
|
+
assert format.is_conventional(input)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@pytest.mark.parametrize("type", CUSTOM_TYPES)
|
|
454
|
+
def test_is_conventional__custom_type(type):
|
|
455
|
+
input = f"{type}: message"
|
|
456
|
+
|
|
457
|
+
assert format.is_conventional(input, CUSTOM_TYPES)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
@pytest.mark.parametrize("type", format.CONVENTIONAL_TYPES)
|
|
461
|
+
def test_is_conventional__conventional_custom_type(type):
|
|
462
|
+
input = f"{type}: message"
|
|
463
|
+
|
|
464
|
+
assert format.is_conventional(input, CUSTOM_TYPES)
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def test_is_conventional__breaking_change():
|
|
468
|
+
input = "fix!: message"
|
|
469
|
+
|
|
470
|
+
assert format.is_conventional(input)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def test_is_conventional__with_scope():
|
|
474
|
+
input = "feat(scope): message"
|
|
475
|
+
|
|
476
|
+
assert format.is_conventional(input)
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def test_is_conventional__body_multiline_body_bad_type():
|
|
480
|
+
input = """wrong: message
|
|
481
|
+
|
|
482
|
+
more_message
|
|
483
|
+
"""
|
|
484
|
+
|
|
485
|
+
assert not format.is_conventional(input)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
def test_is_conventional__bad_body_multiline():
|
|
489
|
+
input = """feat(scope): message
|
|
490
|
+
more message
|
|
491
|
+
"""
|
|
492
|
+
|
|
493
|
+
assert not format.is_conventional(input)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def test_is_conventional__body_multiline():
|
|
497
|
+
input = """feat(scope): message
|
|
498
|
+
|
|
499
|
+
more message
|
|
500
|
+
"""
|
|
501
|
+
|
|
502
|
+
assert format.is_conventional(input)
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
def test_is_conventional__bad_body_multiline_paragraphs():
|
|
506
|
+
input = """feat(scope): message
|
|
507
|
+
more message
|
|
508
|
+
|
|
509
|
+
more body message
|
|
510
|
+
"""
|
|
511
|
+
|
|
512
|
+
assert not format.is_conventional(input)
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
def test_is_conventional__comment():
|
|
516
|
+
input = """feat(scope): message
|
|
517
|
+
# Please enter the commit message for your changes.
|
|
518
|
+
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
519
|
+
"""
|
|
520
|
+
assert format.is_conventional(input)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
@pytest.mark.parametrize("char", ['"', "'", "`", "#", "&"])
|
|
524
|
+
def test_is_conventional__body_special_char(char):
|
|
525
|
+
input = f"feat: message with {char}"
|
|
526
|
+
|
|
527
|
+
assert format.is_conventional(input)
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def test_is_conventional__wrong_type():
|
|
531
|
+
input = "wrong: message"
|
|
532
|
+
|
|
533
|
+
assert not format.is_conventional(input)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
def test_is_conventional__scope_special_chars():
|
|
537
|
+
input = "feat(%&*@()): message"
|
|
538
|
+
|
|
539
|
+
assert not format.is_conventional(input)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def test_is_conventional__space_scope():
|
|
543
|
+
input = "feat (scope): message"
|
|
544
|
+
|
|
545
|
+
assert not format.is_conventional(input)
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
def test_is_conventional__scope_space():
|
|
549
|
+
input = "feat(scope) : message"
|
|
550
|
+
|
|
551
|
+
assert not format.is_conventional(input)
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def test_is_conventional__scope_not_optional():
|
|
555
|
+
input = "feat: message"
|
|
556
|
+
|
|
557
|
+
assert not format.is_conventional(input, optional_scope=False)
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
def test_is_conventional__scope_not_optional_empty_parenthesis():
|
|
561
|
+
input = "feat(): message"
|
|
562
|
+
|
|
563
|
+
assert not format.is_conventional(input, optional_scope=False)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def test_is_conventional__missing_delimiter():
|
|
567
|
+
input = "feat message"
|
|
568
|
+
|
|
569
|
+
assert not format.is_conventional(input)
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
@pytest.mark.parametrize(
|
|
573
|
+
"input,has_prefix",
|
|
574
|
+
[
|
|
575
|
+
("amend! ", True),
|
|
576
|
+
("fixup! ", True),
|
|
577
|
+
("squash! ", True),
|
|
578
|
+
("squash! whatever .. $12 #", True),
|
|
579
|
+
("squash!", False),
|
|
580
|
+
(" squash! ", False),
|
|
581
|
+
("squash!:", False),
|
|
582
|
+
("feat(foo):", False),
|
|
583
|
+
],
|
|
584
|
+
)
|
|
585
|
+
def test_has_autosquash_prefix(input, has_prefix):
|
|
586
|
+
assert format.has_autosquash_prefix(input) == has_prefix
|
|
@@ -142,6 +142,16 @@ def test_subprocess_success__conventional_with_scope(cmd, conventional_commit_wi
|
|
|
142
142
|
assert result == RESULT_SUCCESS
|
|
143
143
|
|
|
144
144
|
|
|
145
|
+
def test_subprocess_success__conventional_with_multiple_scopes(cmd, conventional_commit_with_multiple_scopes_path):
|
|
146
|
+
result = subprocess.call((cmd, "--scopes", "api,client", conventional_commit_with_multiple_scopes_path))
|
|
147
|
+
assert result == RESULT_SUCCESS
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_subprocess_fail__conventional_with_multiple_scopes(cmd, conventional_commit_with_multiple_scopes_path):
|
|
151
|
+
result = subprocess.call((cmd, "--scopes", "api", conventional_commit_with_multiple_scopes_path))
|
|
152
|
+
assert result == RESULT_FAIL
|
|
153
|
+
|
|
154
|
+
|
|
145
155
|
def test_subprocess_success__fixup_commit(cmd, fixup_commit_path):
|
|
146
156
|
result = subprocess.call((cmd, fixup_commit_path))
|
|
147
157
|
|
|
@@ -1,368 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from conventional_pre_commit import format
|
|
6
|
-
|
|
7
|
-
CUSTOM_TYPES = ["one", "two"]
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def test_r_types():
|
|
11
|
-
result = format.r_types(CUSTOM_TYPES)
|
|
12
|
-
regex = re.compile(result)
|
|
13
|
-
|
|
14
|
-
assert regex.match("one")
|
|
15
|
-
assert regex.match("two")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def test_r_scope__optional():
|
|
19
|
-
result = format.r_scope()
|
|
20
|
-
regex = re.compile(result)
|
|
21
|
-
|
|
22
|
-
assert regex.match("")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def test_r_scope__not_optional():
|
|
26
|
-
result = format.r_scope(optional=False)
|
|
27
|
-
regex = re.compile(result)
|
|
28
|
-
|
|
29
|
-
# Assert not optional anymore
|
|
30
|
-
assert not regex.match("")
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_r_scope__parenthesis_required():
|
|
34
|
-
result = format.r_scope()
|
|
35
|
-
regex = re.compile(result)
|
|
36
|
-
|
|
37
|
-
# without parens produces a match object with a 0 span
|
|
38
|
-
# since the (scope) is optional
|
|
39
|
-
without_parens = regex.match("something")
|
|
40
|
-
assert without_parens.span() == (0, 0)
|
|
41
|
-
|
|
42
|
-
# with parens produces a match object with a span
|
|
43
|
-
# that covers the input string
|
|
44
|
-
with_parens = regex.match("(something)")
|
|
45
|
-
assert with_parens.span() == (0, 11)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def test_r_scope__alphanumeric():
|
|
49
|
-
result = format.r_scope()
|
|
50
|
-
regex = re.compile(result)
|
|
51
|
-
|
|
52
|
-
assert regex.match("(50m3t41N6)")
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def test_r_scope__special_chars():
|
|
56
|
-
result = format.r_scope()
|
|
57
|
-
regex = re.compile(result)
|
|
58
|
-
|
|
59
|
-
assert regex.match("(some-thing)")
|
|
60
|
-
assert regex.match("(some_thing)")
|
|
61
|
-
assert regex.match("(some/thing)")
|
|
62
|
-
assert regex.match("(some thing)")
|
|
63
|
-
assert regex.match("(some:thing)")
|
|
64
|
-
assert regex.match("(some,thing)")
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def test_r_delim():
|
|
68
|
-
result = format.r_delim()
|
|
69
|
-
regex = re.compile(result)
|
|
70
|
-
|
|
71
|
-
assert regex.match(":")
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def test_r_delim__optional_breaking_indicator():
|
|
75
|
-
result = format.r_delim()
|
|
76
|
-
regex = re.compile(result)
|
|
77
|
-
|
|
78
|
-
assert regex.match("!:")
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def test_r_subject__starts_with_space():
|
|
82
|
-
result = format.r_subject()
|
|
83
|
-
regex = re.compile(result)
|
|
84
|
-
|
|
85
|
-
assert not regex.match("something")
|
|
86
|
-
assert regex.match(" something")
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def test_r_subject__alphanumeric():
|
|
90
|
-
result = format.r_subject()
|
|
91
|
-
regex = re.compile(result)
|
|
92
|
-
|
|
93
|
-
assert regex.match(" 50m3t41N6")
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def test_r_subject__special_chars():
|
|
97
|
-
result = format.r_subject()
|
|
98
|
-
regex = re.compile(result)
|
|
99
|
-
|
|
100
|
-
assert regex.match(" some-thing")
|
|
101
|
-
assert regex.match(" some_thing")
|
|
102
|
-
assert regex.match(" some/thing")
|
|
103
|
-
assert regex.match(" some thing")
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def test_r_autosquash_prefixes():
|
|
107
|
-
result = format.r_autosquash_prefixes()
|
|
108
|
-
regex = re.compile(result)
|
|
109
|
-
|
|
110
|
-
for prefix in format.AUTOSQUASH_PREFIXES:
|
|
111
|
-
assert regex.match(prefix)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def test_conventional_types__default():
|
|
115
|
-
result = format.conventional_types()
|
|
116
|
-
|
|
117
|
-
assert result == format.CONVENTIONAL_TYPES
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def test_conventional_types__custom():
|
|
121
|
-
result = format.conventional_types(["custom"])
|
|
122
|
-
|
|
123
|
-
assert set(["custom", *format.CONVENTIONAL_TYPES]) == set(result)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def test_r_comment_single():
|
|
127
|
-
regex = re.compile(format.r_comment())
|
|
128
|
-
assert regex.match("# Some comment")
|
|
129
|
-
assert not regex.match("Some comment")
|
|
130
|
-
assert not regex.match(" # Some comment")
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def test_strip_comments__consecutive():
|
|
134
|
-
input = """feat(scope): message
|
|
135
|
-
# Please enter the commit message for your changes.
|
|
136
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
137
|
-
"""
|
|
138
|
-
result = format.strip_comments(input)
|
|
139
|
-
assert result.count("\n") == 1
|
|
140
|
-
assert result.strip() == "feat(scope): message"
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def test_strip_comments__spaced():
|
|
144
|
-
input = """feat(scope): message
|
|
145
|
-
# Please enter the commit message for your changes.
|
|
146
|
-
|
|
147
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
148
|
-
"""
|
|
149
|
-
result = format.strip_comments(input)
|
|
150
|
-
assert result.count("\n") == 2
|
|
151
|
-
assert result.strip() == "feat(scope): message"
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def test_r_verbose_diff__has_diff():
|
|
155
|
-
regex = re.compile(format.r_verbose_diff(), re.MULTILINE)
|
|
156
|
-
input = """# ----------- >8 -----------
|
|
157
|
-
# Some comment
|
|
158
|
-
# Some comment
|
|
159
|
-
diff --git a/file b/file
|
|
160
|
-
"""
|
|
161
|
-
|
|
162
|
-
assert regex.match(input)
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def test_r_verbose_diff__no_diff():
|
|
166
|
-
regex = re.compile(format.r_verbose_diff(), re.MULTILINE)
|
|
167
|
-
input = """# ----------- >8 -----------
|
|
168
|
-
# Some comment
|
|
169
|
-
# Some comment
|
|
170
|
-
"""
|
|
171
|
-
|
|
172
|
-
assert not regex.match(input)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
def test_r_verbose_diff__no_extra_comments():
|
|
176
|
-
regex = re.compile(format.r_verbose_diff(), re.MULTILINE)
|
|
177
|
-
input = """# ----------- >8 -----------
|
|
178
|
-
diff --git a/file b/file
|
|
179
|
-
"""
|
|
180
|
-
|
|
181
|
-
assert not regex.match(input)
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
def test_strip_verbose_diff__has_diff():
|
|
185
|
-
input = """feat(scope): message
|
|
186
|
-
# Please enter the commit message for your changes.
|
|
187
|
-
|
|
188
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
189
|
-
# ----------- >8 -----------
|
|
190
|
-
# Some comment
|
|
191
|
-
# Some comment
|
|
192
|
-
diff --git a/file b/file
|
|
193
|
-
"""
|
|
194
|
-
|
|
195
|
-
result = format.strip_verbose_diff(input)
|
|
196
|
-
assert result.count("\n") == 4
|
|
197
|
-
assert (
|
|
198
|
-
result
|
|
199
|
-
== """feat(scope): message
|
|
200
|
-
# Please enter the commit message for your changes.
|
|
201
|
-
|
|
202
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
203
|
-
"""
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
def test_strip_verbose_diff__no_diff():
|
|
208
|
-
input = """feat(scope): message
|
|
209
|
-
# Please enter the commit message for your changes.
|
|
210
|
-
|
|
211
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
212
|
-
# ----------- >8 -----------
|
|
213
|
-
# Some comment
|
|
214
|
-
# Some comment
|
|
215
|
-
"""
|
|
216
|
-
|
|
217
|
-
result = format.strip_verbose_diff(input)
|
|
218
|
-
assert result == input
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
@pytest.mark.parametrize("type", format.DEFAULT_TYPES)
|
|
222
|
-
def test_is_conventional__default_type(type):
|
|
223
|
-
input = f"{type}: message"
|
|
224
|
-
|
|
225
|
-
assert format.is_conventional(input)
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
@pytest.mark.parametrize("type", format.CONVENTIONAL_TYPES)
|
|
229
|
-
def test_is_conventional__conventional_type(type):
|
|
230
|
-
input = f"{type}: message"
|
|
231
|
-
|
|
232
|
-
assert format.is_conventional(input)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
@pytest.mark.parametrize("type", CUSTOM_TYPES)
|
|
236
|
-
def test_is_conventional__custom_type(type):
|
|
237
|
-
input = f"{type}: message"
|
|
238
|
-
|
|
239
|
-
assert format.is_conventional(input, CUSTOM_TYPES)
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
@pytest.mark.parametrize("type", format.CONVENTIONAL_TYPES)
|
|
243
|
-
def test_is_conventional__conventional_custom_type(type):
|
|
244
|
-
input = f"{type}: message"
|
|
245
|
-
|
|
246
|
-
assert format.is_conventional(input, CUSTOM_TYPES)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def test_is_conventional__breaking_change():
|
|
250
|
-
input = "fix!: message"
|
|
251
|
-
|
|
252
|
-
assert format.is_conventional(input)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def test_is_conventional__with_scope():
|
|
256
|
-
input = "feat(scope): message"
|
|
257
|
-
|
|
258
|
-
assert format.is_conventional(input)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
def test_is_conventional__body_multiline_body_bad_type():
|
|
262
|
-
input = """wrong: message
|
|
263
|
-
|
|
264
|
-
more_message
|
|
265
|
-
"""
|
|
266
|
-
|
|
267
|
-
assert not format.is_conventional(input)
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
def test_is_conventional__bad_body_multiline():
|
|
271
|
-
input = """feat(scope): message
|
|
272
|
-
more message
|
|
273
|
-
"""
|
|
274
|
-
|
|
275
|
-
assert not format.is_conventional(input)
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
def test_is_conventional__body_multiline():
|
|
279
|
-
input = """feat(scope): message
|
|
280
|
-
|
|
281
|
-
more message
|
|
282
|
-
"""
|
|
283
|
-
|
|
284
|
-
assert format.is_conventional(input)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
def test_is_conventional__bad_body_multiline_paragraphs():
|
|
288
|
-
input = """feat(scope): message
|
|
289
|
-
more message
|
|
290
|
-
|
|
291
|
-
more body message
|
|
292
|
-
"""
|
|
293
|
-
|
|
294
|
-
assert not format.is_conventional(input)
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
def test_is_conventional__comment():
|
|
298
|
-
input = """feat(scope): message
|
|
299
|
-
# Please enter the commit message for your changes.
|
|
300
|
-
# These are comments usually added by editors, f.ex. with export EDITOR=vim
|
|
301
|
-
"""
|
|
302
|
-
assert format.is_conventional(input)
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
@pytest.mark.parametrize("char", ['"', "'", "`", "#", "&"])
|
|
306
|
-
def test_is_conventional__body_special_char(char):
|
|
307
|
-
input = f"feat: message with {char}"
|
|
308
|
-
|
|
309
|
-
assert format.is_conventional(input)
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
def test_is_conventional__wrong_type():
|
|
313
|
-
input = "wrong: message"
|
|
314
|
-
|
|
315
|
-
assert not format.is_conventional(input)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
def test_is_conventional__scope_special_chars():
|
|
319
|
-
input = "feat(%&*@()): message"
|
|
320
|
-
|
|
321
|
-
assert not format.is_conventional(input)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
def test_is_conventional__space_scope():
|
|
325
|
-
input = "feat (scope): message"
|
|
326
|
-
|
|
327
|
-
assert not format.is_conventional(input)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
def test_is_conventional__scope_space():
|
|
331
|
-
input = "feat(scope) : message"
|
|
332
|
-
|
|
333
|
-
assert not format.is_conventional(input)
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
def test_is_conventional__scope_not_optional():
|
|
337
|
-
input = "feat: message"
|
|
338
|
-
|
|
339
|
-
assert not format.is_conventional(input, optional_scope=False)
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
def test_is_conventional__scope_not_optional_empty_parenthesis():
|
|
343
|
-
input = "feat(): message"
|
|
344
|
-
|
|
345
|
-
assert not format.is_conventional(input, optional_scope=False)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
def test_is_conventional__missing_delimiter():
|
|
349
|
-
input = "feat message"
|
|
350
|
-
|
|
351
|
-
assert not format.is_conventional(input)
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
@pytest.mark.parametrize(
|
|
355
|
-
"input,has_prefix",
|
|
356
|
-
[
|
|
357
|
-
("amend! ", True),
|
|
358
|
-
("fixup! ", True),
|
|
359
|
-
("squash! ", True),
|
|
360
|
-
("squash! whatever .. $12 #", True),
|
|
361
|
-
("squash!", False),
|
|
362
|
-
(" squash! ", False),
|
|
363
|
-
("squash!:", False),
|
|
364
|
-
("feat(foo):", False),
|
|
365
|
-
],
|
|
366
|
-
)
|
|
367
|
-
def test_has_autosquash_prefix(input, has_prefix):
|
|
368
|
-
assert format.has_autosquash_prefix(input) == has_prefix
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.devcontainer/devcontainer.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/.github/workflows/release.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/conventional_pre_commit/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/conventional_commit
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.2.0 → conventional_pre_commit-3.4.0}/tests/messages/custom_commit
RENAMED
|
File without changes
|
|
File without changes
|