Merge lp:~robru/cupstream2distro/ditch-dotproject into lp:cupstream2distro

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
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

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

PASSED: Continuous integration, rev:1183
http://jenkins.qa.ubuntu.com/job/cu2d-choo-choo-ci/846/
Executed test runs:

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/cu2d-choo-choo-ci/846/rebuild

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."""

Subscribers

People subscribed via source and target branches