Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-portage-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-portage-dev] [PATCH v2 1/3] repoman: Add commit message verification
Date: Sat, 17 Feb 2018 12:57:00
Message-Id: 20180217125648.1697-1-mgorny@gentoo.org
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

Replies