conventional-pre-commit 3.4.0__tar.gz → 3.6.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.4.0 → conventional_pre_commit-3.6.0}/.pre-commit-config.yaml +5 -4
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/PKG-INFO +28 -16
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/README.md +27 -15
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit/format.py +43 -10
- conventional_pre_commit-3.6.0/conventional_pre_commit/hook.py +80 -0
- conventional_pre_commit-3.6.0/conventional_pre_commit/output.py +111 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/PKG-INFO +28 -16
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/SOURCES.txt +2 -0
- conventional_pre_commit-3.6.0/tests/messages/bad_commit +1 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/test_format.py +29 -1
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/test_hook.py +64 -0
- conventional_pre_commit-3.6.0/tests/test_output.py +121 -0
- conventional_pre_commit-3.4.0/conventional_pre_commit/hook.py +0 -106
- conventional_pre_commit-3.4.0/tests/messages/bad_commit +0 -1
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.devcontainer/Dockerfile +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.devcontainer/compose.yml +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.devcontainer/devcontainer.json +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.dockerignore +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.flake8 +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.github/dependabot.yaml +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.github/workflows/release.yml +10 -10
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.github/workflows/tests.yml +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.gitignore +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.pre-commit-hooks.yaml +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.vscode/settings.json +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/LICENSE +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit/__init__.py +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/dependency_links.txt +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/entry_points.txt +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/requires.txt +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit.egg-info/top_level.txt +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/pyproject.toml +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/setup.cfg +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/__init__.py +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/conftest.py +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_bad_multi_line +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_gbk +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_multi_line +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_utf-8 +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_with_multiple_scopes +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit_with_scope +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/custom_commit +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/messages/fixup_commit +0 -0
- {conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/tests/run.sh +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:
|
|
11
|
+
rev: v5.0.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.10.0
|
|
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.1.
|
|
28
|
+
rev: 7.1.1
|
|
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.10
|
|
36
36
|
hooks:
|
|
37
37
|
- id: bandit
|
|
38
38
|
args: ["-ll"]
|
|
@@ -51,3 +51,4 @@ repos:
|
|
|
51
51
|
entry: conventional-pre-commit
|
|
52
52
|
language: python
|
|
53
53
|
stages: [commit-msg]
|
|
54
|
+
args: [--verbose]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conventional_pre_commit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.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
|
|
@@ -269,33 +269,43 @@ Conventional Commit......................................................Failed
|
|
|
269
269
|
- duration: 0.07s
|
|
270
270
|
- exit code: 1
|
|
271
271
|
|
|
272
|
-
[Bad
|
|
273
|
-
|
|
272
|
+
[Bad commit message] >> add a new feature
|
|
274
273
|
Your commit message does not follow Conventional Commits formatting
|
|
275
274
|
https://www.conventionalcommits.org/
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
And with the `--verbose` arg:
|
|
276
278
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
+
```console
|
|
280
|
+
$ git commit -m "add a new feature"
|
|
279
281
|
|
|
280
|
-
|
|
282
|
+
[INFO] Initializing environment for ....
|
|
283
|
+
Conventional Commit......................................................Failed
|
|
284
|
+
- hook id: conventional-pre-commit
|
|
285
|
+
- duration: 0.07s
|
|
286
|
+
- exit code: 1
|
|
281
287
|
|
|
282
|
-
|
|
288
|
+
[Bad commit message] >> add a new feature
|
|
289
|
+
Your commit message does not follow Conventional Commits formatting
|
|
290
|
+
https://www.conventionalcommits.org/
|
|
283
291
|
|
|
284
|
-
|
|
292
|
+
Conventional Commit messages follow a pattern like:
|
|
285
293
|
|
|
286
|
-
|
|
294
|
+
type(scope): subject
|
|
287
295
|
|
|
288
|
-
|
|
296
|
+
extended body
|
|
289
297
|
|
|
290
|
-
|
|
298
|
+
Please correct the following errors:
|
|
291
299
|
|
|
292
|
-
|
|
300
|
+
- Expected value for 'type' but found none.
|
|
301
|
+
- Expected value for 'delim' but found none.
|
|
302
|
+
- Expected value for 'subject' but found none.
|
|
293
303
|
|
|
294
|
-
|
|
304
|
+
Run:
|
|
295
305
|
|
|
296
|
-
|
|
306
|
+
git commit --edit --file=.git/COMMIT_EDITMSG
|
|
297
307
|
|
|
298
|
-
|
|
308
|
+
to edit the commit message and retry the commit.
|
|
299
309
|
```
|
|
300
310
|
|
|
301
311
|
Make a (conventional) commit :heavy_check_mark::
|
|
@@ -352,7 +362,7 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
352
362
|
|
|
353
363
|
```shell
|
|
354
364
|
$ conventional-pre-commit -h
|
|
355
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
365
|
+
usage: conventional-pre-commit [-h] [--no-color] [--force-scope] [--scopes SCOPES] [--strict] [--verbose] [types ...] input
|
|
356
366
|
|
|
357
367
|
Check a git commit message for Conventional Commits formatting.
|
|
358
368
|
|
|
@@ -362,9 +372,11 @@ positional arguments:
|
|
|
362
372
|
|
|
363
373
|
options:
|
|
364
374
|
-h, --help show this help message and exit
|
|
375
|
+
--no-color Disable color in output.
|
|
365
376
|
--force-scope Force commit to have scope defined.
|
|
366
377
|
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
367
378
|
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
379
|
+
--verbose Print more verbose error output.
|
|
368
380
|
```
|
|
369
381
|
|
|
370
382
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
|
@@ -46,33 +46,43 @@ Conventional Commit......................................................Failed
|
|
|
46
46
|
- duration: 0.07s
|
|
47
47
|
- exit code: 1
|
|
48
48
|
|
|
49
|
-
[Bad
|
|
50
|
-
|
|
49
|
+
[Bad commit message] >> add a new feature
|
|
51
50
|
Your commit message does not follow Conventional Commits formatting
|
|
52
51
|
https://www.conventionalcommits.org/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
And with the `--verbose` arg:
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
```console
|
|
57
|
+
$ git commit -m "add a new feature"
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
[INFO] Initializing environment for ....
|
|
60
|
+
Conventional Commit......................................................Failed
|
|
61
|
+
- hook id: conventional-pre-commit
|
|
62
|
+
- duration: 0.07s
|
|
63
|
+
- exit code: 1
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
[Bad commit message] >> add a new feature
|
|
66
|
+
Your commit message does not follow Conventional Commits formatting
|
|
67
|
+
https://www.conventionalcommits.org/
|
|
60
68
|
|
|
61
|
-
|
|
69
|
+
Conventional Commit messages follow a pattern like:
|
|
62
70
|
|
|
63
|
-
|
|
71
|
+
type(scope): subject
|
|
64
72
|
|
|
65
|
-
|
|
73
|
+
extended body
|
|
66
74
|
|
|
67
|
-
|
|
75
|
+
Please correct the following errors:
|
|
68
76
|
|
|
69
|
-
|
|
77
|
+
- Expected value for 'type' but found none.
|
|
78
|
+
- Expected value for 'delim' but found none.
|
|
79
|
+
- Expected value for 'subject' but found none.
|
|
70
80
|
|
|
71
|
-
|
|
81
|
+
Run:
|
|
72
82
|
|
|
73
|
-
|
|
83
|
+
git commit --edit --file=.git/COMMIT_EDITMSG
|
|
74
84
|
|
|
75
|
-
|
|
85
|
+
to edit the commit message and retry the commit.
|
|
76
86
|
```
|
|
77
87
|
|
|
78
88
|
Make a (conventional) commit :heavy_check_mark::
|
|
@@ -129,7 +139,7 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
129
139
|
|
|
130
140
|
```shell
|
|
131
141
|
$ conventional-pre-commit -h
|
|
132
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
142
|
+
usage: conventional-pre-commit [-h] [--no-color] [--force-scope] [--scopes SCOPES] [--strict] [--verbose] [types ...] input
|
|
133
143
|
|
|
134
144
|
Check a git commit message for Conventional Commits formatting.
|
|
135
145
|
|
|
@@ -139,9 +149,11 @@ positional arguments:
|
|
|
139
149
|
|
|
140
150
|
options:
|
|
141
151
|
-h, --help show this help message and exit
|
|
152
|
+
--no-color Disable color in output.
|
|
142
153
|
--force-scope Force commit to have scope defined.
|
|
143
154
|
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
144
155
|
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
156
|
+
--verbose Print more verbose error output.
|
|
145
157
|
```
|
|
146
158
|
|
|
147
159
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
{conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/conventional_pre_commit/format.py
RENAMED
|
@@ -39,7 +39,10 @@ def r_scope(optional=True, scopes: Optional[List[str]] = None):
|
|
|
39
39
|
|
|
40
40
|
if scopes:
|
|
41
41
|
scopes_pattern = _get_scope_pattern(scopes)
|
|
42
|
-
|
|
42
|
+
if optional:
|
|
43
|
+
return f"(?:{scopes_pattern})?"
|
|
44
|
+
else:
|
|
45
|
+
return scopes_pattern
|
|
43
46
|
|
|
44
47
|
if optional:
|
|
45
48
|
return r"(\([\w \/:,-]+\))?"
|
|
@@ -93,22 +96,52 @@ def conventional_types(types=[]):
|
|
|
93
96
|
return types
|
|
94
97
|
|
|
95
98
|
|
|
96
|
-
def
|
|
99
|
+
def conventional_regex(types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
|
|
100
|
+
types = conventional_types(types)
|
|
101
|
+
|
|
102
|
+
types_pattern = f"^(?P<type>{r_types(types)})?"
|
|
103
|
+
scope_pattern = f"(?P<scope>{r_scope(optional_scope, scopes=scopes)})?"
|
|
104
|
+
delim_pattern = f"(?P<delim>{r_delim()})?"
|
|
105
|
+
subject_pattern = f"(?P<subject>{r_subject()})?"
|
|
106
|
+
body_pattern = f"(?P<body>{r_body()})?"
|
|
107
|
+
pattern = types_pattern + scope_pattern + delim_pattern + subject_pattern + body_pattern
|
|
108
|
+
|
|
109
|
+
return re.compile(pattern, re.MULTILINE)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def clean_input(input: str):
|
|
113
|
+
"""
|
|
114
|
+
Prepares an input message for conventional commits format check.
|
|
115
|
+
"""
|
|
116
|
+
input = strip_verbose_commit_ignored(input)
|
|
117
|
+
input = strip_comments(input)
|
|
118
|
+
return input
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def conventional_match(input: str, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None):
|
|
122
|
+
"""
|
|
123
|
+
Returns an `re.Match` object for the input against the Conventional Commits format.
|
|
124
|
+
"""
|
|
125
|
+
input = clean_input(input)
|
|
126
|
+
regex = conventional_regex(types, optional_scope, scopes)
|
|
127
|
+
return regex.match(input)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def is_conventional(input: str, types=DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None) -> bool:
|
|
97
131
|
"""
|
|
98
132
|
Returns True if input matches Conventional Commits formatting
|
|
99
133
|
https://www.conventionalcommits.org
|
|
100
134
|
|
|
101
135
|
Optionally provide a list of additional custom types.
|
|
102
136
|
"""
|
|
103
|
-
|
|
104
|
-
input = strip_comments(input)
|
|
105
|
-
types = conventional_types(types)
|
|
106
|
-
pattern = f"^({r_types(types)}){r_scope(optional_scope, scopes=scopes)}{r_delim()}{r_subject()}{r_body()}"
|
|
107
|
-
regex = re.compile(pattern, re.MULTILINE)
|
|
108
|
-
|
|
109
|
-
result = regex.match(input)
|
|
137
|
+
result = conventional_match(input, types, optional_scope, scopes)
|
|
110
138
|
is_valid = bool(result)
|
|
111
|
-
|
|
139
|
+
|
|
140
|
+
if result and result.group("multi") and not result.group("sep"):
|
|
141
|
+
is_valid = False
|
|
142
|
+
if result and not all(
|
|
143
|
+
[result.group("type"), optional_scope or result.group("scope"), result.group("delim"), result.group("subject")]
|
|
144
|
+
):
|
|
112
145
|
is_valid = False
|
|
113
146
|
|
|
114
147
|
return is_valid
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from conventional_pre_commit import format, output
|
|
5
|
+
|
|
6
|
+
RESULT_SUCCESS = 0
|
|
7
|
+
RESULT_FAIL = 1
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def main(argv=[]):
|
|
11
|
+
parser = argparse.ArgumentParser(
|
|
12
|
+
prog="conventional-pre-commit", description="Check a git commit message for Conventional Commits formatting."
|
|
13
|
+
)
|
|
14
|
+
parser.add_argument("types", type=str, nargs="*", default=format.DEFAULT_TYPES, help="Optional list of types to support")
|
|
15
|
+
parser.add_argument("input", type=str, help="A file containing a git commit message")
|
|
16
|
+
parser.add_argument("--no-color", action="store_false", default=True, dest="color", help="Disable color in output.")
|
|
17
|
+
parser.add_argument(
|
|
18
|
+
"--force-scope", action="store_false", default=True, dest="optional_scope", help="Force commit to have scope defined."
|
|
19
|
+
)
|
|
20
|
+
parser.add_argument(
|
|
21
|
+
"--scopes",
|
|
22
|
+
type=str,
|
|
23
|
+
default=None,
|
|
24
|
+
help="Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)",
|
|
25
|
+
)
|
|
26
|
+
parser.add_argument(
|
|
27
|
+
"--strict",
|
|
28
|
+
action="store_true",
|
|
29
|
+
help="Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.",
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"--verbose",
|
|
33
|
+
action="store_true",
|
|
34
|
+
dest="verbose",
|
|
35
|
+
default=False,
|
|
36
|
+
help="Print more verbose error output.",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
if len(argv) < 1:
|
|
40
|
+
argv = sys.argv[1:]
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
args = parser.parse_args(argv)
|
|
44
|
+
except SystemExit:
|
|
45
|
+
return RESULT_FAIL
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
with open(args.input, encoding="utf-8") as f:
|
|
49
|
+
commit_msg = f.read()
|
|
50
|
+
except UnicodeDecodeError:
|
|
51
|
+
print(output.unicode_decode_error(args.color))
|
|
52
|
+
return RESULT_FAIL
|
|
53
|
+
if args.scopes:
|
|
54
|
+
scopes = args.scopes.split(",")
|
|
55
|
+
else:
|
|
56
|
+
scopes = args.scopes
|
|
57
|
+
|
|
58
|
+
if not args.strict:
|
|
59
|
+
if format.has_autosquash_prefix(commit_msg):
|
|
60
|
+
return RESULT_SUCCESS
|
|
61
|
+
|
|
62
|
+
if format.is_conventional(commit_msg, args.types, args.optional_scope, scopes):
|
|
63
|
+
return RESULT_SUCCESS
|
|
64
|
+
|
|
65
|
+
print(output.fail(commit_msg, use_color=args.color))
|
|
66
|
+
|
|
67
|
+
if not args.verbose:
|
|
68
|
+
print(output.verbose_arg(use_color=args.color))
|
|
69
|
+
else:
|
|
70
|
+
print(
|
|
71
|
+
output.fail_verbose(
|
|
72
|
+
commit_msg, types=args.types, optional_scope=args.optional_scope, scopes=scopes, use_color=args.color
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return RESULT_FAIL
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
if __name__ == "__main__":
|
|
80
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
|
|
4
|
+
from conventional_pre_commit import format
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Colors:
|
|
8
|
+
LBLUE = "\033[00;34m"
|
|
9
|
+
LRED = "\033[01;31m"
|
|
10
|
+
RESTORE = "\033[0m"
|
|
11
|
+
YELLOW = "\033[00;33m"
|
|
12
|
+
|
|
13
|
+
def __init__(self, enabled=True):
|
|
14
|
+
self.enabled = enabled
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def blue(self):
|
|
18
|
+
return self.LBLUE if self.enabled else ""
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def red(self):
|
|
22
|
+
return self.LRED if self.enabled else ""
|
|
23
|
+
|
|
24
|
+
@property
|
|
25
|
+
def restore(self):
|
|
26
|
+
return self.RESTORE if self.enabled else ""
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def yellow(self):
|
|
30
|
+
return self.YELLOW if self.enabled else ""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def fail(commit_msg, use_color=True):
|
|
34
|
+
c = Colors(use_color)
|
|
35
|
+
lines = [
|
|
36
|
+
f"{c.red}[Bad commit message] >>{c.restore} {commit_msg}"
|
|
37
|
+
f"{c.yellow}Your commit message does not follow Conventional Commits formatting{c.restore}",
|
|
38
|
+
f"{c.blue}https://www.conventionalcommits.org/{c.restore}",
|
|
39
|
+
]
|
|
40
|
+
return os.linesep.join(lines)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def verbose_arg(use_color=True):
|
|
44
|
+
c = Colors(use_color)
|
|
45
|
+
lines = [
|
|
46
|
+
"",
|
|
47
|
+
f"{c.yellow}Use the {c.restore}--verbose{c.yellow} arg for more information{c.restore}",
|
|
48
|
+
]
|
|
49
|
+
return os.linesep.join(lines)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def fail_verbose(
|
|
53
|
+
commit_msg: str, types=format.DEFAULT_TYPES, optional_scope=True, scopes: Optional[List[str]] = None, use_color=True
|
|
54
|
+
):
|
|
55
|
+
c = Colors(use_color)
|
|
56
|
+
match = format.conventional_match(commit_msg, types, optional_scope, scopes)
|
|
57
|
+
lines = [
|
|
58
|
+
"",
|
|
59
|
+
f"{c.yellow}Conventional Commit messages follow a pattern like:",
|
|
60
|
+
"",
|
|
61
|
+
f"{c.restore} type(scope): subject",
|
|
62
|
+
"",
|
|
63
|
+
" extended body",
|
|
64
|
+
"",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
groups = match.groupdict() if match else {}
|
|
68
|
+
|
|
69
|
+
if optional_scope:
|
|
70
|
+
groups.pop("scope", None)
|
|
71
|
+
|
|
72
|
+
if not groups.get("body"):
|
|
73
|
+
groups.pop("body", None)
|
|
74
|
+
groups.pop("multi", None)
|
|
75
|
+
groups.pop("sep", None)
|
|
76
|
+
|
|
77
|
+
if groups.keys():
|
|
78
|
+
lines.append(f"{c.yellow}Please correct the following errors:{c.restore}")
|
|
79
|
+
lines.append("")
|
|
80
|
+
for group in [g for g, v in groups.items() if not v]:
|
|
81
|
+
if group == "scope":
|
|
82
|
+
if scopes:
|
|
83
|
+
scopt_opts = f"{c.yellow},{c.restore}".join(scopes)
|
|
84
|
+
lines.append(f"{c.yellow} - Expected value for {c.restore}scope{c.yellow} from: {c.restore}{scopt_opts}")
|
|
85
|
+
else:
|
|
86
|
+
lines.append(f"{c.yellow} - Expected value for {c.restore}scope{c.yellow} but found none.{c.restore}")
|
|
87
|
+
else:
|
|
88
|
+
lines.append(f"{c.yellow} - Expected value for {c.restore}{group}{c.yellow} but found none.{c.restore}")
|
|
89
|
+
|
|
90
|
+
lines.extend(
|
|
91
|
+
[
|
|
92
|
+
"",
|
|
93
|
+
f"{c.yellow}Run:{c.restore}",
|
|
94
|
+
"",
|
|
95
|
+
" git commit --edit --file=.git/COMMIT_EDITMSG",
|
|
96
|
+
"",
|
|
97
|
+
f"{c.yellow}to edit the commit message and retry the commit.{c.restore}",
|
|
98
|
+
]
|
|
99
|
+
)
|
|
100
|
+
return os.linesep.join(lines)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def unicode_decode_error(use_color=True):
|
|
104
|
+
c = Colors(use_color)
|
|
105
|
+
return f"""
|
|
106
|
+
{c.red}[Bad commit message encoding]{c.restore}
|
|
107
|
+
|
|
108
|
+
{c.yellow}conventional-pre-commit couldn't decode your commit message.
|
|
109
|
+
UTF-8 encoding is assumed, please configure git to write commit messages in UTF-8.
|
|
110
|
+
See {c.blue}https://git-scm.com/docs/git-commit/#_discussion{c.yellow} for more.{c.restore}
|
|
111
|
+
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: conventional_pre_commit
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.6.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
|
|
@@ -269,33 +269,43 @@ Conventional Commit......................................................Failed
|
|
|
269
269
|
- duration: 0.07s
|
|
270
270
|
- exit code: 1
|
|
271
271
|
|
|
272
|
-
[Bad
|
|
273
|
-
|
|
272
|
+
[Bad commit message] >> add a new feature
|
|
274
273
|
Your commit message does not follow Conventional Commits formatting
|
|
275
274
|
https://www.conventionalcommits.org/
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
And with the `--verbose` arg:
|
|
276
278
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
+
```console
|
|
280
|
+
$ git commit -m "add a new feature"
|
|
279
281
|
|
|
280
|
-
|
|
282
|
+
[INFO] Initializing environment for ....
|
|
283
|
+
Conventional Commit......................................................Failed
|
|
284
|
+
- hook id: conventional-pre-commit
|
|
285
|
+
- duration: 0.07s
|
|
286
|
+
- exit code: 1
|
|
281
287
|
|
|
282
|
-
|
|
288
|
+
[Bad commit message] >> add a new feature
|
|
289
|
+
Your commit message does not follow Conventional Commits formatting
|
|
290
|
+
https://www.conventionalcommits.org/
|
|
283
291
|
|
|
284
|
-
|
|
292
|
+
Conventional Commit messages follow a pattern like:
|
|
285
293
|
|
|
286
|
-
|
|
294
|
+
type(scope): subject
|
|
287
295
|
|
|
288
|
-
|
|
296
|
+
extended body
|
|
289
297
|
|
|
290
|
-
|
|
298
|
+
Please correct the following errors:
|
|
291
299
|
|
|
292
|
-
|
|
300
|
+
- Expected value for 'type' but found none.
|
|
301
|
+
- Expected value for 'delim' but found none.
|
|
302
|
+
- Expected value for 'subject' but found none.
|
|
293
303
|
|
|
294
|
-
|
|
304
|
+
Run:
|
|
295
305
|
|
|
296
|
-
|
|
306
|
+
git commit --edit --file=.git/COMMIT_EDITMSG
|
|
297
307
|
|
|
298
|
-
|
|
308
|
+
to edit the commit message and retry the commit.
|
|
299
309
|
```
|
|
300
310
|
|
|
301
311
|
Make a (conventional) commit :heavy_check_mark::
|
|
@@ -352,7 +362,7 @@ print(is_conventional("custom: this is a conventional commit", types=["custom"])
|
|
|
352
362
|
|
|
353
363
|
```shell
|
|
354
364
|
$ conventional-pre-commit -h
|
|
355
|
-
usage: conventional-pre-commit [-h] [--force-scope] [--scopes SCOPES] [--strict] [types ...] input
|
|
365
|
+
usage: conventional-pre-commit [-h] [--no-color] [--force-scope] [--scopes SCOPES] [--strict] [--verbose] [types ...] input
|
|
356
366
|
|
|
357
367
|
Check a git commit message for Conventional Commits formatting.
|
|
358
368
|
|
|
@@ -362,9 +372,11 @@ positional arguments:
|
|
|
362
372
|
|
|
363
373
|
options:
|
|
364
374
|
-h, --help show this help message and exit
|
|
375
|
+
--no-color Disable color in output.
|
|
365
376
|
--force-scope Force commit to have scope defined.
|
|
366
377
|
--scopes SCOPES Optional list of scopes to support. Scopes should be separated by commas with no spaces (e.g. api,client)
|
|
367
378
|
--strict Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.
|
|
379
|
+
--verbose Print more verbose error output.
|
|
368
380
|
```
|
|
369
381
|
|
|
370
382
|
Supply arguments on the command-line, or via the pre-commit `hooks.args` property:
|
|
@@ -16,6 +16,7 @@ pyproject.toml
|
|
|
16
16
|
conventional_pre_commit/__init__.py
|
|
17
17
|
conventional_pre_commit/format.py
|
|
18
18
|
conventional_pre_commit/hook.py
|
|
19
|
+
conventional_pre_commit/output.py
|
|
19
20
|
conventional_pre_commit.egg-info/PKG-INFO
|
|
20
21
|
conventional_pre_commit.egg-info/SOURCES.txt
|
|
21
22
|
conventional_pre_commit.egg-info/dependency_links.txt
|
|
@@ -27,6 +28,7 @@ tests/conftest.py
|
|
|
27
28
|
tests/run.sh
|
|
28
29
|
tests/test_format.py
|
|
29
30
|
tests/test_hook.py
|
|
31
|
+
tests/test_output.py
|
|
30
32
|
tests/messages/bad_commit
|
|
31
33
|
tests/messages/conventional_commit
|
|
32
34
|
tests/messages/conventional_commit_bad_multi_line
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bad message
|
|
@@ -66,7 +66,7 @@ def test_r_scope__special_chars():
|
|
|
66
66
|
|
|
67
67
|
def test_r_scope__scopes():
|
|
68
68
|
scopes_input = ["api", "client"]
|
|
69
|
-
result = format.r_scope(scopes=scopes_input)
|
|
69
|
+
result = format.r_scope(scopes=scopes_input, optional=False)
|
|
70
70
|
regex = re.compile(result)
|
|
71
71
|
assert regex.match("(api)")
|
|
72
72
|
assert regex.match("(client)")
|
|
@@ -436,6 +436,34 @@ index fe8a527..1c00c14 100644
|
|
|
436
436
|
assert result == expected
|
|
437
437
|
|
|
438
438
|
|
|
439
|
+
def test_conventional_regex():
|
|
440
|
+
regex = format.conventional_regex()
|
|
441
|
+
|
|
442
|
+
assert isinstance(regex, re.Pattern)
|
|
443
|
+
assert "type" in regex.groupindex
|
|
444
|
+
assert "scope" in regex.groupindex
|
|
445
|
+
assert "delim" in regex.groupindex
|
|
446
|
+
assert "subject" in regex.groupindex
|
|
447
|
+
assert "body" in regex.groupindex
|
|
448
|
+
assert "multi" in regex.groupindex
|
|
449
|
+
assert "sep" in regex.groupindex
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def test_conventional_match():
|
|
453
|
+
match = format.conventional_match(
|
|
454
|
+
"""test(scope): subject line
|
|
455
|
+
|
|
456
|
+
body copy
|
|
457
|
+
"""
|
|
458
|
+
)
|
|
459
|
+
assert match
|
|
460
|
+
assert match.group("type") == "test"
|
|
461
|
+
assert match.group("scope") == "(scope)"
|
|
462
|
+
assert match.group("delim") == ":"
|
|
463
|
+
assert match.group("subject").strip() == "subject line"
|
|
464
|
+
assert match.group("body").strip() == "body copy"
|
|
465
|
+
|
|
466
|
+
|
|
439
467
|
@pytest.mark.parametrize("type", format.DEFAULT_TYPES)
|
|
440
468
|
def test_is_conventional__default_type(type):
|
|
441
469
|
input = f"{type}: message"
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import subprocess
|
|
2
3
|
|
|
3
4
|
import pytest
|
|
4
5
|
|
|
5
6
|
from conventional_pre_commit.hook import RESULT_FAIL, RESULT_SUCCESS, main
|
|
7
|
+
from conventional_pre_commit.output import Colors
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
@pytest.fixture
|
|
@@ -94,6 +96,38 @@ def test_main_fail__conventional_commit_bad_multi_line(conventional_commit_bad_m
|
|
|
94
96
|
assert result == RESULT_FAIL
|
|
95
97
|
|
|
96
98
|
|
|
99
|
+
def test_main_fail__verbose(bad_commit_path, capsys):
|
|
100
|
+
result = main(["--verbose", "--force-scope", bad_commit_path])
|
|
101
|
+
|
|
102
|
+
assert result == RESULT_FAIL
|
|
103
|
+
|
|
104
|
+
captured = capsys.readouterr()
|
|
105
|
+
output = captured.out
|
|
106
|
+
|
|
107
|
+
assert Colors.LBLUE in output
|
|
108
|
+
assert Colors.LRED in output
|
|
109
|
+
assert Colors.RESTORE in output
|
|
110
|
+
assert Colors.YELLOW in output
|
|
111
|
+
assert "Conventional Commit messages follow a pattern like" in output
|
|
112
|
+
assert f"type(scope): subject{os.linesep}{os.linesep} extended body" in output
|
|
113
|
+
assert "git commit --edit --file=.git/COMMIT_EDITMSG" in output
|
|
114
|
+
assert "edit the commit message and retry the commit" in output
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_main_fail__no_color(bad_commit_path, capsys):
|
|
118
|
+
result = main(["--verbose", "--no-color", bad_commit_path])
|
|
119
|
+
|
|
120
|
+
assert result == RESULT_FAIL
|
|
121
|
+
|
|
122
|
+
captured = capsys.readouterr()
|
|
123
|
+
output = captured.out
|
|
124
|
+
|
|
125
|
+
assert Colors.LBLUE not in output
|
|
126
|
+
assert Colors.LRED not in output
|
|
127
|
+
assert Colors.RESTORE not in output
|
|
128
|
+
assert Colors.YELLOW not in output
|
|
129
|
+
|
|
130
|
+
|
|
97
131
|
def test_subprocess_fail__missing_args(cmd):
|
|
98
132
|
result = subprocess.call(cmd)
|
|
99
133
|
|
|
@@ -152,6 +186,36 @@ def test_subprocess_fail__conventional_with_multiple_scopes(cmd, conventional_co
|
|
|
152
186
|
assert result == RESULT_FAIL
|
|
153
187
|
|
|
154
188
|
|
|
189
|
+
def test_main_success__custom_scopes_optional_scope(conventional_commit_path):
|
|
190
|
+
result = main(["--scopes", "api,client", conventional_commit_path])
|
|
191
|
+
assert result == RESULT_SUCCESS
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def test_main_success__custom_scopes_with_allowed_scope(conventional_commit_with_multiple_scopes_path):
|
|
195
|
+
result = main(["--scopes", "chore,api,client", conventional_commit_with_multiple_scopes_path])
|
|
196
|
+
assert result == RESULT_SUCCESS
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def test_main_fail__custom_scopes_with_disallowed_scope(conventional_commit_with_scope_path):
|
|
200
|
+
result = main(["--scopes", "api,client", conventional_commit_with_scope_path])
|
|
201
|
+
assert result == RESULT_FAIL
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def test_main_fail__custom_scopes_require_scope_no_scope(conventional_commit_path):
|
|
205
|
+
result = main(["--scopes", "chore,feat,fix,custom", "--force-scope", conventional_commit_path])
|
|
206
|
+
assert result == RESULT_FAIL
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def test_main_success__custom_scopes_require_scope_with_allowed_scope(conventional_commit_with_scope_path):
|
|
210
|
+
result = main(["--scopes", "api,client,scope", "--force-scope", conventional_commit_with_scope_path])
|
|
211
|
+
assert result == RESULT_SUCCESS
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def test_main_fail__custom_scopes_require_scope_with_disallowed_scope(conventional_commit_with_scope_path):
|
|
215
|
+
result = main(["--scopes", "api,client", "--force-scope", conventional_commit_with_scope_path])
|
|
216
|
+
assert result == RESULT_FAIL
|
|
217
|
+
|
|
218
|
+
|
|
155
219
|
def test_subprocess_success__fixup_commit(cmd, fixup_commit_path):
|
|
156
220
|
result = subprocess.call((cmd, fixup_commit_path))
|
|
157
221
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from conventional_pre_commit.output import Colors, fail, fail_verbose, unicode_decode_error
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_colors():
|
|
6
|
+
colors = Colors()
|
|
7
|
+
|
|
8
|
+
assert colors.blue == colors.LBLUE
|
|
9
|
+
assert colors.red == colors.LRED
|
|
10
|
+
assert colors.restore == colors.RESTORE
|
|
11
|
+
assert colors.yellow == colors.YELLOW
|
|
12
|
+
|
|
13
|
+
colors = Colors(enabled=False)
|
|
14
|
+
|
|
15
|
+
assert colors.blue == ""
|
|
16
|
+
assert colors.red == ""
|
|
17
|
+
assert colors.restore == ""
|
|
18
|
+
assert colors.yellow == ""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_fail():
|
|
22
|
+
output = fail("commit msg")
|
|
23
|
+
|
|
24
|
+
assert Colors.LRED in output
|
|
25
|
+
assert Colors.YELLOW in output
|
|
26
|
+
assert Colors.LBLUE in output
|
|
27
|
+
assert Colors.RESTORE in output
|
|
28
|
+
|
|
29
|
+
assert "Bad commit message" in output
|
|
30
|
+
assert "commit msg" in output
|
|
31
|
+
assert "Conventional Commits formatting" in output
|
|
32
|
+
assert "https://www.conventionalcommits.org/" in output
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_fail__no_color():
|
|
36
|
+
output = fail("commit msg", use_color=False)
|
|
37
|
+
|
|
38
|
+
assert Colors.LRED not in output
|
|
39
|
+
assert Colors.YELLOW not in output
|
|
40
|
+
assert Colors.LBLUE not in output
|
|
41
|
+
assert Colors.RESTORE not in output
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_fail_verbose():
|
|
45
|
+
output = fail_verbose("commit msg", optional_scope=False)
|
|
46
|
+
|
|
47
|
+
assert Colors.YELLOW in output
|
|
48
|
+
assert Colors.RESTORE in output
|
|
49
|
+
|
|
50
|
+
output = output.replace(Colors.YELLOW, Colors.RESTORE).replace(Colors.RESTORE, "")
|
|
51
|
+
|
|
52
|
+
assert "Conventional Commit messages follow a pattern like" in output
|
|
53
|
+
assert f"type(scope): subject{os.linesep}{os.linesep} extended body" in output
|
|
54
|
+
assert "Expected value for type but found none." in output
|
|
55
|
+
assert "Expected value for delim but found none." in output
|
|
56
|
+
assert "Expected value for scope but found none." in output
|
|
57
|
+
assert "Expected value for subject but found none." in output
|
|
58
|
+
assert "git commit --edit --file=.git/COMMIT_EDITMSG" in output
|
|
59
|
+
assert "edit the commit message and retry the commit" in output
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_fail_verbose__no_color():
|
|
63
|
+
output = fail_verbose("commit msg", use_color=False)
|
|
64
|
+
|
|
65
|
+
assert Colors.LRED not in output
|
|
66
|
+
assert Colors.YELLOW not in output
|
|
67
|
+
assert Colors.LBLUE not in output
|
|
68
|
+
assert Colors.RESTORE not in output
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_fail_verbose__optional_scope():
|
|
72
|
+
output = fail_verbose("commit msg", optional_scope=True, use_color=False)
|
|
73
|
+
|
|
74
|
+
assert "Expected value for scope but found none." not in output
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_fail_verbose__missing_subject():
|
|
78
|
+
output = fail_verbose("feat(scope):", optional_scope=False, use_color=False)
|
|
79
|
+
|
|
80
|
+
assert "Expected value for subject but found none." in output
|
|
81
|
+
assert "Expected value for type but found none." not in output
|
|
82
|
+
assert "Expected value for scope but found none." not in output
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def test_fail_verbose__no_body_sep():
|
|
86
|
+
output = fail_verbose(
|
|
87
|
+
"""feat(scope): subject
|
|
88
|
+
body without blank line
|
|
89
|
+
""",
|
|
90
|
+
optional_scope=False,
|
|
91
|
+
use_color=False,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
assert "Expected value for sep but found none." in output
|
|
95
|
+
assert "Expected value for multi but found none." not in output
|
|
96
|
+
|
|
97
|
+
assert "Expected value for subject but found none." not in output
|
|
98
|
+
assert "Expected value for type but found none." not in output
|
|
99
|
+
assert "Expected value for scope but found none." not in output
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_unicode_decode_error():
|
|
103
|
+
output = unicode_decode_error()
|
|
104
|
+
|
|
105
|
+
assert Colors.LRED in output
|
|
106
|
+
assert Colors.YELLOW in output
|
|
107
|
+
assert Colors.LBLUE in output
|
|
108
|
+
assert Colors.RESTORE in output
|
|
109
|
+
|
|
110
|
+
assert "Bad commit message encoding" in output
|
|
111
|
+
assert "UTF-8 encoding is assumed" in output
|
|
112
|
+
assert "https://git-scm.com/docs/git-commit/#_discussion" in output
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_unicode_decode_error__no_color():
|
|
116
|
+
output = unicode_decode_error(use_color=False)
|
|
117
|
+
|
|
118
|
+
assert Colors.LRED not in output
|
|
119
|
+
assert Colors.YELLOW not in output
|
|
120
|
+
assert Colors.LBLUE not in output
|
|
121
|
+
assert Colors.RESTORE not in output
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import sys
|
|
3
|
-
|
|
4
|
-
from conventional_pre_commit import format
|
|
5
|
-
|
|
6
|
-
RESULT_SUCCESS = 0
|
|
7
|
-
RESULT_FAIL = 1
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class Colors:
|
|
11
|
-
LBLUE = "\033[00;34m"
|
|
12
|
-
LRED = "\033[01;31m"
|
|
13
|
-
RESTORE = "\033[0m"
|
|
14
|
-
YELLOW = "\033[00;33m"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def main(argv=[]):
|
|
18
|
-
parser = argparse.ArgumentParser(
|
|
19
|
-
prog="conventional-pre-commit", description="Check a git commit message for Conventional Commits formatting."
|
|
20
|
-
)
|
|
21
|
-
parser.add_argument("types", type=str, nargs="*", default=format.DEFAULT_TYPES, help="Optional list of types to support")
|
|
22
|
-
parser.add_argument("input", type=str, help="A file containing a git commit message")
|
|
23
|
-
parser.add_argument(
|
|
24
|
-
"--force-scope", action="store_false", default=True, dest="optional_scope", help="Force commit to have scope defined."
|
|
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
|
-
)
|
|
32
|
-
parser.add_argument(
|
|
33
|
-
"--strict",
|
|
34
|
-
action="store_true",
|
|
35
|
-
help="Force commit to strictly follow Conventional Commits formatting. Disallows fixup! style commits.",
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
if len(argv) < 1:
|
|
39
|
-
argv = sys.argv[1:]
|
|
40
|
-
|
|
41
|
-
try:
|
|
42
|
-
args = parser.parse_args(argv)
|
|
43
|
-
except SystemExit:
|
|
44
|
-
return RESULT_FAIL
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
with open(args.input, encoding="utf-8") as f:
|
|
48
|
-
message = f.read()
|
|
49
|
-
except UnicodeDecodeError:
|
|
50
|
-
print(
|
|
51
|
-
f"""
|
|
52
|
-
{Colors.LRED}[Bad Commit message encoding] {Colors.RESTORE}
|
|
53
|
-
|
|
54
|
-
{Colors.YELLOW}conventional-pre-commit couldn't decode your commit message.{Colors.RESTORE}
|
|
55
|
-
{Colors.YELLOW}UTF-8{Colors.RESTORE} encoding is assumed, please configure git to write commit messages in UTF-8.
|
|
56
|
-
See {Colors.LBLUE}https://git-scm.com/docs/git-commit/#_discussion{Colors.RESTORE} for more.
|
|
57
|
-
"""
|
|
58
|
-
)
|
|
59
|
-
return RESULT_FAIL
|
|
60
|
-
if args.scopes:
|
|
61
|
-
scopes = args.scopes.split(",")
|
|
62
|
-
else:
|
|
63
|
-
scopes = args.scopes
|
|
64
|
-
|
|
65
|
-
if not args.strict:
|
|
66
|
-
if format.has_autosquash_prefix(message):
|
|
67
|
-
return RESULT_SUCCESS
|
|
68
|
-
|
|
69
|
-
if format.is_conventional(message, args.types, args.optional_scope, scopes):
|
|
70
|
-
return RESULT_SUCCESS
|
|
71
|
-
else:
|
|
72
|
-
print(
|
|
73
|
-
f"""
|
|
74
|
-
{Colors.LRED}[Bad Commit message] >>{Colors.RESTORE} {message}
|
|
75
|
-
{Colors.YELLOW}Your commit message does not follow Conventional Commits formatting
|
|
76
|
-
{Colors.LBLUE}https://www.conventionalcommits.org/{Colors.YELLOW}
|
|
77
|
-
|
|
78
|
-
Conventional Commits start with one of the below types, followed by a colon,
|
|
79
|
-
followed by the commit subject and an optional body seperated by a blank line:{Colors.RESTORE}
|
|
80
|
-
|
|
81
|
-
{" ".join(format.conventional_types(args.types))}
|
|
82
|
-
|
|
83
|
-
{Colors.YELLOW}Example commit message adding a feature:{Colors.RESTORE}
|
|
84
|
-
|
|
85
|
-
feat: implement new API
|
|
86
|
-
|
|
87
|
-
{Colors.YELLOW}Example commit message fixing an issue:{Colors.RESTORE}
|
|
88
|
-
|
|
89
|
-
fix: remove infinite loop
|
|
90
|
-
|
|
91
|
-
{Colors.YELLOW}Example commit with scope in parentheses after the type for more context:{Colors.RESTORE}
|
|
92
|
-
|
|
93
|
-
fix(account): remove infinite loop
|
|
94
|
-
|
|
95
|
-
{Colors.YELLOW}Example commit with a body:{Colors.RESTORE}
|
|
96
|
-
|
|
97
|
-
fix: remove infinite loop
|
|
98
|
-
|
|
99
|
-
Additional information on the issue caused by the infinite loop
|
|
100
|
-
"""
|
|
101
|
-
)
|
|
102
|
-
return RESULT_FAIL
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if __name__ == "__main__":
|
|
106
|
-
raise SystemExit(main())
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
bad: message
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.devcontainer/devcontainer.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.0}/.github/workflows/release.yml
RENAMED
|
@@ -36,16 +36,6 @@ jobs:
|
|
|
36
36
|
- name: Build package
|
|
37
37
|
run: python -m build
|
|
38
38
|
|
|
39
|
-
- name: Release
|
|
40
|
-
id: release
|
|
41
|
-
uses: softprops/action-gh-release@v2
|
|
42
|
-
with:
|
|
43
|
-
files: |
|
|
44
|
-
./dist/*.whl
|
|
45
|
-
./dist/*.tar.gz
|
|
46
|
-
prerelease: ${{ contains(github.ref, '-pre') }}
|
|
47
|
-
generate_release_notes: ${{ !contains(github.ref, '-pre') }}
|
|
48
|
-
|
|
49
39
|
- name: Publish to Test PyPI
|
|
50
40
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
51
41
|
if: ${{ contains(github.ref, '-pre') }}
|
|
@@ -60,3 +50,13 @@ jobs:
|
|
|
60
50
|
if: ${{ !contains(github.ref, '-pre') }}
|
|
61
51
|
with:
|
|
62
52
|
print-hash: true
|
|
53
|
+
|
|
54
|
+
- name: Release
|
|
55
|
+
id: release
|
|
56
|
+
uses: softprops/action-gh-release@v2
|
|
57
|
+
with:
|
|
58
|
+
files: |
|
|
59
|
+
./dist/*.whl
|
|
60
|
+
./dist/*.tar.gz
|
|
61
|
+
prerelease: ${{ contains(github.ref, '-pre') }}
|
|
62
|
+
generate_release_notes: ${{ !contains(github.ref, '-pre') }}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{conventional_pre_commit-3.4.0 → conventional_pre_commit-3.6.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.4.0 → conventional_pre_commit-3.6.0}/tests/messages/conventional_commit
RENAMED
|
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.4.0 → conventional_pre_commit-3.6.0}/tests/messages/custom_commit
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|