Merge lp:~al-maisan/launchpad/newuris-399186 into lp:launchpad/db-devel
- newuris-399186
- Merge into db-devel
Proposed by
Muharem Hrnjadovic
Status: | Merged |
---|---|
Merged at revision: | not available |
Proposed branch: | lp:~al-maisan/launchpad/newuris-399186 |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
545 lines 7 files modified
lib/lp/soyuz/browser/configure.zcml (+1/-1) lib/lp/soyuz/browser/packageset.py (+19/-0) lib/lp/soyuz/interfaces/archivepermission.py (+9/-0) lib/lp/soyuz/interfaces/packageset.py (+5/-5) lib/lp/soyuz/model/archivepermission.py (+6/-1) lib/lp/soyuz/model/packageset.py (+9/-1) lib/lp/soyuz/stories/webservice/xx-packageset.txt (+93/-52) |
To merge this branch: | bzr merge lp:~al-maisan/launchpad/newuris-399186 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Abel Deuring (community) | code | Approve | |
Review via email: mp+14204@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote : | # |
Revision history for this message
Abel Deuring (adeuring) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/soyuz/browser/configure.zcml' | |||
2 | --- lib/lp/soyuz/browser/configure.zcml 2009-10-22 10:33:00 +0000 | |||
3 | +++ lib/lp/soyuz/browser/configure.zcml 2009-10-30 10:10:25 +0000 | |||
4 | @@ -783,7 +783,7 @@ | |||
5 | 783 | /> | 783 | /> |
6 | 784 | <browser:url | 784 | <browser:url |
7 | 785 | for="lp.soyuz.interfaces.packageset.IPackageset" | 785 | for="lp.soyuz.interfaces.packageset.IPackageset" |
9 | 786 | path_expression="name" | 786 | path_expression="string:${distroseries/name}/${name}" |
10 | 787 | parent_utility="lp.soyuz.interfaces.packageset.IPackagesetSet" | 787 | parent_utility="lp.soyuz.interfaces.packageset.IPackagesetSet" |
11 | 788 | /> | 788 | /> |
12 | 789 | <browser:url | 789 | <browser:url |
13 | 790 | 790 | ||
14 | === modified file 'lib/lp/soyuz/browser/packageset.py' | |||
15 | --- lib/lp/soyuz/browser/packageset.py 2009-06-30 16:56:07 +0000 | |||
16 | +++ lib/lp/soyuz/browser/packageset.py 2009-10-30 10:10:25 +0000 | |||
17 | @@ -17,3 +17,22 @@ | |||
18 | 17 | class PackagesetSetNavigation(GetitemNavigation): | 17 | class PackagesetSetNavigation(GetitemNavigation): |
19 | 18 | """Navigation methods for PackagesetSet.""" | 18 | """Navigation methods for PackagesetSet.""" |
20 | 19 | usedfor = IPackagesetSet | 19 | usedfor = IPackagesetSet |
21 | 20 | |||
22 | 21 | def traverse(self, distroseries): | ||
23 | 22 | """Traverse package sets in distro series context. | ||
24 | 23 | |||
25 | 24 | The URI fragment of interest is: | ||
26 | 25 | |||
27 | 26 | /package-sets/lucid/mozilla | ||
28 | 27 | |||
29 | 28 | where 'lucid' is the distro series and 'mozilla' is the package set | ||
30 | 29 | *name* respectively. | ||
31 | 30 | """ | ||
32 | 31 | if self.request.stepstogo: | ||
33 | 32 | # The package set name follows after the distro series. | ||
34 | 33 | ps_name = self.request.stepstogo.consume() | ||
35 | 34 | return self.context.getByName(ps_name, distroseries=distroseries) | ||
36 | 35 | |||
37 | 36 | # Otherwise return None (to trigger a NotFound error). | ||
38 | 37 | return None | ||
39 | 38 | |||
40 | 20 | 39 | ||
41 | === modified file 'lib/lp/soyuz/interfaces/archivepermission.py' | |||
42 | --- lib/lp/soyuz/interfaces/archivepermission.py 2009-08-03 17:10:12 +0000 | |||
43 | +++ lib/lp/soyuz/interfaces/archivepermission.py 2009-10-30 10:10:25 +0000 | |||
44 | @@ -284,6 +284,9 @@ | |||
45 | 284 | def uploadersForPackageset(archive, packageset, direct_permissions=True): | 284 | def uploadersForPackageset(archive, packageset, direct_permissions=True): |
46 | 285 | """The `ArchivePermission` records for uploaders to the package set. | 285 | """The `ArchivePermission` records for uploaders to the package set. |
47 | 286 | 286 | ||
48 | 287 | Please note: if a package set *name* is passed the respective | ||
49 | 288 | package set in the current distro series will be used. | ||
50 | 289 | |||
51 | 287 | :param archive: The archive the permission applies to. | 290 | :param archive: The archive the permission applies to. |
52 | 288 | :param packageset: An `IPackageset` or a string package set name. | 291 | :param packageset: An `IPackageset` or a string package set name. |
53 | 289 | :param direct_permissions: If True only consider permissions granted | 292 | :param direct_permissions: If True only consider permissions granted |
54 | @@ -332,6 +335,9 @@ | |||
55 | 332 | def newPackagesetUploader(archive, person, packageset, explicit=False): | 335 | def newPackagesetUploader(archive, person, packageset, explicit=False): |
56 | 333 | """Create and return a new `ArchivePermission` for an uploader. | 336 | """Create and return a new `ArchivePermission` for an uploader. |
57 | 334 | 337 | ||
58 | 338 | Please note: if a package set *name* is passed the respective | ||
59 | 339 | package set in the current distro series will be used. | ||
60 | 340 | |||
61 | 335 | :param archive: The archive the permission applies to. | 341 | :param archive: The archive the permission applies to. |
62 | 336 | :param person: An `IPerson` for whom you want to add permission. | 342 | :param person: An `IPerson` for whom you want to add permission. |
63 | 337 | :param packageset: An `IPackageset` or a string package set name. | 343 | :param packageset: An `IPackageset` or a string package set name. |
64 | @@ -379,6 +385,9 @@ | |||
65 | 379 | def deletePackagesetUploader(archive, person, packageset, explicit=False): | 385 | def deletePackagesetUploader(archive, person, packageset, explicit=False): |
66 | 380 | """Revoke upload permissions for a person. | 386 | """Revoke upload permissions for a person. |
67 | 381 | 387 | ||
68 | 388 | Please note: if a package set *name* is passed the respective | ||
69 | 389 | package set in the current distro series will be used. | ||
70 | 390 | |||
71 | 382 | :param archive: The archive the permission applies to. | 391 | :param archive: The archive the permission applies to. |
72 | 383 | :param person: An `IPerson` for whom you want to revoke permission. | 392 | :param person: An `IPerson` for whom you want to revoke permission. |
73 | 384 | :param packageset: An `IPackageset` or a string package set name. | 393 | :param packageset: An `IPackageset` or a string package set name. |
74 | 385 | 394 | ||
75 | === modified file 'lib/lp/soyuz/interfaces/packageset.py' | |||
76 | --- lib/lp/soyuz/interfaces/packageset.py 2009-10-27 23:40:24 +0000 | |||
77 | +++ lib/lp/soyuz/interfaces/packageset.py 2009-10-30 10:10:25 +0000 | |||
78 | @@ -37,7 +37,7 @@ | |||
79 | 37 | """Raised when we try to look up an PackageSet that doesn't exist.""" | 37 | """Raised when we try to look up an PackageSet that doesn't exist.""" |
80 | 38 | # Bad request. | 38 | # Bad request. |
81 | 39 | webservice_error(400) | 39 | webservice_error(400) |
83 | 40 | _message_prefix = "No such packageset" | 40 | _message_prefix = "No such package set (in the specified distro series)" |
84 | 41 | 41 | ||
85 | 42 | 42 | ||
86 | 43 | class DuplicatePackagesetName(Exception): | 43 | class DuplicatePackagesetName(Exception): |
87 | @@ -68,17 +68,17 @@ | |||
88 | 68 | title=_("Description"), required=True, readonly=True, | 68 | title=_("Description"), required=True, readonly=True, |
89 | 69 | description=_("The description for the package set at hand."))) | 69 | description=_("The description for the package set at hand."))) |
90 | 70 | 70 | ||
92 | 71 | distroseries = Reference( | 71 | distroseries = exported(Reference( |
93 | 72 | IDistroSeries, title=_("Distribution series"), required=True, | 72 | IDistroSeries, title=_("Distribution series"), required=True, |
94 | 73 | readonly=True, | 73 | readonly=True, |
95 | 74 | description=_( | 74 | description=_( |
97 | 75 | "The distroseries to which this package set is related.")) | 75 | "The distroseries to which this package set is related."))) |
98 | 76 | 76 | ||
99 | 77 | packagesetgroup = Reference( | 77 | packagesetgroup = Reference( |
101 | 78 | IPackagesetGroup, title=_('Packageset group'), required=True, | 78 | IPackagesetGroup, title=_('Package set group'), required=True, |
102 | 79 | readonly=True, | 79 | readonly=True, |
103 | 80 | description=_( | 80 | description=_( |
105 | 81 | 'Used internally to link packagesets across distroseries')) | 81 | 'Used internally to link package sets across distro series.')) |
106 | 82 | 82 | ||
107 | 83 | def sourcesIncluded(direct_inclusion=False): | 83 | def sourcesIncluded(direct_inclusion=False): |
108 | 84 | """Get all source names associated with this package set. | 84 | """Get all source names associated with this package set. |
109 | 85 | 85 | ||
110 | === modified file 'lib/lp/soyuz/model/archivepermission.py' | |||
111 | --- lib/lp/soyuz/model/archivepermission.py 2009-07-28 21:52:56 +0000 | |||
112 | +++ lib/lp/soyuz/model/archivepermission.py 2009-10-30 10:10:25 +0000 | |||
113 | @@ -22,6 +22,7 @@ | |||
114 | 22 | from canonical.database.enumcol import EnumCol | 22 | from canonical.database.enumcol import EnumCol |
115 | 23 | from canonical.database.sqlbase import sqlvalues, SQLBase | 23 | from canonical.database.sqlbase import sqlvalues, SQLBase |
116 | 24 | 24 | ||
117 | 25 | from lp.registry.interfaces.distribution import IDistributionSet | ||
118 | 25 | from lp.soyuz.interfaces.archive import ComponentNotFound | 26 | from lp.soyuz.interfaces.archive import ComponentNotFound |
119 | 26 | from lp.soyuz.interfaces.archivepermission import ( | 27 | from lp.soyuz.interfaces.archivepermission import ( |
120 | 27 | ArchivePermissionType, IArchivePermission, IArchivePermissionSet, | 28 | ArchivePermissionType, IArchivePermission, IArchivePermissionSet, |
121 | @@ -312,9 +313,13 @@ | |||
122 | 312 | def _nameToPackageset(self, packageset): | 313 | def _nameToPackageset(self, packageset): |
123 | 313 | """Helper to convert a possible string name to IPackageset.""" | 314 | """Helper to convert a possible string name to IPackageset.""" |
124 | 314 | if isinstance(packageset, basestring): | 315 | if isinstance(packageset, basestring): |
125 | 316 | # A package set name was passed, assume the current distro series. | ||
126 | 317 | ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | ||
127 | 315 | name = packageset | 318 | name = packageset |
128 | 316 | store = IStore(Packageset) | 319 | store = IStore(Packageset) |
130 | 317 | packageset = store.find(Packageset, name=name).one() | 320 | packageset = store.find( |
131 | 321 | Packageset, name=name, | ||
132 | 322 | distroseries=ubuntu.currentseries).one() | ||
133 | 318 | if packageset is not None: | 323 | if packageset is not None: |
134 | 319 | return packageset | 324 | return packageset |
135 | 320 | else: | 325 | else: |
136 | 321 | 326 | ||
137 | === modified file 'lib/lp/soyuz/model/packageset.py' | |||
138 | --- lib/lp/soyuz/model/packageset.py 2009-10-27 15:42:04 +0000 | |||
139 | +++ lib/lp/soyuz/model/packageset.py 2009-10-30 10:10:25 +0000 | |||
140 | @@ -14,6 +14,7 @@ | |||
141 | 14 | from zope.interface import implements | 14 | from zope.interface import implements |
142 | 15 | 15 | ||
143 | 16 | from canonical.launchpad.interfaces.lpstorm import IMasterStore, IStore | 16 | from canonical.launchpad.interfaces.lpstorm import IMasterStore, IStore |
144 | 17 | from canonical.launchpad.webapp.interfaces import NotFoundError | ||
145 | 17 | from lp.registry.interfaces.distribution import IDistributionSet | 18 | from lp.registry.interfaces.distribution import IDistributionSet |
146 | 18 | from lp.registry.interfaces.sourcepackagename import ( | 19 | from lp.registry.interfaces.sourcepackagename import ( |
147 | 19 | ISourcePackageName, ISourcePackageNameSet) | 20 | ISourcePackageName, ISourcePackageNameSet) |
148 | @@ -350,11 +351,17 @@ | |||
149 | 350 | if not isinstance(name, unicode): | 351 | if not isinstance(name, unicode): |
150 | 351 | name = unicode(name, 'utf-8') | 352 | name = unicode(name, 'utf-8') |
151 | 352 | 353 | ||
152 | 354 | ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | ||
153 | 353 | extra_args = [] | 355 | extra_args = [] |
154 | 354 | if distroseries is not None: | 356 | if distroseries is not None: |
155 | 357 | # If the user just passed a distro series name, look it up. | ||
156 | 358 | if isinstance(distroseries, basestring): | ||
157 | 359 | try: | ||
158 | 360 | distroseries = ubuntu[distroseries] | ||
159 | 361 | except NotFoundError: | ||
160 | 362 | raise NoSuchPackageSet(distroseries) | ||
161 | 355 | extra_args.append(Packageset.distroseries == distroseries) | 363 | extra_args.append(Packageset.distroseries == distroseries) |
162 | 356 | else: | 364 | else: |
163 | 357 | ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | ||
164 | 358 | extra_args.append(Packageset.distroseries == ubuntu.currentseries) | 365 | extra_args.append(Packageset.distroseries == ubuntu.currentseries) |
165 | 359 | 366 | ||
166 | 360 | package_set = store.find( | 367 | package_set = store.find( |
167 | @@ -362,6 +369,7 @@ | |||
168 | 362 | 369 | ||
169 | 363 | if package_set is None: | 370 | if package_set is None: |
170 | 364 | raise NoSuchPackageSet(name) | 371 | raise NoSuchPackageSet(name) |
171 | 372 | |||
172 | 365 | return package_set | 373 | return package_set |
173 | 366 | 374 | ||
174 | 367 | def getByOwner(self, owner): | 375 | def getByOwner(self, owner): |
175 | 368 | 376 | ||
176 | === modified file 'lib/lp/soyuz/stories/webservice/xx-packageset.txt' | |||
177 | --- lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-08-20 04:46:48 +0000 | |||
178 | +++ lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-10-30 10:10:25 +0000 | |||
179 | @@ -52,16 +52,16 @@ | |||
180 | 52 | Can we access it via the webservice API as well? | 52 | Can we access it via the webservice API as well? |
181 | 53 | 53 | ||
182 | 54 | >>> logout() | 54 | >>> logout() |
184 | 55 | >>> umbrella = webservice.get("/package-sets/umbrella").jsonBody() | 55 | >>> umbrella = webservice.get("/package-sets/hoary/umbrella").jsonBody() |
185 | 56 | >>> print umbrella['self_link'] | 56 | >>> print umbrella['self_link'] |
187 | 57 | http://api.launchpad.dev/beta/package-sets/umbrella | 57 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
188 | 58 | 58 | ||
189 | 59 | `PackageSet`s can be looked up by name. | 59 | `PackageSet`s can be looked up by name. |
190 | 60 | 60 | ||
191 | 61 | >>> response = webservice.named_get( | 61 | >>> response = webservice.named_get( |
192 | 62 | ... '/package-sets', 'getByName', {}, name=u'umbrella') | 62 | ... '/package-sets', 'getByName', {}, name=u'umbrella') |
193 | 63 | >>> print response.jsonBody()['self_link'] | 63 | >>> print response.jsonBody()['self_link'] |
195 | 64 | http://api.launchpad.dev/beta/package-sets/umbrella | 64 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
196 | 65 | 65 | ||
197 | 66 | When a `PackageSet` cannot be found, an error is returned. | 66 | When a `PackageSet` cannot be found, an error is returned. |
198 | 67 | 67 | ||
199 | @@ -70,9 +70,17 @@ | |||
200 | 70 | >>> print response | 70 | >>> print response |
201 | 71 | HTTP/1.1 400 Bad Request | 71 | HTTP/1.1 400 Bad Request |
202 | 72 | ... | 72 | ... |
204 | 73 | NoSuchPackageSet: No such packageset: 'not-found'. | 73 | No such package set (in the specified distro series): 'not-found'. |
205 | 74 | ... | ||
206 | 74 | <BLANKLINE> | 75 | <BLANKLINE> |
207 | 75 | 76 | ||
208 | 77 | Here's an example with a funny URL concoted by a "smart" user. | ||
209 | 78 | |||
210 | 79 | >>> response = webservice.get("/package-sets/lucid-plus-1/umbrella/+pwn") | ||
211 | 80 | >>> print response | ||
212 | 81 | HTTP/1.1 404 Not Found | ||
213 | 82 | ... | ||
214 | 83 | |||
215 | 76 | Populate the 'umbrella' package set with source packages. | 84 | Populate the 'umbrella' package set with source packages. |
216 | 77 | 85 | ||
217 | 78 | >>> from canonical.launchpad.webapp.interfaces import ( | 86 | >>> from canonical.launchpad.webapp.interfaces import ( |
218 | @@ -81,7 +89,7 @@ | |||
219 | 81 | >>> store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) | 89 | >>> store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR) |
220 | 82 | >>> all_spns = store.find(SourcePackageName) | 90 | >>> all_spns = store.find(SourcePackageName) |
221 | 83 | >>> response = webservice.named_post( | 91 | >>> response = webservice.named_post( |
223 | 84 | ... '/package-sets/umbrella', 'addSources', {}, | 92 | ... '/package-sets/hoary/umbrella', 'addSources', {}, |
224 | 85 | ... names=[spn.name for spn in all_spns]) | 93 | ... names=[spn.name for spn in all_spns]) |
225 | 86 | >>> print response | 94 | >>> print response |
226 | 87 | HTTP/1.1 200 Ok | 95 | HTTP/1.1 200 Ok |
227 | @@ -91,7 +99,7 @@ | |||
228 | 91 | exist will not fail. Non-existing source package names are *ignored*. | 99 | exist will not fail. Non-existing source package names are *ignored*. |
229 | 92 | 100 | ||
230 | 93 | >>> response = webservice.named_post( | 101 | >>> response = webservice.named_post( |
232 | 94 | ... '/package-sets/umbrella', 'addSources', {}, | 102 | ... '/package-sets/hoary/umbrella', 'addSources', {}, |
233 | 95 | ... names=[u'does-not-exist']) | 103 | ... names=[u'does-not-exist']) |
234 | 96 | >>> print response | 104 | >>> print response |
235 | 97 | HTTP/1.1 200 Ok | 105 | HTTP/1.1 200 Ok |
236 | @@ -99,7 +107,7 @@ | |||
237 | 99 | null | 107 | null |
238 | 100 | 108 | ||
239 | 101 | >>> response = webservice.named_post( | 109 | >>> response = webservice.named_post( |
241 | 102 | ... '/package-sets/umbrella', 'removeSources', {}, | 110 | ... '/package-sets/hoary/umbrella', 'removeSources', {}, |
242 | 103 | ... names=[u'does-not-exist']) | 111 | ... names=[u'does-not-exist']) |
243 | 104 | >>> print response | 112 | >>> print response |
244 | 105 | HTTP/1.1 200 Ok | 113 | HTTP/1.1 200 Ok |
245 | @@ -109,7 +117,7 @@ | |||
246 | 109 | Let's see what we got. | 117 | Let's see what we got. |
247 | 110 | 118 | ||
248 | 111 | >>> response = webservice.named_get( | 119 | >>> response = webservice.named_get( |
250 | 112 | ... '/package-sets/umbrella', 'getSourcesIncluded', {}) | 120 | ... '/package-sets/hoary/umbrella', 'getSourcesIncluded', {}) |
251 | 113 | >>> print response | 121 | >>> print response |
252 | 114 | HTTP/1.1 200 Ok | 122 | HTTP/1.1 200 Ok |
253 | 115 | ... | 123 | ... |
254 | @@ -136,7 +144,7 @@ | |||
255 | 136 | from the 'umbrella' package set. | 144 | from the 'umbrella' package set. |
256 | 137 | 145 | ||
257 | 138 | >>> response = webservice.named_post( | 146 | >>> response = webservice.named_post( |
259 | 139 | ... '/package-sets/umbrella', 'removeSources', {}, | 147 | ... '/package-sets/hoary/umbrella', 'removeSources', {}, |
260 | 140 | ... names=["foobar", "iceweasel"]) | 148 | ... names=["foobar", "iceweasel"]) |
261 | 141 | >>> print response | 149 | >>> print response |
262 | 142 | HTTP/1.1 200 Ok | 150 | HTTP/1.1 200 Ok |
263 | @@ -146,7 +154,7 @@ | |||
264 | 146 | from the list below. | 154 | from the list below. |
265 | 147 | 155 | ||
266 | 148 | >>> response = webservice.named_get( | 156 | >>> response = webservice.named_get( |
268 | 149 | ... '/package-sets/umbrella', 'getSourcesIncluded', {}) | 157 | ... '/package-sets/hoary/umbrella', 'getSourcesIncluded', {}) |
269 | 150 | >>> print response | 158 | >>> print response |
270 | 151 | HTTP/1.1 200 Ok | 159 | HTTP/1.1 200 Ok |
271 | 152 | ... | 160 | ... |
272 | @@ -176,13 +184,13 @@ | |||
273 | 176 | 184 | ||
274 | 177 | >>> response = webservice.get("/package-sets/") | 185 | >>> response = webservice.get("/package-sets/") |
275 | 178 | >>> print_payload(response) | 186 | >>> print_payload(response) |
277 | 179 | http://api.launchpad.dev/beta/package-sets/umbrella | 187 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
278 | 180 | 188 | ||
279 | 181 | Package sets may include other package sets (as subsets). At this point, | 189 | Package sets may include other package sets (as subsets). At this point, |
280 | 182 | however, we only have the 'umbrella' package set. It hence has no subsets. | 190 | however, we only have the 'umbrella' package set. It hence has no subsets. |
281 | 183 | 191 | ||
282 | 184 | >>> response = webservice.named_get( | 192 | >>> response = webservice.named_get( |
284 | 185 | ... '/package-sets/umbrella', 'setsIncluded', {}) | 193 | ... '/package-sets/hoary/umbrella', 'setsIncluded', {}) |
285 | 186 | >>> print response | 194 | >>> print response |
286 | 187 | HTTP/1.1 200 Ok | 195 | HTTP/1.1 200 Ok |
287 | 188 | ... | 196 | ... |
288 | @@ -245,27 +253,27 @@ | |||
289 | 245 | * languagepack | 253 | * languagepack |
290 | 246 | 254 | ||
291 | 247 | >>> response = webservice.named_post( | 255 | >>> response = webservice.named_post( |
293 | 248 | ... '/package-sets/umbrella', 'addSubsets', {}, | 256 | ... '/package-sets/hoary/umbrella', 'addSubsets', {}, |
294 | 249 | ... names=[u'gnome', u'mozilla']) | 257 | ... names=[u'gnome', u'mozilla']) |
295 | 250 | >>> print response | 258 | >>> print response |
296 | 251 | HTTP/1.1 200 Ok | 259 | HTTP/1.1 200 Ok |
297 | 252 | ... | 260 | ... |
298 | 253 | 261 | ||
299 | 254 | >>> response = webservice.named_post( | 262 | >>> response = webservice.named_post( |
301 | 255 | ... '/package-sets/gnome', 'addSubsets', {}, names=[u'languagepack']) | 263 | ... '/package-sets/hoary/gnome', 'addSubsets', {}, names=[u'languagepack']) |
302 | 256 | >>> print response | 264 | >>> print response |
303 | 257 | HTTP/1.1 200 Ok | 265 | HTTP/1.1 200 Ok |
304 | 258 | ... | 266 | ... |
305 | 259 | 267 | ||
306 | 260 | >>> response = webservice.named_post( | 268 | >>> response = webservice.named_post( |
308 | 261 | ... '/package-sets/thunderbird', 'addSubsets', {}, | 269 | ... '/package-sets/hoary/thunderbird', 'addSubsets', {}, |
309 | 262 | ... names=[u'languagepack']) | 270 | ... names=[u'languagepack']) |
310 | 263 | >>> print response | 271 | >>> print response |
311 | 264 | HTTP/1.1 200 Ok | 272 | HTTP/1.1 200 Ok |
312 | 265 | ... | 273 | ... |
313 | 266 | 274 | ||
314 | 267 | >>> response = webservice.named_post( | 275 | >>> response = webservice.named_post( |
316 | 268 | ... '/package-sets/mozilla', 'addSubsets', {}, | 276 | ... '/package-sets/hoary/mozilla', 'addSubsets', {}, |
317 | 269 | ... names=[u'firefox', u'thunderbird']) | 277 | ... names=[u'firefox', u'thunderbird']) |
318 | 270 | >>> print response | 278 | >>> print response |
319 | 271 | HTTP/1.1 200 Ok | 279 | HTTP/1.1 200 Ok |
320 | @@ -275,7 +283,7 @@ | |||
321 | 275 | non-existing package sets will not fail. | 283 | non-existing package sets will not fail. |
322 | 276 | 284 | ||
323 | 277 | >>> response = webservice.named_post( | 285 | >>> response = webservice.named_post( |
325 | 278 | ... '/package-sets/thunderbird', 'addSubsets', {}, | 286 | ... '/package-sets/hoary/thunderbird', 'addSubsets', {}, |
326 | 279 | ... names=[u'does-not-exist']) | 287 | ... names=[u'does-not-exist']) |
327 | 280 | >>> print response | 288 | >>> print response |
328 | 281 | HTTP/1.1 200 Ok | 289 | HTTP/1.1 200 Ok |
329 | @@ -283,7 +291,7 @@ | |||
330 | 283 | null | 291 | null |
331 | 284 | 292 | ||
332 | 285 | >>> response = webservice.named_post( | 293 | >>> response = webservice.named_post( |
334 | 286 | ... '/package-sets/thunderbird', 'removeSubsets', {}, | 294 | ... '/package-sets/hoary/thunderbird', 'removeSubsets', {}, |
335 | 287 | ... names=[u'does-not-exist']) | 295 | ... names=[u'does-not-exist']) |
336 | 288 | >>> print response | 296 | >>> print response |
337 | 289 | HTTP/1.1 200 Ok | 297 | HTTP/1.1 200 Ok |
338 | @@ -293,49 +301,49 @@ | |||
339 | 293 | The 'umbrella' package set should have plenty of subsets now. | 301 | The 'umbrella' package set should have plenty of subsets now. |
340 | 294 | 302 | ||
341 | 295 | >>> response = webservice.named_get( | 303 | >>> response = webservice.named_get( |
343 | 296 | ... '/package-sets/umbrella', 'setsIncluded', {}) | 304 | ... '/package-sets/hoary/umbrella', 'setsIncluded', {}) |
344 | 297 | >>> print_payload(response) | 305 | >>> print_payload(response) |
350 | 298 | http://api.launchpad.dev/beta/package-sets/firefox | 306 | http://api.launchpad.dev/beta/package-sets/hoary/firefox |
351 | 299 | http://api.launchpad.dev/beta/package-sets/gnome | 307 | http://api.launchpad.dev/beta/package-sets/hoary/gnome |
352 | 300 | http://api.launchpad.dev/beta/package-sets/languagepack | 308 | http://api.launchpad.dev/beta/package-sets/hoary/languagepack |
353 | 301 | http://api.launchpad.dev/beta/package-sets/mozilla | 309 | http://api.launchpad.dev/beta/package-sets/hoary/mozilla |
354 | 302 | http://api.launchpad.dev/beta/package-sets/thunderbird | 310 | http://api.launchpad.dev/beta/package-sets/hoary/thunderbird |
355 | 303 | 311 | ||
356 | 304 | However only two of the above are direct subsets. | 312 | However only two of the above are direct subsets. |
357 | 305 | 313 | ||
358 | 306 | >>> response = webservice.named_get( | 314 | >>> response = webservice.named_get( |
360 | 307 | ... '/package-sets/umbrella', 'setsIncluded', {}, | 315 | ... '/package-sets/hoary/umbrella', 'setsIncluded', {}, |
361 | 308 | ... direct_inclusion=True) | 316 | ... direct_inclusion=True) |
362 | 309 | >>> print_payload(response) | 317 | >>> print_payload(response) |
365 | 310 | http://api.launchpad.dev/beta/package-sets/gnome | 318 | http://api.launchpad.dev/beta/package-sets/hoary/gnome |
366 | 311 | http://api.launchpad.dev/beta/package-sets/mozilla | 319 | http://api.launchpad.dev/beta/package-sets/hoary/mozilla |
367 | 312 | 320 | ||
368 | 313 | Let's ask the question the other way around what package sets are including | 321 | Let's ask the question the other way around what package sets are including |
369 | 314 | a particular subset? | 322 | a particular subset? |
370 | 315 | 323 | ||
371 | 316 | >>> response = webservice.named_get( | 324 | >>> response = webservice.named_get( |
373 | 317 | ... '/package-sets/languagepack', 'setsIncludedBy', {}) | 325 | ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {}) |
374 | 318 | >>> print_payload(response) | 326 | >>> print_payload(response) |
379 | 319 | http://api.launchpad.dev/beta/package-sets/gnome | 327 | http://api.launchpad.dev/beta/package-sets/hoary/gnome |
380 | 320 | http://api.launchpad.dev/beta/package-sets/mozilla | 328 | http://api.launchpad.dev/beta/package-sets/hoary/mozilla |
381 | 321 | http://api.launchpad.dev/beta/package-sets/thunderbird | 329 | http://api.launchpad.dev/beta/package-sets/hoary/thunderbird |
382 | 322 | http://api.launchpad.dev/beta/package-sets/umbrella | 330 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
383 | 323 | 331 | ||
384 | 324 | The list of package sets that *directly* include 'languagepack' will be | 332 | The list of package sets that *directly* include 'languagepack' will be |
385 | 325 | shorter because the transitive closure is ignored. | 333 | shorter because the transitive closure is ignored. |
386 | 326 | 334 | ||
387 | 327 | >>> response = webservice.named_get( | 335 | >>> response = webservice.named_get( |
389 | 328 | ... '/package-sets/languagepack', 'setsIncludedBy', {}, | 336 | ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {}, |
390 | 329 | ... direct_inclusion=True) | 337 | ... direct_inclusion=True) |
391 | 330 | >>> print_payload(response) | 338 | >>> print_payload(response) |
394 | 331 | http://api.launchpad.dev/beta/package-sets/gnome | 339 | http://api.launchpad.dev/beta/package-sets/hoary/gnome |
395 | 332 | http://api.launchpad.dev/beta/package-sets/thunderbird | 340 | http://api.launchpad.dev/beta/package-sets/hoary/thunderbird |
396 | 333 | 341 | ||
397 | 334 | We can remove subsets as well. In the example below 'thunderbird' will | 342 | We can remove subsets as well. In the example below 'thunderbird' will |
398 | 335 | stop including 'languagepack'. | 343 | stop including 'languagepack'. |
399 | 336 | 344 | ||
400 | 337 | >>> response = webservice.named_post( | 345 | >>> response = webservice.named_post( |
402 | 338 | ... '/package-sets/thunderbird', 'removeSubsets', {}, | 346 | ... '/package-sets/hoary/thunderbird', 'removeSubsets', {}, |
403 | 339 | ... names=[u'languagepack']) | 347 | ... names=[u'languagepack']) |
404 | 340 | >>> print response | 348 | >>> print response |
405 | 341 | HTTP/1.1 200 Ok | 349 | HTTP/1.1 200 Ok |
406 | @@ -344,37 +352,37 @@ | |||
407 | 344 | And, here we go, now 'languagepack' has only one direct predecessor: 'gnome'. | 352 | And, here we go, now 'languagepack' has only one direct predecessor: 'gnome'. |
408 | 345 | 353 | ||
409 | 346 | >>> response = webservice.named_get( | 354 | >>> response = webservice.named_get( |
411 | 347 | ... '/package-sets/languagepack', 'setsIncludedBy', {}, | 355 | ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {}, |
412 | 348 | ... direct_inclusion=True) | 356 | ... direct_inclusion=True) |
413 | 349 | >>> print_payload(response) | 357 | >>> print_payload(response) |
415 | 350 | http://api.launchpad.dev/beta/package-sets/gnome | 358 | http://api.launchpad.dev/beta/package-sets/hoary/gnome |
416 | 351 | 359 | ||
417 | 352 | Let's add a few source packages to the 'firefox' and the 'thunderbird' | 360 | Let's add a few source packages to the 'firefox' and the 'thunderbird' |
418 | 353 | package sets. | 361 | package sets. |
419 | 354 | 362 | ||
420 | 355 | >>> response = webservice.named_post( | 363 | >>> response = webservice.named_post( |
422 | 356 | ... '/package-sets/firefox', 'addSources', {}, | 364 | ... '/package-sets/hoary/firefox', 'addSources', {}, |
423 | 357 | ... names=['at', 'mozilla-firefox', 'language-pack-de']) | 365 | ... names=['at', 'mozilla-firefox', 'language-pack-de']) |
424 | 358 | >>> print response | 366 | >>> print response |
425 | 359 | HTTP/1.1 200 Ok | 367 | HTTP/1.1 200 Ok |
426 | 360 | ... | 368 | ... |
427 | 361 | 369 | ||
428 | 362 | >>> response = webservice.named_get( | 370 | >>> response = webservice.named_get( |
430 | 363 | ... '/package-sets/firefox', 'getSourcesIncluded', {}) | 371 | ... '/package-sets/hoary/firefox', 'getSourcesIncluded', {}) |
431 | 364 | >>> print response | 372 | >>> print response |
432 | 365 | HTTP/1.1 200 Ok | 373 | HTTP/1.1 200 Ok |
433 | 366 | ... | 374 | ... |
434 | 367 | ["at", "language-pack-de", "mozilla-firefox"] | 375 | ["at", "language-pack-de", "mozilla-firefox"] |
435 | 368 | 376 | ||
436 | 369 | >>> response = webservice.named_post( | 377 | >>> response = webservice.named_post( |
438 | 370 | ... '/package-sets/thunderbird', 'addSources', {}, | 378 | ... '/package-sets/hoary/thunderbird', 'addSources', {}, |
439 | 371 | ... names=['at', 'cnews', 'thunderbird', 'language-pack-de']) | 379 | ... names=['at', 'cnews', 'thunderbird', 'language-pack-de']) |
440 | 372 | >>> print response | 380 | >>> print response |
441 | 373 | HTTP/1.1 200 Ok | 381 | HTTP/1.1 200 Ok |
442 | 374 | ... | 382 | ... |
443 | 375 | 383 | ||
444 | 376 | >>> response = webservice.named_get( | 384 | >>> response = webservice.named_get( |
446 | 377 | ... '/package-sets/thunderbird', 'getSourcesIncluded', {}) | 385 | ... '/package-sets/hoary/thunderbird', 'getSourcesIncluded', {}) |
447 | 378 | >>> print response | 386 | >>> print response |
448 | 379 | HTTP/1.1 200 Ok | 387 | HTTP/1.1 200 Ok |
449 | 380 | ... | 388 | ... |
450 | @@ -386,9 +394,9 @@ | |||
451 | 386 | ... '/package-sets/', 'setsIncludingSource', {}, | 394 | ... '/package-sets/', 'setsIncludingSource', {}, |
452 | 387 | ... sourcepackagename=u'mozilla-firefox') | 395 | ... sourcepackagename=u'mozilla-firefox') |
453 | 388 | >>> print_payload(response) | 396 | >>> print_payload(response) |
457 | 389 | http://api.launchpad.dev/beta/package-sets/firefox | 397 | http://api.launchpad.dev/beta/package-sets/hoary/firefox |
458 | 390 | http://api.launchpad.dev/beta/package-sets/mozilla | 398 | http://api.launchpad.dev/beta/package-sets/hoary/mozilla |
459 | 391 | http://api.launchpad.dev/beta/package-sets/umbrella | 399 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
460 | 392 | 400 | ||
461 | 393 | Which package sets include the 'mozilla-firefox' source package *directly*? | 401 | Which package sets include the 'mozilla-firefox' source package *directly*? |
462 | 394 | 402 | ||
463 | @@ -397,8 +405,8 @@ | |||
464 | 397 | ... sourcepackagename=u'mozilla-firefox', | 405 | ... sourcepackagename=u'mozilla-firefox', |
465 | 398 | ... direct_inclusion=True) | 406 | ... direct_inclusion=True) |
466 | 399 | >>> print_payload(response) | 407 | >>> print_payload(response) |
469 | 400 | http://api.launchpad.dev/beta/package-sets/firefox | 408 | http://api.launchpad.dev/beta/package-sets/hoary/firefox |
470 | 401 | http://api.launchpad.dev/beta/package-sets/umbrella | 409 | http://api.launchpad.dev/beta/package-sets/hoary/umbrella |
471 | 402 | 410 | ||
472 | 403 | If a non-existing source package name is passed it returns an error. | 411 | If a non-existing source package name is passed it returns an error. |
473 | 404 | 412 | ||
474 | @@ -414,9 +422,9 @@ | |||
475 | 414 | What source packages are shared by the 'firefox' and the 'thunderbird' | 422 | What source packages are shared by the 'firefox' and the 'thunderbird' |
476 | 415 | package sets? | 423 | package sets? |
477 | 416 | 424 | ||
479 | 417 | >>> thunderbird = webservice.get("/package-sets/thunderbird").jsonBody() | 425 | >>> thunderbird = webservice.get("/package-sets/hoary/thunderbird").jsonBody() |
480 | 418 | >>> response = webservice.named_get( | 426 | >>> response = webservice.named_get( |
482 | 419 | ... '/package-sets/firefox', 'getSourcesSharedBy', {}, | 427 | ... '/package-sets/hoary/firefox', 'getSourcesSharedBy', {}, |
483 | 420 | ... other_package_set=thunderbird['self_link']) | 428 | ... other_package_set=thunderbird['self_link']) |
484 | 421 | >>> print response | 429 | >>> print response |
485 | 422 | HTTP/1.1 200 Ok | 430 | HTTP/1.1 200 Ok |
486 | @@ -426,16 +434,16 @@ | |||
487 | 426 | How about the complement set i.e. the packages not shared? | 434 | How about the complement set i.e. the packages not shared? |
488 | 427 | 435 | ||
489 | 428 | >>> response = webservice.named_get( | 436 | >>> response = webservice.named_get( |
491 | 429 | ... '/package-sets/firefox', 'getSourcesNotSharedBy', {}, | 437 | ... '/package-sets/hoary/firefox', 'getSourcesNotSharedBy', {}, |
492 | 430 | ... other_package_set=thunderbird['self_link']) | 438 | ... other_package_set=thunderbird['self_link']) |
493 | 431 | >>> print response | 439 | >>> print response |
494 | 432 | HTTP/1.1 200 Ok | 440 | HTTP/1.1 200 Ok |
495 | 433 | ... | 441 | ... |
496 | 434 | ["mozilla-firefox"] | 442 | ["mozilla-firefox"] |
497 | 435 | 443 | ||
499 | 436 | >>> firefox = webservice.get("/package-sets/firefox").jsonBody() | 444 | >>> firefox = webservice.get("/package-sets/hoary/firefox").jsonBody() |
500 | 437 | >>> response = webservice.named_get( | 445 | >>> response = webservice.named_get( |
502 | 438 | ... '/package-sets/thunderbird', 'getSourcesNotSharedBy', {}, | 446 | ... '/package-sets/hoary/thunderbird', 'getSourcesNotSharedBy', {}, |
503 | 439 | ... other_package_set=firefox['self_link']) | 447 | ... other_package_set=firefox['self_link']) |
504 | 440 | >>> print response | 448 | >>> print response |
505 | 441 | HTTP/1.1 200 Ok | 449 | HTTP/1.1 200 Ok |
506 | @@ -443,6 +451,39 @@ | |||
507 | 443 | ["cnews", "thunderbird"] | 451 | ["cnews", "thunderbird"] |
508 | 444 | 452 | ||
509 | 445 | 453 | ||
510 | 454 | === Package sets and distro series === | ||
511 | 455 | |||
512 | 456 | Every package set is associated with a distro series. | ||
513 | 457 | |||
514 | 458 | >>> from lazr.restful.testing.webservice import pprint_entry | ||
515 | 459 | >>> mozilla = webservice.named_get( | ||
516 | 460 | ... '/package-sets', 'getByName', {}, name=u'mozilla').jsonBody() | ||
517 | 461 | >>> print mozilla['distroseries_link'] | ||
518 | 462 | http://api.launchpad.dev/beta/ubuntu/hoary | ||
519 | 463 | |||
520 | 464 | |||
521 | 465 | === Related package sets === | ||
522 | 466 | |||
523 | 467 | When adding a package set we can specify that is to be related to another set | ||
524 | 468 | that exists already. | ||
525 | 469 | |||
526 | 470 | >>> grumpy = webservice.get("/ubuntu/grumpy").jsonBody() | ||
527 | 471 | >>> print grumpy['self_link'] | ||
528 | 472 | http://api.launchpad.dev/beta/ubuntu/grumpy | ||
529 | 473 | |||
530 | 474 | We are adding a new 'mozilla' package set to the 'grumpy' distro series and | ||
531 | 475 | it is related to 'mozilla' in 'hoary'. | ||
532 | 476 | |||
533 | 477 | >>> response = webservice.named_post( | ||
534 | 478 | ... '/package-sets', 'new', {}, | ||
535 | 479 | ... name=u'mozilla', | ||
536 | 480 | ... description=u'Contains all mozilla packages', | ||
537 | 481 | ... owner=name12['self_link'], distroseries=grumpy['self_link'], | ||
538 | 482 | ... related_set=mozilla['self_link']) | ||
539 | 483 | >>> print response | ||
540 | 484 | HTTP/1.1 201 Created | ||
541 | 485 | ... | ||
542 | 486 | |||
543 | 446 | == Archive permissions and package sets == | 487 | == Archive permissions and package sets == |
544 | 447 | 488 | ||
545 | 448 | Operating on package set based archive permissions is possible via | 489 | Operating on package set based archive permissions is possible via |
Hello there!
a branch that introduces the association between package sets and distro
series has already landed on db-devel.
Package set names are now *not* globally unique any more but only unique
within the context of a distro series.
The branch at hand revises the package set traversal rules accordingly.
Pre-implementation call with Michael Nelson.
Tests to run:
bin/test -vvt packageset
No pertinent "make lint" errors or warnings.