1 |
Add a check for common mistakes in commit messages. For now, it is |
2 |
pretty rough and works only for -m/-F. It will be extended to work |
3 |
in the interactive mode in the future. |
4 |
--- |
5 |
repoman/pym/repoman/actions.py | 74 ++++++++++++++++++++++++- |
6 |
repoman/pym/repoman/tests/commit/__init__.py | 2 + |
7 |
repoman/pym/repoman/tests/commit/__test__.py | 1 + |
8 |
repoman/pym/repoman/tests/simple/test_simple.py | 8 +-- |
9 |
4 files changed, 80 insertions(+), 5 deletions(-) |
10 |
create mode 100644 repoman/pym/repoman/tests/commit/__init__.py |
11 |
create mode 100644 repoman/pym/repoman/tests/commit/__test__.py |
12 |
|
13 |
diff --git a/repoman/pym/repoman/actions.py b/repoman/pym/repoman/actions.py |
14 |
index b76a6e466..91603865c 100644 |
15 |
--- a/repoman/pym/repoman/actions.py |
16 |
+++ b/repoman/pym/repoman/actions.py |
17 |
@@ -119,7 +119,16 @@ class Actions(object): |
18 |
if commitmessage[:9].lower() in ("cat/pkg: ",): |
19 |
commitmessage = self.msg_prefix() + commitmessage[9:] |
20 |
|
21 |
- if not commitmessage or not commitmessage.strip(): |
22 |
+ if commitmessage is not None and commitmessage.strip(): |
23 |
+ res, expl = self.verify_commit_message(commitmessage) |
24 |
+ if not res: |
25 |
+ print(bad("RepoMan does not like your commit message:")) |
26 |
+ print(expl) |
27 |
+ if self.options.force: |
28 |
+ print('(but proceeding due to --force)') |
29 |
+ else: |
30 |
+ sys.exit(1) |
31 |
+ else: |
32 |
commitmessage = self.get_new_commit_message(qa_output) |
33 |
|
34 |
commitmessage = commitmessage.rstrip() |
35 |
@@ -585,3 +594,66 @@ class Actions(object): |
36 |
print("* no commit message? aborting commit.") |
37 |
sys.exit(1) |
38 |
return commitmessage |
39 |
+ |
40 |
+ footer_re = re.compile(r'^[\w-]+:') |
41 |
+ |
42 |
+ @classmethod |
43 |
+ def verify_commit_message(cls, msg): |
44 |
+ """ |
45 |
+ Check whether the message roughly complies with GLEP66. Returns |
46 |
+ (True, None) if it does, (False, <explanation>) if it does not. |
47 |
+ """ |
48 |
+ |
49 |
+ problems = [] |
50 |
+ paras = msg.strip().split('\n\n') |
51 |
+ summary = paras.pop(0) |
52 |
+ |
53 |
+ if ':' not in summary: |
54 |
+ problems.append('summary line must start with a logical unit name, e.g. "cat/pkg:"') |
55 |
+ if '\n' in summary.strip(): |
56 |
+ problems.append('commit message must start with a *single* line of summary, followed by empty line') |
57 |
+ # accept 69 overall or unit+50, in case of very long package names |
58 |
+ elif len(summary.strip()) > 69 and len(summary.split(':', 1)[-1]) > 50: |
59 |
+ problems.append('summary line is too long (max 69 characters)') |
60 |
+ |
61 |
+ multiple_footers = False |
62 |
+ gentoo_bug_used = False |
63 |
+ bug_closes_without_url = False |
64 |
+ body_too_long = False |
65 |
+ |
66 |
+ found_footer = False |
67 |
+ for p in paras: |
68 |
+ lines = p.splitlines() |
69 |
+ # if all lines look like footer material, we assume it's footer |
70 |
+ # else, we assume it's body text |
71 |
+ if all(cls.footer_re.match(l) for l in lines if l.strip()): |
72 |
+ # multiple footer-like blocks? |
73 |
+ if found_footer: |
74 |
+ multiple_footers = True |
75 |
+ found_footer = True |
76 |
+ for l in lines: |
77 |
+ if l.startswith('Gentoo-Bug'): |
78 |
+ gentoo_bug_used = True |
79 |
+ elif l.startswith('Bug:') or l.startswith('Closes:'): |
80 |
+ if 'http://' not in l and 'https://' not in l: |
81 |
+ bug_closes_without_url = True |
82 |
+ else: |
83 |
+ for l in lines: |
84 |
+ # we recommend wrapping at 72 but accept up to 80; |
85 |
+ # do not complain if we have single word (usually |
86 |
+ # it means very long URL) |
87 |
+ if len(l.strip()) > 80 and len(l.split()) > 1: |
88 |
+ body_too_long = True |
89 |
+ |
90 |
+ if multiple_footers: |
91 |
+ problems.append('multiple footer-style blocks found, please combine them into one') |
92 |
+ if gentoo_bug_used: |
93 |
+ problems.append('please replace Gentoo-Bug with GLEP 66-compliant Bug/Closes') |
94 |
+ if bug_closes_without_url: |
95 |
+ problems.append('Bug/Closes footers require full URL') |
96 |
+ if body_too_long: |
97 |
+ problems.append('body lines should be wrapped at 72 (max 80) characters') |
98 |
+ |
99 |
+ if problems: |
100 |
+ return (False, '\n'.join('- %s' % x for x in problems)) |
101 |
+ return (True, None) |
102 |
diff --git a/repoman/pym/repoman/tests/commit/__init__.py b/repoman/pym/repoman/tests/commit/__init__.py |
103 |
new file mode 100644 |
104 |
index 000000000..d74fd94a7 |
105 |
--- /dev/null |
106 |
+++ b/repoman/pym/repoman/tests/commit/__init__.py |
107 |
@@ -0,0 +1,2 @@ |
108 |
+# Copyright 2011-2018 Gentoo Foundation |
109 |
+# Distributed under the terms of the GNU General Public License v2 |
110 |
diff --git a/repoman/pym/repoman/tests/commit/__test__.py b/repoman/pym/repoman/tests/commit/__test__.py |
111 |
new file mode 100644 |
112 |
index 000000000..8b1378917 |
113 |
--- /dev/null |
114 |
+++ b/repoman/pym/repoman/tests/commit/__test__.py |
115 |
@@ -0,0 +1 @@ |
116 |
+ |
117 |
diff --git a/repoman/pym/repoman/tests/simple/test_simple.py b/repoman/pym/repoman/tests/simple/test_simple.py |
118 |
index a24e0d5a3..3d7a70ad0 100644 |
119 |
--- a/repoman/pym/repoman/tests/simple/test_simple.py |
120 |
+++ b/repoman/pym/repoman/tests/simple/test_simple.py |
121 |
@@ -1,4 +1,4 @@ |
122 |
-# Copyright 2011-2015 Gentoo Foundation |
123 |
+# Copyright 2011-2018 Gentoo Foundation |
124 |
# Distributed under the terms of the GNU General Public License v2 |
125 |
|
126 |
import subprocess |
127 |
@@ -194,13 +194,13 @@ class SimpleRepomanTestCase(TestCase): |
128 |
("", repoman_cmd + ("full", "-d")), |
129 |
("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "2.ebuild")), |
130 |
("", git_cmd + ("add", test_ebuild[:-8] + "2.ebuild")), |
131 |
- ("", repoman_cmd + ("commit", "-m", "bump to version 2")), |
132 |
+ ("", repoman_cmd + ("commit", "-m", "cat/pkg: bump to version 2")), |
133 |
("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "3.ebuild")), |
134 |
("", git_cmd + ("add", test_ebuild[:-8] + "3.ebuild")), |
135 |
- ("dev-libs", repoman_cmd + ("commit", "-m", "bump to version 3")), |
136 |
+ ("dev-libs", repoman_cmd + ("commit", "-m", "cat/pkg: bump to version 3")), |
137 |
("", cp_cmd + (test_ebuild, test_ebuild[:-8] + "4.ebuild")), |
138 |
("", git_cmd + ("add", test_ebuild[:-8] + "4.ebuild")), |
139 |
- ("dev-libs/A", repoman_cmd + ("commit", "-m", "bump to version 4")), |
140 |
+ ("dev-libs/A", repoman_cmd + ("commit", "-m", "cat/pkg: bump to version 4")), |
141 |
) |
142 |
|
143 |
env = { |
144 |
-- |
145 |
2.16.1 |