Merge lp:~adeuring/launchpad/no-package-translation-uploads-when-sharing into lp:launchpad

Proposed by Abel Deuring
Status: Merged
Approved by: Abel Deuring
Approved revision: no longer in the source branch.
Merged at revision: 12647
Proposed branch: lp:~adeuring/launchpad/no-package-translation-uploads-when-sharing
Merge into: lp:launchpad
Diff against target: 351 lines (+111/-35)
5 files modified
lib/lp/soyuz/doc/distroseriesqueue-translations.txt (+13/-8)
lib/lp/soyuz/interfaces/queue.py (+9/-7)
lib/lp/soyuz/model/queue.py (+22/-13)
lib/lp/soyuz/model/sourcepackagerelease.py (+11/-6)
lib/lp/soyuz/tests/test_sourcepackagerelease.py (+56/-1)
To merge this branch: bzr merge lp:~adeuring/launchpad/no-package-translation-uploads-when-sharing
Reviewer Review Type Date Requested Status
Leonard Richardson (community) Approve
Review via email: mp+54356@code.launchpad.net

Commit message

[r=leonardr][bug=732612] Disable POTemplate/POFile imports from source packages if upstream translation sharing is enabled.

Description of the change

This branch fixes bug 732612: translation uploads from source package builds should stop when upstream sharing is enabled.

The fix is quite straightforward: Prevent a call of ITranslationImportQueue.addOrUpdateEntriesFromTarball() in SourcePackageRelease.attachTranslationFiles(), if translation sharing is enabled. I needed some time to figure out if attachTranslationFiles() is used anywhere: It is called by PackageUploadCustom.publishRosettaTranslations(), and grepping for publish_ROSETTA_TRANSLATIONS (as it was formerly alled) did not yield any results. The reason: The method was looked up in PackageUploadCustom.publish() by concatenating the string 'publish_' with the name of an enumeration value, and by using the resulting string in getattr(self, method_name). That works, but maked it a bit hard to figure out which method is used where, so I also changed the way how PackageUploadCustom.publish() find the right "worker method".

test: ./bin/test soyuz -vvt soyuz.tests.test_sourcepackagerelease

lint:

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/soyuz/doc/distroseriesqueue-translations.txt
  lib/lp/soyuz/interfaces/queue.py
  lib/lp/soyuz/model/queue.py
  lib/lp/soyuz/model/sourcepackagerelease.py
  lib/lp/soyuz/tests/test_sourcepackagerelease.py

./lib/lp/soyuz/doc/distroseriesqueue-translations.txt
       7: source has bad indentation.
      22: source has bad indentation.
      25: source has bad indentation.
      28: source has bad indentation.
      32: source has bad indentation.
      35: source has bad indentation.
      40: source has bad indentation.
      45: source has bad indentation.
      53: source has bad indentation.
      61: source has bad indentation.
      73: source has bad indentation.
      74: source exceeds 78 characters.
      76: source has bad indentation.
      79: source has bad indentation.
      85: source has bad indentation.
      97: source has bad indentation.
     103: source has bad indentation.
     108: source has bad indentation.
     113: source has bad indentation.
     117: want exceeds 78 characters.
     128: source has bad indentation.
     135: source has bad indentation.
     138: source has bad indentation.
     145: source has bad indentation.
     150: source has bad indentation.
     157: source has bad indentation.
     174: source has bad indentation.
     178: source has bad indentation.
     183: source has bad indentation.
     190: source has bad indentation.
     193: want exceeds 78 characters.
     195: source has bad indentation.
     199: source has bad indentation.
     207: source has bad indentation.
     222: want exceeds 78 characters.
     224: source has bad indentation.
     228: source has bad indentation.
     234: source has bad indentation.
     240: source has bad indentation.
     255: want exceeds 78 characters.
     257: source has bad indentation.
     261: source has bad indentation.
     267: source has bad indentation.
     273: source has bad indentation.
     276: want exceeds 78 characters.
     278: source has bad indentation.
     287: source has bad indentation.
     291: source has bad indentation.
     295: source has bad indentation.
     299: source has bad indentation.
     300: want exceeds 78 characters.
     305: source has bad indentation.
     315: source has bad indentation.
     318: source has bad indentation.
     323: source has bad indentation.
     327: source has bad indentation.
     328: want exceeds 78 characters.
     333: source has bad indentation.
     344: source has bad indentation.
     345: source exceeds 78 characters.
     358: source has bad indentation.
     363: source has bad indentation.
     374: source exceeds 78 characters.
     376: source has bad indentation.
     389: source has bad indentation.
     400: source has bad indentation.
     404: source has bad indentation.
     416: source has bad indentation.
     426: source has bad indentation.
     445: source has bad indentation.
