Gentoo Archives: gentoo-portage-dev

From: Mike Frysinger <vapier@g.o>
To: gentoo-portage-dev@l.g.o
Subject: [gentoo-portage-dev] [PATCH 1/2] repoman: update cat/pkg info in header all the time
Date: Wed, 13 Jun 2012 00:12:13
Message-Id: 1339539221-6290-1-git-send-email-vapier@gentoo.org
1 There are edge cases where repoman's changelog code is not as good as
2 the existing echangelog. Mostly related to out of date headers. Have
3 the code check the header in more cases not just for missing lines, but
4 also outdated values all the time.
5
6 While we're at it, write some tests!
7
8 Signed-off-by: Mike Frysinger <vapier@g.o>
9 ---
10 pym/portage/tests/repoman/test_echangelog.py | 101 ++++++++++++++++++++++++++
11 pym/repoman/utilities.py | 57 ++++++++-------
12 2 files changed, 133 insertions(+), 25 deletions(-)
13 create mode 100644 pym/portage/tests/repoman/test_echangelog.py
14
15 diff --git a/pym/portage/tests/repoman/test_echangelog.py b/pym/portage/tests/repoman/test_echangelog.py
16 new file mode 100644
17 index 0000000..71d6d5e
18 --- /dev/null
19 +++ b/pym/portage/tests/repoman/test_echangelog.py
20 @@ -0,0 +1,101 @@
21 +# Copyright 2012 Gentoo Foundation
22 +# Distributed under the terms of the GNU General Public License v2
23 +
24 +import datetime
25 +import subprocess
26 +import sys
27 +import tempfile
28 +import time
29 +
30 +import portage
31 +from portage import os
32 +from portage import shutil
33 +from portage.tests import TestCase
34 +from repoman.utilities import UpdateChangeLog
35 +
36 +class RepomanEchangelogTestCase(TestCase):
37 +
38 + def setUp(self):
39 + super(RepomanEchangelogTestCase, self).setUp()
40 +
41 + self.tmpdir = tempfile.mkdtemp(prefix='repoman.echangelog.')
42 +
43 + self.skel_changelog = os.path.join(self.tmpdir, 'skel.ChangeLog')
44 + skel = [
45 + '# ChangeLog for <CATEGORY>/<PACKAGE_NAME>\n',
46 + '# Copyright 1999-2000 Gentoo Foundation; Distributed under the GPL v2\n',
47 + '# $Header: $\n'
48 + ]
49 + self._writelines(self.skel_changelog, skel)
50 +
51 + self.cat = 'mycat'
52 + self.pkg = 'mypkg'
53 + self.pkgdir = os.path.join(self.tmpdir, self.cat, self.pkg)
54 + os.makedirs(self.pkgdir)
55 +
56 + self.header_pkg = '# ChangeLog for %s/%s\n' % (self.cat, self.pkg)
57 + self.header_copyright = '# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2\n' % \
58 + datetime.datetime.now().year
59 + self.header_cvs = '# $Header: $\n'
60 +
61 + self.changelog = os.path.join(self.pkgdir, 'ChangeLog')
62 +
63 + self.user = 'Testing User <portage@g.o>'
64 +
65 + def tearDown(self):
66 + super(RepomanEchangelogTestCase, self).tearDown()
67 + shutil.rmtree(self.tmpdir)
68 +
69 + def _readlines(self, file):
70 + with open(file, 'r') as f:
71 + return f.readlines()
72 +
73 + def _writelines(self, file, data):
74 + with open(file, 'w') as f:
75 + f.writelines(data)
76 +
77 + def testRejectRootUser(self):
78 + self.assertEqual(UpdateChangeLog(self.pkgdir, 'me <root@g.o>', '', '', '', '', quiet=True), None)
79 +
80 + def testMissingSkelFile(self):
81 + # Test missing ChangeLog, but with empty skel (i.e. do nothing).
82 + UpdateChangeLog(self.pkgdir, self.user, 'test!', '/does/not/exist', self.cat, self.pkg, quiet=True)
83 + actual_cl = self._readlines(self.changelog)
84 + self.assertGreater(len(actual_cl[0]), 0)
85 +
86 + def testEmptyChangeLog(self):
87 + # Make sure we do the right thing with a 0-byte ChangeLog
88 + open(self.changelog, 'w').close()
89 + UpdateChangeLog(self.pkgdir, self.user, 'test!', self.skel_changelog, self.cat, self.pkg, quiet=True)
90 + actual_cl = self._readlines(self.changelog)
91 + self.assertEqual(actual_cl[0], self.header_pkg)
92 + self.assertEqual(actual_cl[1], self.header_copyright)
93 + self.assertEqual(actual_cl[2], self.header_cvs)
94 +
95 + def testCopyrightUpdate(self):
96 + # Make sure updating the copyright line works
97 + UpdateChangeLog(self.pkgdir, self.user, 'test!', self.skel_changelog, self.cat, self.pkg, quiet=True)
98 + actual_cl = self._readlines(self.changelog)
99 + self.assertEqual(actual_cl[1], self.header_copyright)
100 +
101 + def testSkelHeader(self):
102 + # Test skel.ChangeLog -> ChangeLog
103 + UpdateChangeLog(self.pkgdir, self.user, 'test!', self.skel_changelog, self.cat, self.pkg, quiet=True)
104 + actual_cl = self._readlines(self.changelog)
105 + self.assertEqual(actual_cl[0], self.header_pkg)
106 +
107 + def testExistingGoodHeader(self):
108 + # Test existing ChangeLog (correct values)
109 + self._writelines(self.changelog, [self.header_pkg])
110 +
111 + UpdateChangeLog(self.pkgdir, self.user, 'test!', self.skel_changelog, self.cat, self.pkg, quiet=True)
112 + actual_cl = self._readlines(self.changelog)
113 + self.assertEqual(actual_cl[0], self.header_pkg)
114 +
115 + def testExistingBadHeader(self):
116 + # Test existing ChangeLog (wrong values)
117 + self._writelines(self.changelog, ['# ChangeLog for \n'])
118 +
119 + UpdateChangeLog(self.pkgdir, self.user, 'test!', self.skel_changelog, self.cat, self.pkg, quiet=True)
120 + actual_cl = self._readlines(self.changelog)
121 + self.assertEqual(actual_cl[0], self.header_pkg)
122 diff --git a/pym/repoman/utilities.py b/pym/repoman/utilities.py
123 index bee67aa..1e07bad 100644
124 --- a/pym/repoman/utilities.py
125 +++ b/pym/repoman/utilities.py
126 @@ -681,7 +681,7 @@ def get_committer_name(env=None):
127 return user
128
129 def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
130 - new=(), removed=(), changed=(), pretend=False):
131 + new=(), removed=(), changed=(), pretend=False, quiet=False):
132 """
133 Write an entry to an existing ChangeLog, or create a new one.
134 Updates copyright year on changed files, and updates the header of
135 @@ -689,8 +689,8 @@ def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
136 """
137
138 if '<root@' in user:
139 - err = 'Please set ECHANGELOG_USER or run as non-root'
140 - logging.critical(err)
141 + if not quiet:
142 + logging.critical('Please set ECHANGELOG_USER or run as non-root')
143 return None
144
145 # ChangeLog times are in UTC
146 @@ -711,24 +711,13 @@ def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
147 old_header_lines = []
148 header_lines = []
149
150 + clold_file = None
151 try:
152 clold_file = io.open(_unicode_encode(cl_path,
153 encoding=_encodings['fs'], errors='strict'),
154 mode='r', encoding=_encodings['repo.content'], errors='replace')
155 except EnvironmentError:
156 - clold_file = None
157 -
158 - clskel_file = None
159 - if clold_file is None:
160 - # we will only need the ChangeLog skeleton if there is no
161 - # ChangeLog yet
162 - try:
163 - clskel_file = io.open(_unicode_encode(skel_path,
164 - encoding=_encodings['fs'], errors='strict'),
165 - mode='r', encoding=_encodings['repo.content'],
166 - errors='replace')
167 - except EnvironmentError:
168 - pass
169 + pass
170
171 f, clnew_path = mkstemp()
172
173 @@ -736,17 +725,35 @@ def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
174 try:
175 if clold_file is not None:
176 # retain header from old ChangeLog
177 + first_line = True
178 for line in clold_file:
179 - line_strip = line.strip()
180 + line_strip = line.strip()
181 if line_strip and line[:1] != "#":
182 clold_lines.append(line)
183 break
184 + # always make sure cat/pkg is up-to-date in case we are
185 + # moving packages around, or copied from another pkg, or ...
186 + if first_line:
187 + if line.startswith('# ChangeLog for'):
188 + line = '# ChangeLog for %s/%s\n' % (category, package)
189 + first_line = False
190 old_header_lines.append(line)
191 header_lines.append(_update_copyright_year(year, line))
192 if not line_strip:
193 break
194
195 - elif clskel_file is not None:
196 + clskel_file = None
197 + if not header_lines:
198 + # delay opening this until we find we need a header
199 + try:
200 + clskel_file = io.open(_unicode_encode(skel_path,
201 + encoding=_encodings['fs'], errors='strict'),
202 + mode='r', encoding=_encodings['repo.content'],
203 + errors='replace')
204 + except EnvironmentError:
205 + pass
206 +
207 + if clskel_file is not None:
208 # read skel.ChangeLog up to first empty line
209 for line in clskel_file:
210 line_strip = line.strip()
211 @@ -806,7 +813,7 @@ def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
212 errors='backslashreplace')
213
214 for line in clnew_lines:
215 - f.write(line)
216 + f.write(_unicode_decode(line))
217
218 # append stuff from old ChangeLog
219 if clold_file is not None:
220 @@ -837,12 +844,12 @@ def UpdateChangeLog(pkgdir, user, msg, skel_path, category, package,
221 clold_file.close()
222 f.close()
223
224 - # show diff (do we want to keep on doing this, or only when
225 - # pretend?)
226 - for line in difflib.unified_diff(clold_lines, clnew_lines,
227 - fromfile=cl_path, tofile=cl_path, n=0):
228 - util.writemsg_stdout(line, noiselevel=-1)
229 - util.writemsg_stdout("\n", noiselevel=-1)
230 + # show diff
231 + if not quiet:
232 + for line in difflib.unified_diff(clold_lines, clnew_lines,
233 + fromfile=cl_path, tofile=cl_path, n=0):
234 + util.writemsg_stdout(line, noiselevel=-1)
235 + util.writemsg_stdout("\n", noiselevel=-1)
236
237 if pretend:
238 # remove what we've done
239 --
240 1.7.9.7

Replies