Merge lp:~robru/cupstream2distro/ditch-dotproject into lp:cupstream2distro
- ditch-dotproject
- Merge into trunk
Proposed by
Robert Bruce Park
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Robert Bruce Park | ||||
Approved revision: | 1183 | ||||
Merged at revision: | 1175 | ||||
Proposed branch: | lp:~robru/cupstream2distro/ditch-dotproject | ||||
Merge into: | lp:cupstream2distro | ||||
Diff against target: |
877 lines (+110/-379) 14 files modified
citrain/recipes/base.py (+47/-14) citrain/recipes/manual.py (+1/-3) citrain/recipes/merge.py (+1/-3) citrain/recipes/secondary.py (+0/-4) citrain/recipes/sourcesync.py (+1/-2) citrain/revert.py (+1/-2) cupstream2distro/project.py (+0/-116) tests/data/project_files/foo.project (+0/-3) tests/unit/test_project.py (+0/-180) tests/unit/test_recipe_base.py (+49/-30) tests/unit/test_recipe_manual.py (+1/-1) tests/unit/test_recipe_secondary.py (+0/-1) tests/unit/test_recipe_sourcesync.py (+6/-12) tests/unit/test_script_revert.py (+3/-8) |
||||
To merge this branch: | bzr merge lp:~robru/cupstream2distro/ditch-dotproject | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Bruce Park (community) | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Review via email: mp+275622@code.launchpad.net |
Commit message
Rip out DotProject
Description of the change
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Robert Bruce Park (robru) wrote : | # |
Looks good in staging, really happy with this one.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'citrain/recipes/base.py' |
2 | --- citrain/recipes/base.py 2015-10-24 09:24:59 +0000 |
3 | +++ citrain/recipes/base.py 2015-10-25 00:27:54 +0000 |
4 | @@ -36,7 +36,6 @@ |
5 | from cupstream2distro.packagelist import PackageList |
6 | from cupstream2distro.archive import Archive, ArchWatcher, newest |
7 | from cupstream2distro.branchhandling import Branch |
8 | -from cupstream2distro.project import DotProject |
9 | from cupstream2distro.version import V |
10 | from cupstream2distro.errors import ( |
11 | BuildError, |
12 | @@ -52,10 +51,12 @@ |
13 | ) |
14 | from cupstream2distro.utils import ( |
15 | SILO_DIR, |
16 | + atomic_write, |
17 | env, |
18 | log_value_of, |
19 | name_ppa, |
20 | suppress, |
21 | + utf8_open, |
22 | ) |
23 | |
24 | |
25 | @@ -115,15 +116,11 @@ |
26 | def clean_source(source): |
27 | """Clean all related source content from current silos.""" |
28 | logging.info('Cleaning silo files associated with {}.'.format(source)) |
29 | - config_file = DotProject(source).filename |
30 | source_dir = SILO_DIR(source) |
31 | with suppress(OSError): |
32 | - log_value_of.config_file('Deleting!') |
33 | - os.remove(config_file) |
34 | - with suppress(OSError): |
35 | log_value_of.source_dir('Deleting!') |
36 | shutil.rmtree(source_dir) |
37 | - fileglob = '{}_*'.format(source) |
38 | + fileglob = '{}[._]*'.format(source) |
39 | for path in glob(SILO_DIR(fileglob)): |
40 | log_value_of.path('Deleting!') |
41 | with suppress(OSError): |
42 | @@ -135,6 +132,7 @@ |
43 | class BuildBase(Package, Branch, Archive): |
44 | """Outlines build steps common to all types of package builds.""" |
45 | blame = lp.people[env.BUILD_USER_ID] if env.BUILD_USER_ID else None |
46 | + magic = ('dest_current_version', 'published_version') |
47 | packagelist = None |
48 | authorized = None |
49 | failures = set() |
50 | @@ -156,6 +154,45 @@ |
51 | self.target = None |
52 | self.dest = dest |
53 | |
54 | + def find_file(self, key): |
55 | + """Identify where keyfiles are located.""" |
56 | + return '{}_{}'.format(self.path, key) |
57 | + |
58 | + def set_file(self, key, value): |
59 | + """Atomically write a value to a file.""" |
60 | + with atomic_write(self.find_file(key), 'w') as data: |
61 | + data.write(str(value)) |
62 | + |
63 | + def get_file(self, key): |
64 | + try: |
65 | + with utf8_open(self.find_file(key)) as data: |
66 | + return data.read().strip() |
67 | + except FileNotFoundError: |
68 | + # TODO: This is transitional, drop after last .project file goes. |
69 | + with suppress(FileNotFoundError): |
70 | + with utf8_open(self.path + '.project') as data: |
71 | + for line in data: |
72 | + if line.startswith(key): |
73 | + logging.debug('Fell back to .project file.') |
74 | + value = line.strip().split()[-1] |
75 | + value = {'=': ''}.get(value, value) |
76 | + setattr(self, key, value) |
77 | + return value |
78 | + |
79 | + def __getattr__(self, attr): |
80 | + """Fetch some special properties.""" |
81 | + if attr in self.magic: |
82 | + return self.get_file(attr) |
83 | + raise AttributeError |
84 | + |
85 | + def __setattr__(self, attr, value): |
86 | + """Set some special properties.""" |
87 | + super().__setattr__(attr, value) |
88 | + if attr in self.magic: |
89 | + log_value_of.attr('Setting') |
90 | + log_value_of.value('To') |
91 | + self.set_file(attr, value) |
92 | + |
93 | def validate_phase(self): |
94 | """Stub validate phase.""" |
95 | pass |
96 | @@ -388,7 +425,7 @@ |
97 | logging.info( |
98 | 'Checking for new {} uploads at dest.'.format(self.name)) |
99 | version = self.get_archive_version(self.dest, self.series) |
100 | - supposed = DotProject(self.name).dest_current_version |
101 | + supposed = self.dest_current_version |
102 | log_value_of.version('Dest archive has') |
103 | log_value_of.supposed('At build time, dest had') |
104 | if supposed and version != supposed: |
105 | @@ -408,18 +445,14 @@ |
106 | dest_version = self.get_archive_version(self.dest, self.series) |
107 | if V(version) > dest_version: |
108 | self.packagelist.publish_source(source, dest_version) |
109 | - self.mark_published(version) |
110 | + self.published_version = version |
111 | else: |
112 | logging.warning( |
113 | '{} version {} not greater than {}, skipping.'.format( |
114 | self.name, version, dest_version)) |
115 | else: |
116 | self.copy_to_archive(source) |
117 | - self.mark_published(version) |
118 | - |
119 | - def mark_published(self, version): |
120 | - """Record what version was published.""" |
121 | - DotProject(self.name).mark_as_published(version) |
122 | + self.published_version = version |
123 | |
124 | @classmethod |
125 | def post_publish_phase(cls, silo_state): |
126 | @@ -429,7 +462,7 @@ |
127 | |
128 | def migration_phase(self): |
129 | """Identify the location of this package in its migration.""" |
130 | - version = DotProject(self.name).published_version |
131 | + version = self.published_version |
132 | log_value_of.version('Checking for') |
133 | self.states[self.name] = self.check_archive_migration(version) |
134 | logging.info('{}: {}'.format(self.name, self.states[self.name])) |
135 | |
136 | === modified file 'citrain/recipes/manual.py' |
137 | --- citrain/recipes/manual.py 2015-09-14 19:55:26 +0000 |
138 | +++ citrain/recipes/manual.py 2015-10-25 00:27:54 +0000 |
139 | @@ -26,7 +26,6 @@ |
140 | sys.path.append(os.path.dirname(os.path.dirname(__file__))) |
141 | |
142 | from citrain.recipes.base import BuildBase, clean_source |
143 | -from cupstream2distro.project import DotProject |
144 | from cupstream2distro.utils import SILO_DIR |
145 | |
146 | |
147 | @@ -52,10 +51,9 @@ |
148 | def diff_phase(self): |
149 | """Download manually uploaded sources from PPA.""" |
150 | clean_source(self.name) |
151 | - our_version = self.get_archive_version(self.silo_ppa) |
152 | dest_version = self.get_archive_version(self.dest) |
153 | self.get_from_archive(SILO_DIR(), self.silo_ppa) |
154 | - DotProject.soft_save(self.name, dest=dest_version, ours=our_version) |
155 | + self.dest_current_version = dest_version |
156 | |
157 | # Proceed with standard diffing. |
158 | super().diff_phase() |
159 | |
160 | === modified file 'citrain/recipes/merge.py' |
161 | --- citrain/recipes/merge.py 2015-10-23 07:28:58 +0000 |
162 | +++ citrain/recipes/merge.py 2015-10-25 00:27:54 +0000 |
163 | @@ -25,7 +25,6 @@ |
164 | sys.path.append(os.path.dirname(os.path.dirname(__file__))) |
165 | |
166 | from citrain.recipes.base import BuildBase |
167 | -from cupstream2distro.project import DotProject |
168 | from cupstream2distro.revno import Rev |
169 | from cupstream2distro.version import V |
170 | from cupstream2distro.errors import BuildError, PrepError |
171 | @@ -139,7 +138,7 @@ |
172 | Rev(self.name, target.web_link).write(target.last_scanned_id) |
173 | self.get_branch(target.web_link) |
174 | trunk_version = self.get_package_version() |
175 | - DotProject.soft_save(self.name, dest=trunk_version) |
176 | + self.dest_current_version = trunk_version |
177 | for merge in merges: |
178 | branch = merge.source_branch.web_link |
179 | message = self.generate_commit_message(merge) |
180 | @@ -169,7 +168,6 @@ |
181 | authors = self.collect_changelog_contents() |
182 | self.update_package_changelog(new_version, authors) |
183 | self.release_branch(new_version) |
184 | - DotProject.soft_save(self.name, ours=new_version) |
185 | |
186 | def generate_commit_message(self, merge): |
187 | """Generate a commit message to use when committing merges. |
188 | |
189 | === modified file 'citrain/recipes/secondary.py' |
190 | --- citrain/recipes/secondary.py 2015-10-24 00:05:41 +0000 |
191 | +++ citrain/recipes/secondary.py 2015-10-25 00:27:54 +0000 |
192 | @@ -91,10 +91,6 @@ |
193 | """The primary dest_version_check phase already tracks versions.""" |
194 | pass |
195 | |
196 | - def mark_published(self, version): |
197 | - """The primary mark_published function handles this.""" |
198 | - pass |
199 | - |
200 | def migration_phase(self): |
201 | """The primary migration phase takes care of migration reporting.""" |
202 | pass |
203 | |
204 | === modified file 'citrain/recipes/sourcesync.py' |
205 | --- citrain/recipes/sourcesync.py 2015-08-22 04:23:10 +0000 |
206 | +++ citrain/recipes/sourcesync.py 2015-10-25 00:27:54 +0000 |
207 | @@ -30,7 +30,6 @@ |
208 | from glob import glob |
209 | |
210 | from citrain.recipes.base import BuildBase |
211 | -from cupstream2distro.project import DotProject |
212 | from cupstream2distro.version import V |
213 | from cupstream2distro.errors import BuildError |
214 | from cupstream2distro.utils import SILO_DIR, log_value_of, suppress |
215 | @@ -87,4 +86,4 @@ |
216 | self.rename_orig_tarball(new_upstream) |
217 | self.correct_package_changelog(new_version, self.series.name) |
218 | self.initialize_branch() |
219 | - DotProject.soft_save(self.name, dest=dest_version, ours=new_version) |
220 | + self.dest_current_version = dest_version |
221 | |
222 | === modified file 'citrain/revert.py' |
223 | --- citrain/revert.py 2015-09-24 05:06:40 +0000 |
224 | +++ citrain/revert.py 2015-10-25 00:27:54 +0000 |
225 | @@ -48,7 +48,6 @@ |
226 | from citrain.recipes.manager import Manager |
227 | from citrain.recipes.sourcesync import SourceSync |
228 | from cupstream2distro.version import V |
229 | -from cupstream2distro.project import DotProject |
230 | from cupstream2distro.archive import sort_by_date |
231 | from citrain.build import main as build_main |
232 | from cupstream2distro.errors import RevertError |
233 | @@ -99,7 +98,7 @@ |
234 | call(['dch', '-r', '-D', self.series.name, '--force-distribution', ''], |
235 | cwd=self.path) |
236 | self.initialize_branch() |
237 | - DotProject.soft_save(self.name, dest=current, ours=new_version) |
238 | + self.dest_current_version = current |
239 | |
240 | |
241 | class RevertManager(Manager): |
242 | |
243 | === removed file 'cupstream2distro/project.py' |
244 | --- cupstream2distro/project.py 2015-10-02 20:13:54 +0000 |
245 | +++ cupstream2distro/project.py 1970-01-01 00:00:00 +0000 |
246 | @@ -1,116 +0,0 @@ |
247 | -# -*- coding: utf-8 -*- |
248 | -# Copyright (C) 2014 Canonical |
249 | -# |
250 | -# This program is free software; you can redistribute it and/or modify it under |
251 | -# the terms of the GNU General Public License as published by the Free Software |
252 | -# Foundation; version 3. |
253 | -# |
254 | -# This program is distributed in the hope that it will be useful, but WITHOUT |
255 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
256 | -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
257 | -# details. |
258 | -# |
259 | -# You should have received a copy of the GNU General Public License along with |
260 | -# this program; if not, write to the Free Software Foundation, Inc., |
261 | -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
262 | - |
263 | -"""Class for .project files, which store per-package version numbers.""" |
264 | - |
265 | -import os |
266 | - |
267 | -from glob import glob |
268 | -from os.path import join |
269 | -from six.moves import configparser |
270 | - |
271 | -from cupstream2distro.utils import ( |
272 | - SILO_DIR, |
273 | - log_value_of, |
274 | - suppress, |
275 | - utf8_open, |
276 | -) |
277 | - |
278 | -SECTION = 'Package' |
279 | - |
280 | - |
281 | -def _get_project_files(infix): |
282 | - """Glob for the project files.""" |
283 | - return glob(join(SILO_DIR(), '*{}'.format(infix))) |
284 | - |
285 | - |
286 | -def _get_state(filename): |
287 | - """Read the .project file from disk unconditionally and return it.""" |
288 | - config = configparser.RawConfigParser() |
289 | - with suppress(IOError): |
290 | - with utf8_open(filename) as data: |
291 | - config.readfp(data) |
292 | - return config |
293 | - |
294 | - |
295 | -class DotProject(object): |
296 | - """Provide a standard API for accessing and modifying .project files.""" |
297 | - SUFFIX = '.project' |
298 | - _state = None |
299 | - |
300 | - @staticmethod |
301 | - def get_all_packages_uploaded(): |
302 | - """Get (package, version) of all packages uploaded. |
303 | - |
304 | - We do not rely on the .changes files because we need the exact version, |
305 | - which can have an epoch. And also because the .changes files are not |
306 | - present for manual source uploads. |
307 | - """ |
308 | - result = set() |
309 | - project_files = _get_project_files(DotProject.SUFFIX) |
310 | - log_value_of.project_files() |
311 | - for filename in project_files: |
312 | - basename = os.path.basename(filename) |
313 | - name = basename.split(DotProject.SUFFIX)[0] |
314 | - proj = DotProject(name) |
315 | - result.add((name, proj.packaging_version)) |
316 | - log_value_of.result('Returning') |
317 | - return result |
318 | - |
319 | - @staticmethod |
320 | - def soft_save(name, dest='', ours=''): |
321 | - """Create a .project file without overwriting values in an old one.""" |
322 | - proj = DotProject(name) |
323 | - proj.dest_current_version = dest or proj.dest_current_version |
324 | - proj.packaging_version = ours or proj.packaging_version |
325 | - proj.write() |
326 | - |
327 | - def __init__(self, source_package_name): |
328 | - """Identify the location of the .project file.""" |
329 | - super().__setattr__('name', source_package_name) |
330 | - super().__setattr__('filename', SILO_DIR(self.name + self.SUFFIX)) |
331 | - |
332 | - @property |
333 | - def state(self): |
334 | - """Load the .project file from disk if necessary.""" |
335 | - if not self._state: |
336 | - super().__setattr__('_state', _get_state(self.filename)) |
337 | - return self._state |
338 | - |
339 | - def __getattr__(self, key): |
340 | - """Access a value from a .project file, reading from disk if needed.""" |
341 | - with suppress(configparser.NoSectionError, configparser.NoOptionError): |
342 | - return self.state.get(SECTION, key) |
343 | - return '' |
344 | - |
345 | - def __setattr__(self, key, value): |
346 | - """Set a value for the .project file in memory only.""" |
347 | - with suppress(configparser.Error): |
348 | - self.state.add_section(SECTION) |
349 | - log_value_of.key('Setting') |
350 | - log_value_of.value('To') |
351 | - self.state.set(SECTION, key, value) |
352 | - |
353 | - def mark_as_published(self, version): |
354 | - """Record the published version in the project file.""" |
355 | - self.published_version = version |
356 | - self.write() |
357 | - |
358 | - def write(self): |
359 | - """Write the .project file to disk if we have something to write.""" |
360 | - with utf8_open(self.filename, 'w') as data: |
361 | - if self._state: |
362 | - self._state.write(data) |
363 | |
364 | === removed directory 'tests/data/project_files' |
365 | === removed file 'tests/data/project_files/foo.project' |
366 | --- tests/data/project_files/foo.project 2015-03-02 03:40:36 +0000 |
367 | +++ tests/data/project_files/foo.project 1970-01-01 00:00:00 +0000 |
368 | @@ -1,3 +0,0 @@ |
369 | -[Package] |
370 | -dest_current_version = 6.12.0-0ubuntu1 |
371 | -packaging_version = 6.12.0daily13.02.27-0ubuntu1 |
372 | |
373 | === removed file 'tests/unit/test_project.py' |
374 | --- tests/unit/test_project.py 2015-10-24 09:52:33 +0000 |
375 | +++ tests/unit/test_project.py 1970-01-01 00:00:00 +0000 |
376 | @@ -1,180 +0,0 @@ |
377 | -# -*- coding: utf-8 -*- |
378 | -# Copyright: (C) 2014 Canonical |
379 | -# |
380 | -# This program is free software; you can redistribute it and/or modify it under |
381 | -# the terms of the GNU General Public License as published by the Free Software |
382 | -# Foundation; version 3. |
383 | -# |
384 | -# This program is distributed in the hope that it will be useful, but WITHOUT |
385 | -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
386 | -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
387 | -# details. |
388 | -# |
389 | -# You should have received a copy of the GNU General Public License along with |
390 | -# this program; if not, write to the Free Software Foundation, Inc., |
391 | -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
392 | - |
393 | -"""Tests for DotProject class.""" |
394 | - |
395 | -from tests.unit import DirectoryAwareTestCase |
396 | - |
397 | -from os.path import join |
398 | -from cupstream2distro import project |
399 | -from cupstream2distro.project import DotProject |
400 | -from cupstream2distro.utils import env, utf8_open |
401 | - |
402 | -import os |
403 | -import shutil |
404 | - |
405 | - |
406 | -class ProjectTests(DirectoryAwareTestCase): |
407 | - """Test cupstream2distro DotProject class.""" |
408 | - def setUp(self): |
409 | - """Mock out SILO_DIR and SILOS_DIR for testing.""" |
410 | - super().setUp() |
411 | - project.SILO_DIR = lambda *parts: join(self.tempdir, *parts) |
412 | - env.SILONAME = '' |
413 | - |
414 | - def test_file_creation(self): |
415 | - """Do we create an empty file when saving an empty project?""" |
416 | - proj = DotProject('hello') |
417 | - proj.write() |
418 | - self.assertTrue(os.path.isfile( |
419 | - join(self.tempdir, 'hello.project'))) |
420 | - path = join(self.tempdir, 'hello.project') |
421 | - with utf8_open(path) as data: |
422 | - self.assertEqual(data.readlines(), []) |
423 | - |
424 | - def test_file_writing(self): |
425 | - """Does the written file have the expected values in it?""" |
426 | - proj = DotProject('yeehaw') |
427 | - proj.dest_current_version = '0.99.alpha+15.04.20141225-0ubuntu1' |
428 | - proj.packaging_version = '1.0+15.04.20150101-0ubuntu1' |
429 | - proj.write() |
430 | - path = join(self.tempdir, 'yeehaw.project') |
431 | - with utf8_open(path) as data: |
432 | - self.assertEqual(data.readlines(), [ |
433 | - '[Package]\n', |
434 | - 'dest_current_version = 0.99.alpha+15.04.20141225-0ubuntu1\n', |
435 | - 'packaging_version = 1.0+15.04.20150101-0ubuntu1\n', |
436 | - '\n', |
437 | - ]) |
438 | - |
439 | - def test_soft_save_initial(self): |
440 | - """Does the soft_save method create the expected values in the file?""" |
441 | - DotProject.soft_save( |
442 | - 'yessir', dest='0.1', ours='0.2') |
443 | - path = join(self.tempdir, 'yessir.project') |
444 | - with utf8_open(path) as data: |
445 | - self.assertEqual(data.readlines(), [ |
446 | - '[Package]\n', |
447 | - 'dest_current_version = 0.1\n', |
448 | - 'packaging_version = 0.2\n', |
449 | - '\n', |
450 | - ]) |
451 | - |
452 | - def test_soft_save_initial_with_blanks(self): |
453 | - """Does soft_save create the expected blank values in the file?""" |
454 | - DotProject.soft_save('yessir', dest='', ours='0.2') |
455 | - path = join(self.tempdir, 'yessir.project') |
456 | - with utf8_open(path) as data: |
457 | - self.assertEqual(data.readlines(), [ |
458 | - '[Package]\n', |
459 | - 'dest_current_version = \n', |
460 | - 'packaging_version = 0.2\n', |
461 | - '\n', |
462 | - ]) |
463 | - |
464 | - def test_soft_save_twice(self): |
465 | - """Does a second call to soft_save preserve original values?""" |
466 | - DotProject.soft_save('yessir', dest='0.1', ours='0.2') |
467 | - DotProject.soft_save('yessir', ours='0.3') |
468 | - path = join(self.tempdir, 'yessir.project') |
469 | - with utf8_open(path) as data: |
470 | - self.assertEqual(data.readlines(), [ |
471 | - '[Package]\n', |
472 | - 'dest_current_version = 0.1\n', |
473 | - 'packaging_version = 0.3\n', |
474 | - '\n', |
475 | - ]) |
476 | - |
477 | - def test_file_reading(self): |
478 | - """If we create a file manually, can DotProject read those values?""" |
479 | - path = join(self.tempdir, 'fuddy.project') |
480 | - with utf8_open(path, 'w') as data: |
481 | - data.write( |
482 | - '[Package]\n' |
483 | - 'dest_current_version = 0.99\n' |
484 | - 'packaging_version = 1.0\n' |
485 | - 'branch = lp:𝖚𝖓𝖎𝖈𝖔𝖉𝖊-𝖕𝖗𝖔𝖏𝖊𝖈𝖙\n\n') |
486 | - proj = DotProject('fuddy') |
487 | - self.assertEqual(proj.branch, 'lp:𝖚𝖓𝖎𝖈𝖔𝖉𝖊-𝖕𝖗𝖔𝖏𝖊𝖈𝖙') |
488 | - self.assertEqual(proj.dest_current_version, '0.99') |
489 | - self.assertEqual(proj.packaging_version, '1.0') |
490 | - |
491 | - def test_get_previous_distro_version_from_config(self): |
492 | - """Can we access dest_current_version?""" |
493 | - shutil.copy2( |
494 | - join(self.project_file_dir, 'foo.project'), |
495 | - self.tempdir) |
496 | - self.assertEqual( |
497 | - DotProject('foo').dest_current_version, |
498 | - '6.12.0-0ubuntu1') |
499 | - |
500 | - def test_get_all_packages_uploaded(self): |
501 | - """Does get_all_packages_uploaded find one file?""" |
502 | - shutil.copy2( |
503 | - join(self.project_file_dir, 'foo.project'), |
504 | - self.tempdir) |
505 | - self.assertEqual( |
506 | - DotProject.get_all_packages_uploaded(), |
507 | - set([('foo', '6.12.0daily13.02.27-0ubuntu1')])) |
508 | - |
509 | - def test_get_all_packages_uploaded_multi(self): |
510 | - """Does get_all_packages_uploaded find three files?""" |
511 | - shutil.copy2( |
512 | - join(self.project_file_dir, 'foo.project'), |
513 | - self.tempdir) |
514 | - path = join(self.tempdir, 'f.project') |
515 | - with utf8_open(path, 'w') as data: |
516 | - data.write( |
517 | - '[Package]\n' |
518 | - 'dest_current_version = 0.99\n' |
519 | - 'packaging_version = 1.0\n\n' |
520 | - 'published_version = 2.0\n' |
521 | - 'wut = yo\n\n') |
522 | - proj = DotProject('bar') |
523 | - proj.packaging_version = 'OVER NINE THOUSAND' |
524 | - proj.write() |
525 | - self.assertEqual( |
526 | - DotProject.get_all_packages_uploaded(), set([ |
527 | - ('f', '1.0'), |
528 | - ('foo', '6.12.0daily13.02.27-0ubuntu1'), |
529 | - ('bar', 'OVER NINE THOUSAND'), |
530 | - ])) |
531 | - |
532 | - def test_mark_project_as_published(self): |
533 | - """Confirm project file creation to avoid re-publishing projects.""" |
534 | - shutil.copy2(join(self.project_file_dir, 'foo.project'), |
535 | - self.tempdir) |
536 | - DotProject('foo').mark_as_published('4.2dailysomething-0ubuntu1') |
537 | - filename = join(self.tempdir, 'foo.project') |
538 | - self.assertTrue(os.path.isfile(filename)) |
539 | - with utf8_open(filename) as data: |
540 | - self.assertEqual(data.readlines(), [ |
541 | - '[Package]\n', |
542 | - 'dest_current_version = 6.12.0-0ubuntu1\n', |
543 | - 'packaging_version = 6.12.0daily13.02.27-0ubuntu1\n', |
544 | - 'published_version = 4.2dailysomething-0ubuntu1\n', |
545 | - '\n', |
546 | - ]) |
547 | - |
548 | - def test_mark_project_and_diff_as_published(self): |
549 | - """Confirm diff file creation to prevent project republishing.""" |
550 | - shutil.copy2(join(self.project_file_dir, 'foo.project'), |
551 | - self.tempdir) |
552 | - shutil.copy2(join(self.project_file_dir, 'foo.project'), |
553 | - join( |
554 | - self.tempdir, 'packaging_changes_foo_4.2' |
555 | - 'dailysomething-0ubuntu1.diff')) |
556 | - DotProject('foo').mark_as_published('4.2dailysomething-0ubuntu1') |
557 | |
558 | === modified file 'tests/unit/test_recipe_base.py' |
559 | --- tests/unit/test_recipe_base.py 2015-10-24 09:36:34 +0000 |
560 | +++ tests/unit/test_recipe_base.py 2015-10-25 00:27:54 +0000 |
561 | @@ -16,7 +16,7 @@ |
562 | |
563 | """Tests for CI Train Build script.""" |
564 | |
565 | -from os.path import join |
566 | +from os.path import isfile, join |
567 | from pprint import pprint |
568 | from mock import Mock, call, patch |
569 | |
570 | @@ -28,7 +28,7 @@ |
571 | DEPWAIT_TIMEOUT as DW, |
572 | PPA_TIMEOUT as PT, |
573 | ) |
574 | -from cupstream2distro.utils import env |
575 | +from cupstream2distro.utils import env, utf8_open |
576 | from cupstream2distro.errors import ( |
577 | CITrainError, |
578 | PublishError, |
579 | @@ -78,6 +78,40 @@ |
580 | BuildBase.failures.clear() |
581 | BuildBase.packagelist = None |
582 | |
583 | + def test_getattr(self): |
584 | + """Ensure we can read files from disk.""" |
585 | + path = join(self.tempdir, 'getattr_published_version') |
586 | + with utf8_open(path, 'w') as data: |
587 | + data.write('hello') |
588 | + build = BuildBase('getattr', self.dest, self.series, self.ppa) |
589 | + self.assertEqual(build.published_version, 'hello') |
590 | + |
591 | + def test_getattr_failed(self): |
592 | + """Raise AttributeError for wrong attributes.""" |
593 | + build = BuildBase('wrong', self.dest, self.series, self.ppa) |
594 | + with self.assertRaises(AttributeError): |
595 | + build.zipblorp() |
596 | + |
597 | + def test_getattr_transition(self): |
598 | + """Ensure we can still read from .project files.""" |
599 | + path = join(self.tempdir, 'transition.project') |
600 | + new_path = join(self.tempdir, 'transition_published_version') |
601 | + self.assertFalse(isfile(new_path)) |
602 | + with utf8_open(path, 'w') as data: |
603 | + data.write('watever\nglorp\npublished_version = hiya\n') |
604 | + build = BuildBase('transition', self.dest, self.series, self.ppa) |
605 | + self.assertEqual(build.published_version, 'hiya') |
606 | + with utf8_open(new_path) as data: |
607 | + self.assertEqual(data.read().strip(), 'hiya') |
608 | + |
609 | + def test_getattr_transition_empty(self): |
610 | + """Ensure we can still read from .project files.""" |
611 | + path = join(self.tempdir, 'transition.project') |
612 | + with utf8_open(path, 'w') as data: |
613 | + data.write('published_version =\nha\n') |
614 | + build = BuildBase('transition', self.dest, self.series, self.ppa) |
615 | + self.assertEqual(build.published_version, '') |
616 | + |
617 | def test_pre_validate(self): |
618 | """Test some nops.""" |
619 | mock = Mock() |
620 | @@ -137,17 +171,14 @@ |
621 | @patch('citrain.recipes.base.os') |
622 | @patch('citrain.recipes.base.glob') |
623 | @patch('citrain.recipes.base.shutil') |
624 | - @patch('citrain.recipes.base.DotProject') |
625 | - def test_buildbase_clean_phase(self, dp_mock, sh_mock, glob_mock, os_mock): |
626 | + def test_buildbase_clean_phase(self, sh_mock, glob_mock, os_mock): |
627 | """Clean phase cleans sources.""" |
628 | glob_mock.return_value = ['/silo/dir/foo_hi'] |
629 | build = BuildBase('foo', Mock(), Mock(), Mock()) |
630 | func = 'citrain.recipes.base.SILO_DIR' |
631 | with patch(func, lambda *parts: join(self.tempdir, *parts)): |
632 | build.clean_phase() |
633 | - dp_mock.assert_called_once_with('foo') |
634 | self.assertEqual(os_mock.remove.mock_calls, [ |
635 | - call(dp_mock.return_value.filename), |
636 | call('/silo/dir/foo_hi'), |
637 | ]) |
638 | self.assertEqual(sh_mock.rmtree.mock_calls, [ |
639 | @@ -579,14 +610,13 @@ |
640 | build.ackaging_phase() |
641 | |
642 | @patch('citrain.recipes.base.lp') |
643 | - @patch('citrain.recipes.base.DotProject') |
644 | @patch('citrain.recipes.base.BuildBase.get_archive_version', Mock()) |
645 | - def test_buildbase_dest_version_check_phase(self, dp_mock, lp_mock): |
646 | + def test_buildbase_dest_version_check_phase(self, lp_mock): |
647 | """Ensure dest versions are correctly checked.""" |
648 | lp_mock.is_distro_archive.return_value = True |
649 | env.IGNORE_VERSIONDESTINATION = 'false' |
650 | - dp_mock.return_value.dest_current_version = '1.0' |
651 | build = BuildBase('grue', self.series, self.dest, self.ppa) |
652 | + build.dest_current_version = '1.0' |
653 | build.get_archive_version.return_value = '1.1' |
654 | build.dest_version_check_phase() |
655 | self.assertEqual(build.failures, { |
656 | @@ -595,17 +625,16 @@ |
657 | }) |
658 | |
659 | @patch('citrain.recipes.base.lp') |
660 | - @patch('citrain.recipes.base.DotProject') |
661 | @patch('citrain.recipes.base.BuildBase.get_archive_version', Mock()) |
662 | - def test_buildbase_dest_version_check_phase_pass(self, dp_mock, lp_mock): |
663 | + def test_buildbase_dest_version_check_phase_pass(self, lp_mock): |
664 | """Ensure dest versions are correctly checked.""" |
665 | lp_mock.is_distro_archive.return_value = True |
666 | env.IGNORE_VERSIONDESTINATION = 'false' |
667 | - dp_mock.return_value.dest_current_version = '1.0' |
668 | build = BuildBase('grue', self.series, self.dest, self.ppa) |
669 | + build.dest_current_version = '1.0' |
670 | build.get_archive_version.return_value = '1.0' |
671 | build.dest_version_check_phase() |
672 | - dp_mock.return_value.dest_current_version = '1.1' |
673 | + build.dest_current_version = '1.1' |
674 | lp_mock.is_distro_archive.return_value = False |
675 | build.dest_version_check_phase() |
676 | lp_mock.is_distro_archive.return_value = True |
677 | @@ -623,10 +652,9 @@ |
678 | self.assertEqual(BuildBase.packagelist, pl_mock.return_value) |
679 | |
680 | @patch('citrain.recipes.base.lp') |
681 | - @patch('citrain.recipes.base.DotProject') |
682 | @patch('citrain.recipes.base.BuildBase.get_archive_version', Mock()) |
683 | @patch('citrain.recipes.base.BuildBase.get_source_from_archive', Mock()) |
684 | - def test_buildbase_publish_phase_distro(self, dp_mock, lp_mock): |
685 | + def test_buildbase_publish_phase_distro(self, lp_mock): |
686 | """Do some publishing!""" |
687 | lp_mock.is_distro_archive.return_value = True |
688 | build = BuildBase('florp', self.series, self.dest, self.ppa) |
689 | @@ -637,18 +665,15 @@ |
690 | build.publish_phase() |
691 | build.packagelist.publish_source.assert_called_once_with( |
692 | source, 'Schwifty-one') |
693 | - dp_mock.assert_called_once_with('florp') |
694 | - dp_mock.return_value.mark_as_published.assert_called_once_with( |
695 | - 'Schwifty-two') |
696 | build.get_source_from_archive.assert_called_once_with() |
697 | build.get_archive_version.assert_called_once_with( |
698 | build.dest, build.series) |
699 | + self.assertEqual(build.published_version, 'Schwifty-two') |
700 | |
701 | @patch('citrain.recipes.base.lp') |
702 | - @patch('citrain.recipes.base.DotProject') |
703 | @patch('citrain.recipes.base.BuildBase.get_archive_version', Mock()) |
704 | @patch('citrain.recipes.base.BuildBase.get_source_from_archive', Mock()) |
705 | - def test_buildbase_publish_phase_skipped(self, dp_mock, lp_mock): |
706 | + def test_buildbase_publish_phase_skipped(self, lp_mock): |
707 | """Skip packages that aren't newer than distro.""" |
708 | lp_mock.is_distro_archive.return_value = True |
709 | build = BuildBase('glorp', self.series, self.dest, self.ppa) |
710 | @@ -658,17 +683,15 @@ |
711 | build.packagelist = Mock() |
712 | build.publish_phase() |
713 | self.assertEqual(build.packagelist.publish_source.mock_calls, []) |
714 | - self.assertEqual(dp_mock.mock_calls, []) |
715 | build.get_source_from_archive.assert_called_once_with() |
716 | build.get_archive_version.assert_called_once_with( |
717 | build.dest, build.series) |
718 | |
719 | @patch('citrain.recipes.base.lp') |
720 | - @patch('citrain.recipes.base.DotProject') |
721 | @patch('citrain.recipes.base.BuildBase.copy_to_archive', Mock()) |
722 | @patch('citrain.recipes.base.BuildBase.get_archive_version', Mock()) |
723 | @patch('citrain.recipes.base.BuildBase.get_source_from_archive', Mock()) |
724 | - def test_buildbase_publish_phase_ppa(self, dp_mock, lp_mock): |
725 | + def test_buildbase_publish_phase_ppa(self, lp_mock): |
726 | """Call copyPackage directly for PPA destinations.""" |
727 | lp_mock.is_distro_archive.return_value = False |
728 | build = BuildBase('norp', self.series, self.dest, self.ppa) |
729 | @@ -680,9 +703,7 @@ |
730 | build.get_source_from_archive.assert_called_once_with() |
731 | self.assertEqual(build.get_archive_version.mock_calls, []) |
732 | build.copy_to_archive.assert_called_once_with(source) |
733 | - dp_mock.assert_called_once_with('norp') |
734 | - dp_mock.return_value.mark_as_published.assert_called_once_with( |
735 | - 'Schwifty-two') |
736 | + self.assertEqual(build.published_version, 'Schwifty-two') |
737 | |
738 | def test_buildbase_post_publish_phase(self): |
739 | """Write PackageList to disk.""" |
740 | @@ -694,14 +715,12 @@ |
741 | self.assertEqual(silo_state.mock_calls, []) |
742 | BuildBase.packagelist.write.assert_called_once_with() # ONCE |
743 | |
744 | - @patch('citrain.recipes.base.DotProject') |
745 | - def test_buildbase_migration_phase(self, dp_mock): |
746 | + def test_buildbase_migration_phase(self): |
747 | """Report the location status of this package.""" |
748 | - dp_mock.return_value.published_version = '2.0' |
749 | build = BuildBase('foo', self.series, self.dest, self.ppa) |
750 | + build.published_version = '2.0' |
751 | build.check_archive_migration = Mock(return_value='Release pocket') |
752 | build.migration_phase() |
753 | - dp_mock.assert_called_once_with('foo') |
754 | build.check_archive_migration.assert_called_once_with('2.0') |
755 | self.assertEqual( |
756 | BuildBase.states, |
757 | |
758 | === modified file 'tests/unit/test_recipe_manual.py' |
759 | --- tests/unit/test_recipe_manual.py 2015-09-22 06:53:49 +0000 |
760 | +++ tests/unit/test_recipe_manual.py 2015-10-25 00:27:54 +0000 |
761 | @@ -66,7 +66,7 @@ |
762 | manual.diff_phase() |
763 | cs_mock.assert_called_once_with('zappy') |
764 | self.assertEqual(manual.get_archive_version.mock_calls, [ |
765 | - call(self.ppa), call(self.dest), |
766 | + call(self.dest), |
767 | ]) |
768 | manual.get_from_archive.assert_called_once_with( |
769 | self.tempdir, manual.silo_ppa) |
770 | |
771 | === modified file 'tests/unit/test_recipe_secondary.py' |
772 | --- tests/unit/test_recipe_secondary.py 2015-10-24 00:05:41 +0000 |
773 | +++ tests/unit/test_recipe_secondary.py 2015-10-25 00:27:54 +0000 |
774 | @@ -60,7 +60,6 @@ |
775 | sec.ackaging_phase() |
776 | sec.migration_phase() |
777 | sec.enumeration_phase() |
778 | - sec.mark_published('boo') |
779 | self.assertEqual(sec.upload_package.mock_calls, []) |
780 | self.assertEqual(sec.get_from_archive.mock_calls, []) |
781 | self.assertEqual(sec.generate_package_diffs.mock_calls, []) |
782 | |
783 | === modified file 'tests/unit/test_recipe_sourcesync.py' |
784 | --- tests/unit/test_recipe_sourcesync.py 2015-09-22 06:53:49 +0000 |
785 | +++ tests/unit/test_recipe_sourcesync.py 2015-10-25 00:27:54 +0000 |
786 | @@ -40,14 +40,13 @@ |
787 | @patch(MOD + 'os') |
788 | @patch(MOD + 'glob') |
789 | @patch(MOD + 'shutil') |
790 | - @patch(MOD + 'DotProject') |
791 | @patch(MOD + 'SourceSync.from_archive', Mock()) |
792 | @patch(MOD + 'SourceSync.get_from_archive', Mock()) |
793 | @patch(MOD + 'SourceSync.initialize_branch', Mock()) |
794 | @patch(MOD + 'SourceSync.get_archive_version', Mock()) |
795 | @patch(MOD + 'SourceSync.get_package_version', Mock()) |
796 | @patch(MOD + 'SourceSync.correct_package_changelog', Mock()) |
797 | - def test_collect(self, dp_mock, sh_mock, glob_mock, os_mock): |
798 | + def test_collect(self, sh_mock, glob_mock, os_mock): |
799 | """Syncs can download from sync sources.""" |
800 | self.dest.distribution.name = 'ubuntu-rtm' |
801 | self.dest.name = 'primary' |
802 | @@ -89,22 +88,19 @@ |
803 | sync.correct_package_changelog.assert_called_once_with( |
804 | '1+15.04.20150208~rtm-0ubuntu2', self.series.name) |
805 | sync.initialize_branch.assert_called_once_with() |
806 | - dp_mock.soft_save.assert_called_once_with( |
807 | - 'sink', |
808 | - dest=sync.get_archive_version.return_value, |
809 | - ours='1+15.04.20150208~rtm-0ubuntu2') |
810 | + self.assertEqual( |
811 | + sync.dest_current_version, '1+15.04.20150208~rtm-0ubuntu1') |
812 | |
813 | @patch(MOD + 'os') |
814 | @patch(MOD + 'glob') |
815 | @patch(MOD + 'shutil') |
816 | - @patch(MOD + 'DotProject') |
817 | @patch(MOD + 'SourceSync.from_archive', Mock()) |
818 | @patch(MOD + 'SourceSync.get_from_archive', Mock()) |
819 | @patch(MOD + 'SourceSync.initialize_branch', Mock()) |
820 | @patch(MOD + 'SourceSync.get_archive_version', Mock()) |
821 | @patch(MOD + 'SourceSync.get_package_version', Mock()) |
822 | @patch(MOD + 'SourceSync.correct_package_changelog', Mock()) |
823 | - def test_collect_nrtm(self, dp_mock, sh_mock, glob_mock, os_mock): |
824 | + def test_collect_nrtm(self, sh_mock, glob_mock, os_mock): |
825 | """Source syncs from the same distro modify version numbers, non RTM""" |
826 | self.dest.distribution.name = 'ubuntu' |
827 | self.dest.name = 'primary' |
828 | @@ -132,10 +128,8 @@ |
829 | ]) |
830 | sync.correct_package_changelog.assert_called_once_with( |
831 | '1+15.04.20150210-0ubuntu1', self.series.name) |
832 | - dp_mock.soft_save.assert_called_once_with( |
833 | - 'sink', |
834 | - dest=sync.get_archive_version.return_value, |
835 | - ours='1+15.04.20150210-0ubuntu1') |
836 | + self.assertEqual( |
837 | + sync.dest_current_version, '1+15.04.20150208-0ubuntu1') |
838 | |
839 | @patch(MOD + 'glob') |
840 | @patch(MOD + 'SourceSync.from_archive', Mock()) |
841 | |
842 | === modified file 'tests/unit/test_script_revert.py' |
843 | --- tests/unit/test_script_revert.py 2015-10-22 22:41:56 +0000 |
844 | +++ tests/unit/test_script_revert.py 2015-10-25 00:27:54 +0000 |
845 | @@ -33,11 +33,8 @@ |
846 | |
847 | def setUp(self): |
848 | super().setUp() |
849 | - self.revert = self.script.Revert(Mock(), Mock(), Mock(), Mock()) |
850 | - self.revert.name = 'regress' |
851 | + self.revert = self.script.Revert('regress', Mock(), Mock(), Mock()) |
852 | self.revert.series = Mock(version='15.04') |
853 | - self.revert.dest = Mock() |
854 | - self.revert.silo_ppa = Mock() |
855 | |
856 | def test_revert_collect_phase(self): |
857 | """Ensure that Revert class can get packages to revert to.""" |
858 | @@ -70,8 +67,7 @@ |
859 | cwd=revert.path), |
860 | ]) |
861 | revert.initialize_branch.assert_called_once_with() |
862 | - self.script.DotProject.soft_save.assert_called_once_with( |
863 | - 'regress', dest='2.0', ours=new_version + '-0ubuntu1') |
864 | + self.assertEqual(revert.dest_current_version, '2.0') |
865 | |
866 | def test_revert_collect_phase_epoch(self): |
867 | """Ensure that Revert class can handle epoch'd versions.""" |
868 | @@ -104,8 +100,7 @@ |
869 | cwd=revert.path), |
870 | ]) |
871 | revert.initialize_branch.assert_called_once_with() |
872 | - self.script.DotProject.soft_save.assert_called_once_with( |
873 | - 'regress', dest='2:2.0', ours='2:{}-0ubuntu1'.format(new_version)) |
874 | + self.assertEqual(revert.dest_current_version, '2:2.0') |
875 | |
876 | def test_revert_collect_phase_none_found(self): |
877 | """Raise the correct error when there's no previous version.""" |
PASSED: Continuous integration, rev:1183 jenkins. qa.ubuntu. com/job/ cu2d-choo- choo-ci/ 846/
http://
Executed test runs:
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/cu2d- choo-choo- ci/846/ rebuild
http://