./lib/lp/soyuz/model/sourcepackagerelease.py
     201: redefinition of function 'copyright' from line 192

The complaint about a redefinition of "copyright" is bogus: There is a @property named "copyright" and a @copyright.setter named "copyright".

To post a comment you must log in.
Revision history for this message
Leonard Richardson (leonardr) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/doc/distroseriesqueue-translations.txt'
2--- lib/lp/soyuz/doc/distroseriesqueue-translations.txt 2010-12-22 20:46:21 +0000
3+++ lib/lp/soyuz/doc/distroseriesqueue-translations.txt 2011-03-22 14:49:18 +0000
4@@ -1,4 +1,5 @@
5-== Upload processing queue with translations ==
6+Upload processing queue with translations
7+=========================================
8
9 This test covers the use case when a package includes translations and is
10 uploaded into the system.
11@@ -277,7 +278,8 @@
12 >>> transaction.abort()
13
14
15-== Translations from PPA build ==
16+Translations from PPA build
17+---------------------------
18
19 For now we simply ignore translations for archives other than the
20 Distribution archives (i.e. PPAs).
21@@ -305,7 +307,8 @@
22 >>> transaction.abort()
23
24
25-== Translations from a rebuild ==
26+Translations from a rebuild
27+---------------------------
28
29 Translations coming from rebuilt packages are also ignored.
30
31@@ -331,7 +334,8 @@
32 0
33
34
35-== Translations importer: publish_ROSETTA_TRANSLATIONS ==
36+Translations importer: publishRosettaTranslations
37+-------------------------------------------------
38
39 We create mock objects for SourcePackageRelease, PackageUpload and
40 PackageUploadCustom: these will emulate everything we need to document
41@@ -404,7 +408,7 @@
42 True
43 >>> translations_upload = MockPackageUploadCustom()
44 >>> translations_upload.packageupload = sync_package_upload
45- >>> translations_upload.publish_ROSETTA_TRANSLATIONS()
46+ >>> translations_upload.publishRosettaTranslations()
47 Imported by: katie
48
49 Non-auto-sync uploads by 'katie' still indicate 'katie' as the uploader.
50@@ -414,7 +418,7 @@
51 >>> non_sync_package_upload.isAutoSyncUpload()
52 False
53 >>> translations_upload.packageupload = non_sync_package_upload
54- >>> translations_upload.publish_ROSETTA_TRANSLATIONS()
55+ >>> translations_upload.publishRosettaTranslations()
56 Imported by: katie
57
58 Uploads by anyone else are treated as if importer is the packager.
59@@ -427,11 +431,12 @@
60 >>> carlos_package_upload.isAutoSyncUpload()
61 False
62 >>> translations_upload.packageupload = carlos_package_upload
63- >>> translations_upload.publish_ROSETTA_TRANSLATIONS()
64+ >>> translations_upload.publishRosettaTranslations()
65 Imported by: carlos
66
67
68-=== Translations tarball ===
69+Translations tarball
70+~~~~~~~~~~~~~~~~~~~~
71
72 The LibraryFileAlias returned by getLatestTranslationsUploads on the
73 source package points to a tarball with translations files for the
74
75=== modified file 'lib/lp/soyuz/interfaces/queue.py'
76--- lib/lp/soyuz/interfaces/queue.py 2011-01-31 16:01:21 +0000
77+++ lib/lp/soyuz/interfaces/queue.py 2011-03-22 14:49:18 +0000
78@@ -389,6 +389,7 @@
79 process will be logged to it.
80 """
81
82+
83 class IPackageUploadSource(Interface):
84 """A Queue item's related sourcepackagereleases."""
85
86@@ -517,7 +518,7 @@
87 process will be logged to it.
88 """
89
90- def publish_DEBIAN_INSTALLER(logger=None):
91+ def publishDebianInstaller(logger=None):
92 """Publish this custom item as a raw installer tarball.
93
94 This will write the installer tarball out to the right part of
95@@ -527,7 +528,7 @@
96 process will be logged to it.
97 """
98
99- def publish_DIST_UPGRADER(logger=None):
100+ def publishDistUpgrader(logger=None):
101 """Publish this custom item as a raw dist-upgrader tarball.
102
103 This will write the dist-upgrader tarball out to the right part of
104@@ -537,7 +538,7 @@
105 process will be logged to it.
106 """
107
108- def publish_DDTP_TARBALL(logger=None):
109+ def publishDdtpTarball(logger=None):
110 """Publish this custom item as a raw ddtp-tarball.
111
112 This will write the ddtp-tarball out to the right part of
113@@ -547,7 +548,7 @@
114 process will be logged to it.
115 """
116
117- def publish_ROSETTA_TRANSLATIONS(logger=None):
118+ def publishRosettaTranslations(logger=None):
119 """Publish this custom item as a rosetta tarball.
120
121 Essentially this imports the tarball into rosetta.
122@@ -556,14 +557,14 @@
123 process will be logged to it.
124 """
125
126- def publish_STATIC_TRANSLATIONS(logger):
127+ def publishStaticTranslations(logger):
128 """Publish this custom item as a static translations tarball.
129
130 This is currently a no-op as we don't publish these files, they only
131 reside in the librarian for later retrieval using the webservice.
132 """
133
134- def publish_META_DATA(logger):
135+ def publishMetaData(logger):
136 """Publish this custom item as a meta-data file.
137
138 This method writes the meta-data custom file to the archive in
139@@ -662,7 +663,8 @@
140 return all pockets. It supports multiple pockets as a list.
141
142 If 'archive' is specified return only queue items targeted to this
143- archive, if not restrict the results to the IDistribution.main_archive.
144+ archive, if not restrict the results to the
145+ IDistribution.main_archive.
146
147 Use 'exact_match' argument for precise results.
148 """
149
150=== modified file 'lib/lp/soyuz/model/queue.py'
151--- lib/lp/soyuz/model/queue.py 2011-03-04 05:41:41 +0000
152+++ lib/lp/soyuz/model/queue.py 2011-03-22 14:49:18 +0000
153@@ -1655,13 +1655,7 @@
154 self.packageupload.distroseries.distribution.name,
155 self.packageupload.distroseries.name))
156
157- name = "publish_" + self.customformat.name
158- method = getattr(self, name, None)
159- if method is not None:
160- method(logger)
161- else:
162- raise NotFoundError("Unable to find a publisher method for %s" % (
163- self.customformat.name))
164+ self.publisher_dispatch[self.customformat](self, logger)
165
166 def temp_filename(self):
167 """See `IPackageUploadCustom`."""
168@@ -1692,7 +1686,7 @@
169 finally:
170 shutil.rmtree(os.path.dirname(temp_filename))
171
172- def publish_DEBIAN_INSTALLER(self, logger=None):
173+ def publishDebianInstaller(self, logger=None):
174 """See `IPackageUploadCustom`."""
175 # XXX cprov 2005-03-03: We need to use the Zope Component Lookup
176 # to instantiate the object in question and avoid circular imports
177@@ -1701,7 +1695,7 @@
178
179 self._publishCustom(process_debian_installer)
180
181- def publish_DIST_UPGRADER(self, logger=None):
182+ def publishDistUpgrader(self, logger=None):
183 """See `IPackageUploadCustom`."""
184 # XXX cprov 2005-03-03: We need to use the Zope Component Lookup
185 # to instantiate the object in question and avoid circular imports
186@@ -1710,7 +1704,7 @@
187
188 self._publishCustom(process_dist_upgrader)
189
190- def publish_DDTP_TARBALL(self, logger=None):
191+ def publishDdtpTarball(self, logger=None):
192 """See `IPackageUploadCustom`."""
193 # XXX cprov 2005-03-03: We need to use the Zope Component Lookup
194 # to instantiate the object in question and avoid circular imports
195@@ -1719,7 +1713,7 @@
196
197 self._publishCustom(process_ddtp_tarball)
198
199- def publish_ROSETTA_TRANSLATIONS(self, logger=None):
200+ def publishRosettaTranslations(self, logger=None):
201 """See `IPackageUploadCustom`."""
202 sourcepackagerelease = self.packageupload.sourcepackagerelease
203
204@@ -1756,7 +1750,7 @@
205 debug(logger, "Unable to fetch %s to import it into Rosetta" %
206 self.libraryfilealias.http_url)
207
208- def publish_STATIC_TRANSLATIONS(self, logger=None):
209+ def publishStaticTranslations(self, logger=None):
210 """See `IPackageUploadCustom`."""
211 # Static translations are not published. Currently, they're
212 # only exposed via webservice methods so that third parties can
213@@ -1764,7 +1758,7 @@
214 debug(logger, "Skipping publishing of static translations.")
215 return
216
217- def publish_META_DATA(self, logger=None):
218+ def publishMetaData(self, logger=None):
219 """See `IPackageUploadCustom`."""
220 # In the future this could use the existing custom upload file
221 # processing which deals with versioning, etc., but that's too
222@@ -1787,6 +1781,21 @@
223 self.libraryfilealias.open()
224 copy_and_close(self.libraryfilealias, file_obj)
225
226+ publisher_dispatch = {
227+ PackageUploadCustomFormat.DEBIAN_INSTALLER: publishDebianInstaller,
228+ PackageUploadCustomFormat.ROSETTA_TRANSLATIONS:
229+ publishRosettaTranslations,
230+ PackageUploadCustomFormat.DIST_UPGRADER: publishDistUpgrader,
231+ PackageUploadCustomFormat.DDTP_TARBALL: publishDdtpTarball,
232+ PackageUploadCustomFormat.STATIC_TRANSLATIONS:
233+ publishStaticTranslations,
234+ PackageUploadCustomFormat.META_DATA: publishMetaData,
235+ }
236+
237+ # publisher_dispatch must have an entry for each value of
238+ # PackageUploadCustomFormat.
239+ assert len(publisher_dispatch) == len(PackageUploadCustomFormat)
240+
241
242 class PackageUploadSet:
243 """See `IPackageUploadSet`"""
244
245=== modified file 'lib/lp/soyuz/model/sourcepackagerelease.py'
246--- lib/lp/soyuz/model/sourcepackagerelease.py 2011-03-10 07:53:15 +0000
247+++ lib/lp/soyuz/model/sourcepackagerelease.py 2011-03-22 14:49:18 +0000
248@@ -32,7 +32,6 @@
249 from zope.interface import implements
250
251 from canonical.database.constants import (
252- DEFAULT,
253 UTC_NOW,
254 )
255 from canonical.database.datetimecol import UtcDateTimeCol
256@@ -624,11 +623,17 @@
257
258 queue = getUtility(ITranslationImportQueue)
259
260- queue.addOrUpdateEntriesFromTarball(
261- tarball, by_maintainer, importer,
262- sourcepackagename=self.sourcepackagename,
263- distroseries=self.upload_distroseries,
264- filename_filter=_filter_ubuntu_translation_file)
265+ # We do not want to override upstream translations, if
266+ # translation sharing is enabled.
267+ # Avoid circular imports.
268+ from lp.translations.utilities.translationsharinginfo import (
269+ has_upstream_template)
270+ if not has_upstream_template(self.sourcepackage):
271+ queue.addOrUpdateEntriesFromTarball(
272+ tarball, by_maintainer, importer,
273+ sourcepackagename=self.sourcepackagename,
274+ distroseries=self.upload_distroseries,
275+ filename_filter=_filter_ubuntu_translation_file)
276
277 def getDiffTo(self, to_sourcepackagerelease):
278 """See ISourcePackageRelease."""
279
280=== modified file 'lib/lp/soyuz/tests/test_sourcepackagerelease.py'
281--- lib/lp/soyuz/tests/test_sourcepackagerelease.py 2010-10-04 19:50:45 +0000
282+++ lib/lp/soyuz/tests/test_sourcepackagerelease.py 2011-03-22 14:49:18 +0000
283@@ -5,8 +5,21 @@
284
285 __metaclass__ = type
286
287+import transaction
288+from zope.component import getUtility
289+
290 from canonical.testing.layers import LaunchpadFunctionalLayer
291-from lp.testing import TestCaseWithFactory
292+from lp.services.tarfile_helpers import LaunchpadWriteTarFile
293+from lp.testing import (
294+ TestCaseWithFactory,
295+ person_logged_in,
296+ )
297+from lp.translations.interfaces.translationimportqueue import (
298+ ITranslationImportQueue,
299+ )
300+from lp.translations.utilities.translationsharinginfo import (
301+ has_upstream_template,
302+ )
303
304
305 class TestSourcePackageRelease(TestCaseWithFactory):
306@@ -54,3 +67,45 @@
307 # does not have to be valid.
308 spr = self.factory.makeSourcePackageRelease(homepage="<invalid<url")
309 self.assertEquals("<invalid<url", spr.homepage)
310+
311+ def makeTranslationsLFA(self):
312+ """Create an LibraryFileAlias containing dummy translation data."""
313+ test_tar_content = {
314+ 'source/po/foo.pot': 'Foo template',
315+ }
316+ tarfile_content = LaunchpadWriteTarFile.files_to_string(
317+ test_tar_content)
318+ return self.factory.makeLibraryFileAlias(content=tarfile_content)
319+
320+ def test_attachTranslationFiles__no_translation_sharing(self):
321+ # If translation sharing is disabled,
322+ # SourcePackageRelease.attachTranslationFiles() creates a job
323+ # in the translation import queue.
324+ spr = self.factory.makeSourcePackageRelease()
325+ self.assertFalse(has_upstream_template(spr.sourcepackage))
326+ lfa = self.makeTranslationsLFA()
327+ transaction.commit()
328+ spr.attachTranslationFiles(lfa, True, spr.maintainer)
329+ translation_import_queue = getUtility(ITranslationImportQueue)
330+ entries_in_queue = translation_import_queue.getAllEntries(
331+ target=spr.sourcepackage).count()
332+ self.assertEqual(1, entries_in_queue)
333+
334+ def test_attachTranslationFiles__translation_sharing(self):
335+ # If translation sharing is enabled,
336+ # SourcePackageRelease.attachTranslationFiles() does nothing.
337+ spr = self.factory.makeSourcePackageRelease()
338+ sourcepackage = spr.sourcepackage
339+ productseries = self.factory.makeProductSeries()
340+ self.factory.makePOTemplate(productseries=productseries)
341+ with person_logged_in(sourcepackage.distroseries.owner):
342+ sourcepackage.setPackaging(
343+ productseries, sourcepackage.distroseries.owner)
344+ self.assertTrue(has_upstream_template(sourcepackage))
345+ lfa = self.makeTranslationsLFA()
346+ transaction.commit()
347+ spr.attachTranslationFiles(lfa, True, spr.maintainer)
348+ translation_import_queue = getUtility(ITranslationImportQueue)
349+ entries_in_queue = translation_import_queue.getAllEntries(
350+ target=sourcepackage).count()
351+ self.assertEqual(0, entries_in_queue)