Merge lp:~al-maisan/launchpad/psds-model-changes-399186 into lp:launchpad/db-devel

Proposed by Muharem Hrnjadovic
Status: Merged
Merged at revision: not available
Proposed branch: lp:~al-maisan/launchpad/psds-model-changes-399186
Merge into: lp:launchpad/db-devel
Diff against target: 668 lines
10 files modified
database/schema/comments.sql (+10/-1)
database/schema/patch-2207-06-0.sql (+122/-0)
database/schema/security.cfg (+5/-0)
database/schema/trusted.sql (+15/-0)
lib/lp/soyuz/configure.zcml (+8/-0)
lib/lp/soyuz/interfaces/packageset.py (+40/-5)
lib/lp/soyuz/interfaces/packagesetgroup.py (+41/-0)
lib/lp/soyuz/model/packageset.py (+53/-5)
lib/lp/soyuz/model/packagesetgroup.py (+30/-0)
lib/lp/soyuz/tests/test_packageset.py (+121/-0)
To merge this branch: bzr merge lp:~al-maisan/launchpad/psds-model-changes-399186
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+14038@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Hello there!

The branch at hand introduces the association between package sets and
distro series as well as a new model class (PackagesetGroup) that
facilitates the tracking of equivalent package sets across distro series
boundaries.

For more detail on these changes and why they are needed, please see:

  * the original "package set and distro series" meeting minutes:
    http://pastebin.ubuntu.com/302054/
  * Julian's update: http://pastebin.ubuntu.com/302058/

Please note that the underlying db schema patch (http://tinyurl.com/ykkwb97) has already been approved.
This branch is based on the respective schema patch branch (lp:~al-maisan/launchpad/psds-399186). The *actual* diff for it is here:

    http://pastebin.ubuntu.com/302886/

Tests to run:

    bin/test -vvt packageset

No pertinent "make lint" errors or warnings.

Revision history for this message
Brad Crittenden (bac) wrote :

Hi Muharem,

Thanks for the branch. It looks good except for the following small items:

* Line 46 - End of line comments are discouraged by our coding standards. Please move to the previous line.

* I think "The person who owns the package set at hand." would read better for most users as "The person who owns this package set."

* Lines 91,110 - Capitalize Ubuntu.

* Line 383 - typo 'dupliacte'

review: Approve (code)
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Brad Crittenden wrote:
> Review: Approve code
> Hi Muharem,
>
> Thanks for the branch. It looks good except for the following small items:
>
> * Line 46 - End of line comments are discouraged by our coding standards. Please move to the previous line.
>
> * I think "The person who owns the package set at hand." would read better for most users as "The person who owns this package set."
>
> * Lines 91,110 - Capitalize Ubuntu.
>
> * Line 383 - typo 'dupliacte'

Hello Brad,

thank you very much for the review! I have revised the branch to
accommodate your suggestions.

Best regards

--
Muharem Hrnjadovic <email address hidden>
Public key id : B2BBFCFC
Key fingerprint : A5A3 CC67 2B87 D641 103F 5602 219F 6B60 B2BB FCFC

=== modified file 'lib/lp/soyuz/interfaces/packageset.py'
--- lib/lp/soyuz/interfaces/packageset.py 2009-10-27 15:42:04 +0000
+++ lib/lp/soyuz/interfaces/packageset.py 2009-10-27 22:26:47 +0000
@@ -35,13 +35,15 @@
3535
36class NoSuchPackageSet(NameLookupFailed):36class NoSuchPackageSet(NameLookupFailed):
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."""
38 webservice_error(400) #Bad request.38 # Bad request.
39 webservice_error(400)
39 _message_prefix = "No such packageset"40 _message_prefix = "No such packageset"
4041
4142
42class DuplicatePackagesetName(Exception):43class DuplicatePackagesetName(Exception):
43 """Raised for packagesets with the same name and distroseries."""44 """Raised for packagesets with the same name and distroseries."""
44 webservice_error(400) # Bad request.45 # Bad request.
46 webservice_error(400)
4547
4648
47class IPackagesetViewOnly(IHasOwner):49class IPackagesetViewOnly(IHasOwner):
@@ -56,7 +58,7 @@
5658
57 owner = exported(Reference(59 owner = exported(Reference(
58 IPerson, title=_("Person"), required=True, readonly=True,60 IPerson, title=_("Person"), required=True, readonly=True,
59 description=_("The person who owns the package set at hand.")))61 description=_("The person who owns this package set.")))
6062
61 name = exported(TextLine(63 name = exported(TextLine(
62 title=_('Valid package set name'),64 title=_('Valid package set name'),
@@ -336,7 +338,7 @@
336 title=_('Package set description'), required=True),338 title=_('Package set description'), required=True),
337 owner=Reference(339 owner=Reference(
338 IPerson, title=_("Person"), required=True, readonly=True,340 IPerson, title=_("Person"), required=True, readonly=True,
339 description=_("The person who owns the package set at hand.")),341 description=_("The person who owns this package set.")),
340 distroseries=Reference(342 distroseries=Reference(
341 IDistroSeries, title=_("Distroseries"), required=False,343 IDistroSeries, title=_("Distroseries"), required=False,
342 readonly=True, description=_(344 readonly=True, description=_(
@@ -350,7 +352,7 @@
350 :param description: the description for the package set to be created.352 :param description: the description for the package set to be created.
351 :param owner: the owner of the package set to be created.353 :param owner: the owner of the package set to be created.
352 :param distroseries: the distroseries to which the new packageset354 :param distroseries: the distroseries to which the new packageset
353 is related. Defaults to the current ubuntu series.355 is related. Defaults to the current Ubuntu series.
354 :param related_set: the newly created package set is to be related to356 :param related_set: the newly created package set is to be related to
355 `related_set` (by being placed in the same package group).357 `related_set` (by being placed in the same package group).
356358
@@ -368,7 +370,7 @@
368370
369 :param name: the name of the package set sought.371 :param name: the name of the package set sought.
370 :param distroseries: the distroseries to which the new packageset372 :param distroseries: the distroseries to which the new packageset
371 is related. Defaults to the current ubuntu series.373 is related. Defaults to the current Ubuntu series.
372374
373 :return: An `IPackageset` instance or None.375 :return: An `IPackageset` instance or None.
374 """376 """
375377
=== modified file 'lib/lp/soyuz/tests/test_packageset.py'
--- lib/lp/soyuz/tests/test_packageset.py 2009-10-27 15:51:28 +0000
+++ lib/lp/soyuz/tests/test_packageset.py 2009-10-27 22:21:31 +0000
@@ -70,7 +70,7 @@
7070
71 self.failUnlessRaises(71 self.failUnlessRaises(
72 DuplicatePackagesetName, self.packageset_set.new,72 DuplicatePackagesetName, self.packageset_set.new,
73 u'kernel', u'A packageset with a dupliacte name', self.person1,73 u'kernel', u'A packageset with a duplicate name', self.person1,
74 distroseries=self.distroseries_experimental)74 distroseries=self.distroseries_experimental)
7575
76 def test_new_duplicate_name_for_different_distroseries(self):76 def test_new_duplicate_name_for_different_distroseries(self):

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'database/schema/comments.sql'
--- database/schema/comments.sql 2009-10-07 12:54:03 +0000
+++ database/schema/comments.sql 2009-10-27 23:43:13 +0000
@@ -2239,11 +2239,20 @@
22392239
2240-- Packageset2240-- Packageset
22412241
2242COMMENT ON TABLE Packageset IS 'Package sets facilitate the grouping of packages for purposes like the control of upload permissions, et.';2242COMMENT ON TABLE Packageset IS 'Package sets facilitate the grouping of packages (in a given distro series) for purposes like the control of upload permissions, etc.';
2243COMMENT ON COLUMN Packageset.date_created IS 'Date and time of creation.';2243COMMENT ON COLUMN Packageset.date_created IS 'Date and time of creation.';
2244COMMENT ON COLUMN Packageset.owner IS 'The Person or team who owns the package set';2244COMMENT ON COLUMN Packageset.owner IS 'The Person or team who owns the package set';
2245COMMENT ON COLUMN Packageset.name IS 'The name for the package set on hand.';2245COMMENT ON COLUMN Packageset.name IS 'The name for the package set on hand.';
2246COMMENT ON COLUMN Packageset.description IS 'The description for the package set on hand.';2246COMMENT ON COLUMN Packageset.description IS 'The description for the package set on hand.';
2247COMMENT ON COLUMN Packageset.packagesetgroup IS 'The group this package set is affiliated with.';
2248COMMENT ON COLUMN Packageset.distroseries IS 'The distro series this package set belongs to.';
2249
2250-- PackagesetGroup
2251
2252COMMENT ON TABLE PackagesetGroup IS 'Package set groups keep track of equivalent package sets across distro series boundaries.';
2253COMMENT ON COLUMN Packageset.date_created IS 'Date and time of creation.';
2254COMMENT ON COLUMN Packageset.owner IS 'The Person or team who owns the package
2255set group.';
22472256
2248-- PackagesetSources2257-- PackagesetSources
22492258
22502259
=== added file 'database/schema/patch-2207-06-0.sql'
--- database/schema/patch-2207-06-0.sql 1970-01-01 00:00:00 +0000
+++ database/schema/patch-2207-06-0.sql 2009-10-27 23:43:13 +0000
@@ -0,0 +1,122 @@
1-- Copyright 2009 Canonical Ltd. This software is licensed under the
2-- GNU Affero General Public License version 3 (see the file LICENSE).
3
4SET client_min_messages=ERROR;
5
6-- ** PART 1 ** Create the 'packagesetgroup' table and the
7-- 'packageset.packagesetgroup' foreign key,
8-- populate the 'packagesetgroup' table
9
10-- This table keeps track of package sets that are equivalent across
11-- distro series boundaries.
12CREATE SEQUENCE packagesetgroup_id_seq
13 START WITH 1
14 INCREMENT BY 1
15 NO MAXVALUE
16 NO MINVALUE
17 CACHE 1;
18CREATE TABLE packagesetgroup (
19 id integer NOT NULL DEFAULT nextval('packagesetgroup_id_seq'),
20 date_created timestamp without time zone DEFAULT timezone('UTC'::text, now()) NOT NULL,
21 owner integer NOT NULL,
22 -- Please note: the 'name' column is only here to ease the data migration
23 -- and will be dropped at the end of this patch.
24 name text NOT NULL
25);
26ALTER SEQUENCE packagesetgroup_id_seq OWNED BY packagesetgroup.id;
27ALTER TABLE ONLY packagesetgroup
28 ADD CONSTRAINT packagesetgroup_pkey PRIMARY KEY (id);
29ALTER TABLE ONLY packagesetgroup
30 ADD CONSTRAINT packagesetgroup__owner__fk
31 FOREIGN KEY (owner) REFERENCES person(id);
32
33-- Package sets and their clones belong to the same package set group.
34ALTER TABLE ONLY packageset ADD COLUMN packagesetgroup integer;
35ALTER TABLE ONLY packageset
36 ADD CONSTRAINT packageset__packagesetgroup__fk
37 FOREIGN KEY (packagesetgroup) REFERENCES packagesetgroup(id);
38
39-- Create a group for each of the original (karmic koala) package sets.
40INSERT INTO packagesetgroup(owner, name)
41SELECT packageset.owner, packageset.name
42FROM packageset WHERE NOT packageset.name LIKE('lucid-%');
43
44
45-- ** PART 2 ** Associate the karmic koala package sets and their lucid lynx
46-- clones with the appropriate package set groups
47
48-- Update the karmic koala package sets so they reference their groups.
49UPDATE packageset SET packagesetgroup = packagesetgroup.id
50FROM packagesetgroup WHERE packageset.name = packagesetgroup.name;
51
52-- Update the lucid lynx package set *clones* so they reference their groups
53-- as well.
54UPDATE packageset SET packagesetgroup = packagesetgroup.id
55FROM packagesetgroup WHERE packageset.name = 'lucid-' || packagesetgroup.name;
56
57-- ** PART 3 ** Add the 'packageset.distroseries' foreign key and
58-- initialise it for the existing package sets.
59
60-- A package set lives in a distro series context.
61ALTER TABLE ONLY packageset ADD COLUMN distroseries integer;
62
63-- Define the foreign key constraint.
64ALTER TABLE ONLY packageset
65 ADD CONSTRAINT packageset__distroseries__fk
66 FOREIGN KEY (distroseries) REFERENCES distroseries(id);
67
68-- First migrate the original package sets created for the karmic koala.
69UPDATE packageset SET distroseries = distroseries.id FROM distroseries
70WHERE distroseries.name = 'karmic' AND NOT packageset.name LIKE('lucid-%');
71
72-- Migrate the lucid lynx package sets next.
73UPDATE packageset SET distroseries = distroseries.id FROM distroseries
74WHERE distroseries.name = 'lucid' AND packageset.name LIKE('lucid-%');
75
76-- Make the 'distroseries' foreign key mandatory.
77ALTER TABLE ONLY packageset ALTER COLUMN distroseries SET NOT NULL;
78
79-- The package set name is now only unique in conjunction with a distro series.
80ALTER TABLE ONLY packageset
81 DROP CONSTRAINT packageset_name_key;
82ALTER TABLE ONLY packageset
83 ADD CONSTRAINT packageset__name__distroseries__key UNIQUE (name, distroseries);
84
85-- ** PART 4 ** Strip off the 'lucid-' prefix of the lucid lynx
86-- package set names
87UPDATE packageset SET name = substring(name FROM length('lucid-')+1)
88WHERE name LIKE('lucid-%');
89
90-- ** PART 5 ** Create package set groups for package sets that were added in
91-- lucid lynx but do not exist in the karmic koala,
92-- associate these package sets with their newly created groups
93INSERT INTO packagesetgroup(owner, name)
94SELECT packageset.owner, packageset.name
95FROM packageset, distroseries WHERE
96 packageset.packagesetgroup IS NULL
97 AND packageset.distroseries = distroseries.id
98 AND distroseries.name = 'lucid';
99
100UPDATE packageset SET packagesetgroup = packagesetgroup.id
101FROM packagesetgroup, distroseries
102WHERE
103 packageset.packagesetgroup IS NULL
104 AND packageset.distroseries = distroseries.id
105 AND distroseries.name = 'lucid'
106 AND packageset.name = packagesetgroup.name;
107
108-- ** PART 6 ** Make the 'packageset.packagesetgroup' foreign key mandatory
109ALTER TABLE ONLY packageset ALTER COLUMN packagesetgroup SET NOT NULL;
110
111-- ** PART 7 ** Drop the 'packagesetgroup.name' column that was only added
112-- for data migration purposes.
113ALTER TABLE ONLY packagesetgroup DROP COLUMN name;
114
115-- Define indices on the newly added foreign keys.
116CREATE INDEX packageset__packagesetgroup__idx
117 ON packageset(packagesetgroup);
118CREATE INDEX packageset__distroseries__idx
119 ON packageset(distroseries);
120CREATE INDEX packagesetgroup__owner__idx ON PackageSetGroup(owner);
121
122INSERT INTO LaunchpadDatabaseRevision VALUES (2207, 06, 0);
0123
=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg 2009-10-15 23:26:39 +0000
+++ database/schema/security.cfg 2009-10-27 23:43:13 +0000
@@ -226,6 +226,7 @@
226public.packagediff = SELECT, INSERT, UPDATE, DELETE226public.packagediff = SELECT, INSERT, UPDATE, DELETE
227public.packagediff = SELECT, INSERT, UPDATE, DELETE227public.packagediff = SELECT, INSERT, UPDATE, DELETE
228public.packageset = SELECT, INSERT, UPDATE, DELETE228public.packageset = SELECT, INSERT, UPDATE, DELETE
229public.packagesetgroup = SELECT, INSERT, UPDATE, DELETE
229public.packagesetsources = SELECT, INSERT, UPDATE, DELETE230public.packagesetsources = SELECT, INSERT, UPDATE, DELETE
230public.packagesetinclusion = SELECT, INSERT, UPDATE, DELETE231public.packagesetinclusion = SELECT, INSERT, UPDATE, DELETE
231public.flatpackagesetinclusion = SELECT, INSERT, UPDATE, DELETE232public.flatpackagesetinclusion = SELECT, INSERT, UPDATE, DELETE
@@ -777,6 +778,7 @@
777public.packagecopyrequest = SELECT, INSERT, UPDATE778public.packagecopyrequest = SELECT, INSERT, UPDATE
778public.packagediff = SELECT, INSERT, UPDATE779public.packagediff = SELECT, INSERT, UPDATE
779public.packageset = SELECT780public.packageset = SELECT
781public.packagesetgroup = SELECT
780public.packagesetsources = SELECT, INSERT, UPDATE, DELETE782public.packagesetsources = SELECT, INSERT, UPDATE, DELETE
781public.packagesetinclusion = SELECT, INSERT, UPDATE, DELETE783public.packagesetinclusion = SELECT, INSERT, UPDATE, DELETE
782public.flatpackagesetinclusion = SELECT, INSERT, UPDATE, DELETE784public.flatpackagesetinclusion = SELECT, INSERT, UPDATE, DELETE
@@ -854,6 +856,7 @@
854public.teammembership = SELECT856public.teammembership = SELECT
855public.gpgkey = SELECT857public.gpgkey = SELECT
856public.packageset = SELECT858public.packageset = SELECT
859public.packagesetgroup = SELECT
857public.packagesetsources = SELECT860public.packagesetsources = SELECT
858public.packagesetinclusion = SELECT861public.packagesetinclusion = SELECT
859public.flatpackagesetinclusion = SELECT862public.flatpackagesetinclusion = SELECT
@@ -1054,6 +1057,7 @@
1054public.archive = SELECT, INSERT, UPDATE1057public.archive = SELECT, INSERT, UPDATE
1055public.archivearch = SELECT, INSERT, UPDATE1058public.archivearch = SELECT, INSERT, UPDATE
1056public.packageset = SELECT1059public.packageset = SELECT
1060public.packagesetgroup = SELECT
1057public.packagesetsources = SELECT1061public.packagesetsources = SELECT
1058public.packagesetinclusion = SELECT1062public.packagesetinclusion = SELECT
1059public.flatpackagesetinclusion = SELECT1063public.flatpackagesetinclusion = SELECT
@@ -1242,6 +1246,7 @@
1242public.personlanguage = SELECT1246public.personlanguage = SELECT
1243public.structuralsubscription = SELECT1247public.structuralsubscription = SELECT
1244public.packageset = SELECT1248public.packageset = SELECT
1249public.packagesetgroup = SELECT
1245public.packagesetsources = SELECT1250public.packagesetsources = SELECT
1246public.packagesetinclusion = SELECT1251public.packagesetinclusion = SELECT
1247public.flatpackagesetinclusion = SELECT1252public.flatpackagesetinclusion = SELECT
12481253
=== modified file 'database/schema/trusted.sql'
--- database/schema/trusted.sql 2009-08-19 15:35:13 +0000
+++ database/schema/trusted.sql 2009-10-27 23:43:13 +0000
@@ -1029,7 +1029,22 @@
1029 DECLARE1029 DECLARE
1030 parent_name text;1030 parent_name text;
1031 child_name text;1031 child_name text;
1032 parent_distroseries text;
1033 child_distroseries text;
1032 BEGIN1034 BEGIN
1035 -- Make sure that the package sets being associated here belong
1036 -- to the same distro series.
1037 IF (SELECT parent.distroseries != child.distroseries
1038 FROM packageset parent, packageset child
1039 WHERE parent.id = NEW.parent AND child.id = NEW.child)
1040 THEN
1041 SELECT name INTO parent_name FROM packageset WHERE id = NEW.parent;
1042 SELECT name INTO child_name FROM packageset WHERE id = NEW.child;
1043 SELECT ds.name INTO parent_distroseries FROM packageset ps, distroseries ds WHERE ps.id = NEW.parent AND ps.distroseries = ds.id;
1044 SELECT ds.name INTO child_distroseries FROM packageset ps, distroseries ds WHERE ps.id = NEW.child AND ps.distroseries = ds.id;
1045 RAISE EXCEPTION 'Package sets % and % belong to different distro series (to % and % respectively) and thus cannot be associated.', child_name, parent_name, child_distroseries, parent_distroseries;
1046 END IF;
1047
1033 IF EXISTS(1048 IF EXISTS(
1034 SELECT * FROM flatpackagesetinclusion1049 SELECT * FROM flatpackagesetinclusion
1035 WHERE parent = NEW.child AND child = NEW.parent LIMIT 1)1050 WHERE parent = NEW.child AND child = NEW.parent LIMIT 1)
10361051
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml 2009-10-05 13:31:09 +0000
+++ lib/lp/soyuz/configure.zcml 2009-10-27 23:43:13 +0000
@@ -856,4 +856,12 @@
856 new"/>856 new"/>
857 </securedutility>857 </securedutility>
858858
859 <!-- PackagesetGroup -->
860 <class
861 class="lp.soyuz.model.packagesetgroup.PackagesetGroup">
862 <allow
863 interface="lp.soyuz.interfaces.packagesetgroup.IPackagesetGroup"/>
864 </class>
865
866
859</configure>867</configure>
860868
=== modified file 'lib/lp/soyuz/interfaces/packageset.py'
--- lib/lp/soyuz/interfaces/packageset.py 2009-07-25 16:33:39 +0000
+++ lib/lp/soyuz/interfaces/packageset.py 2009-10-27 23:43:13 +0000
@@ -8,6 +8,7 @@
8__metaclass__ = type8__metaclass__ = type
99
10__all__ = [10__all__ = [
11 'DuplicatePackagesetName',
11 'IPackageset',12 'IPackageset',
12 'IPackagesetSet',13 'IPackagesetSet',
13 'NoSuchPackageSet',14 'NoSuchPackageSet',
@@ -26,16 +27,25 @@
26 operation_parameters, operation_returns_collection_of,27 operation_parameters, operation_returns_collection_of,
27 operation_returns_entry, webservice_error)28 operation_returns_entry, webservice_error)
28from lazr.restful.fields import Reference29from lazr.restful.fields import Reference
30from lp.registry.interfaces.distroseries import IDistroSeries
29from lp.registry.interfaces.person import IPerson31from lp.registry.interfaces.person import IPerson
30from lp.registry.interfaces.role import IHasOwner32from lp.registry.interfaces.role import IHasOwner
33from lp.soyuz.interfaces.packagesetgroup import IPackagesetGroup
3134
3235
33class NoSuchPackageSet(NameLookupFailed):36class NoSuchPackageSet(NameLookupFailed):
34 """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."""
35 webservice_error(400) #Bad request.38 # Bad request.
39 webservice_error(400)
36 _message_prefix = "No such packageset"40 _message_prefix = "No such packageset"
3741
3842
43class DuplicatePackagesetName(Exception):
44 """Raised for packagesets with the same name and distroseries."""
45 # Bad request.
46 webservice_error(400)
47
48
39class IPackagesetViewOnly(IHasOwner):49class IPackagesetViewOnly(IHasOwner):
40 """A read-only interface for package sets."""50 """A read-only interface for package sets."""
41 export_as_webservice_entry()51 export_as_webservice_entry()
@@ -48,7 +58,7 @@
4858
49 owner = exported(Reference(59 owner = exported(Reference(
50 IPerson, title=_("Person"), required=True, readonly=True,60 IPerson, title=_("Person"), required=True, readonly=True,
51 description=_("The person who owns the package set at hand.")))61 description=_("The person who owns this package set.")))
5262
53 name = exported(TextLine(63 name = exported(TextLine(
54 title=_('Valid package set name'),64 title=_('Valid package set name'),
@@ -58,6 +68,18 @@
58 title=_("Description"), required=True, readonly=True,68 title=_("Description"), required=True, readonly=True,
59 description=_("The description for the package set at hand.")))69 description=_("The description for the package set at hand.")))
6070
71 distroseries = Reference(
72 IDistroSeries, title=_("Distribution series"), required=True,
73 readonly=True,
74 description=_(
75 "The distroseries to which this package set is related."))
76
77 packagesetgroup = Reference(
78 IPackagesetGroup, title=_('Packageset group'), required=True,
79 readonly=True,
80 description=_(
81 'Used internally to link packagesets across distroseries'))
82
61 def sourcesIncluded(direct_inclusion=False):83 def sourcesIncluded(direct_inclusion=False):
62 """Get all source names associated with this package set.84 """Get all source names associated with this package set.
6385
@@ -316,15 +338,26 @@
316 title=_('Package set description'), required=True),338 title=_('Package set description'), required=True),
317 owner=Reference(339 owner=Reference(
318 IPerson, title=_("Person"), required=True, readonly=True,340 IPerson, title=_("Person"), required=True, readonly=True,
319 description=_("The person who owns the package set at hand.")))341 description=_("The person who owns this package set.")),
342 distroseries=Reference(
343 IDistroSeries, title=_("Distroseries"), required=False,
344 readonly=True, description=_(
345 "The distribution series to which the packageset "
346 "is related.")))
320 @export_factory_operation(IPackageset, [])347 @export_factory_operation(IPackageset, [])
321 def new(name, description, owner):348 def new(name, description, owner, distroseries=None, related_set=None):
322 """Create a new package set.349 """Create a new package set.
323350
324 :param name: the name of the package set to be created.351 :param name: the name of the package set to be created.
325 :param description: the description for the package set to be created.352 :param description: the description for the package set to be created.
326 :param owner: the owner of the package set to be created.353 :param owner: the owner of the package set to be created.
354 :param distroseries: the distroseries to which the new packageset
355 is related. Defaults to the current Ubuntu series.
356 :param related_set: the newly created package set is to be related to
357 `related_set` (by being placed in the same package group).
327358
359 :raises DuplicatePackagesetName: if a package set with the same `name`
360 exists in `distroseries` already.
328 :return: a newly created `IPackageset`.361 :return: a newly created `IPackageset`.
329 """362 """
330363
@@ -332,10 +365,12 @@
332 name=TextLine(title=_('Package set name'), required=True))365 name=TextLine(title=_('Package set name'), required=True))
333 @operation_returns_entry(IPackageset)366 @operation_returns_entry(IPackageset)
334 @export_read_operation()367 @export_read_operation()
335 def getByName(name):368 def getByName(name, distroseries=None):
336 """Return the single package set with the given name (if any).369 """Return the single package set with the given name (if any).
337370
338 :param name: the name of the package set sought.371 :param name: the name of the package set sought.
372 :param distroseries: the distroseries to which the new packageset
373 is related. Defaults to the current Ubuntu series.
339374
340 :return: An `IPackageset` instance or None.375 :return: An `IPackageset` instance or None.
341 """376 """
342377
=== added file 'lib/lp/soyuz/interfaces/packagesetgroup.py'
--- lib/lp/soyuz/interfaces/packagesetgroup.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/interfaces/packagesetgroup.py 2009-10-27 23:43:13 +0000
@@ -0,0 +1,41 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Packageset Group interface."""
5
6__metaclass__ = type
7
8__all__ = [
9 'IPackagesetGroup',
10 ]
11
12from zope.schema import Datetime, Int
13
14from lazr.restful.fields import Reference
15
16from canonical.launchpad import _
17from lp.registry.interfaces.person import IPerson
18from lp.registry.interfaces.role import IHasOwner
19
20
21class IPackagesetGroup(IHasOwner):
22 """A group of related package sets across distroseries'
23
24 This class is used internally to group related packagesets across
25 distroseries. For example, if in Karmic there is a 'gnome-games'
26 package set, and this package set is cloned initially for Lucid,
27 then both packagesets would refer to the same packageset-group.
28
29 Packageset-groups are not exposed at all. The date_created and
30 owner fields are present for internal use only.
31 """
32 id = Int(title=_('ID'), required=True, readonly=True)
33
34 date_created = Datetime(
35 title=_("Date Created"), required=True, readonly=True,
36 description=_("The creation date/time for this packageset group."))
37
38 owner = Reference(
39 IPerson, title=_("Person"), required=True, readonly=True,
40 description=_("The person who created this packageset group."))
41
042
=== modified file 'lib/lp/soyuz/model/packageset.py'
--- lib/lp/soyuz/model/packageset.py 2009-07-25 16:33:39 +0000
+++ lib/lp/soyuz/model/packageset.py 2009-10-27 23:43:13 +0000
@@ -6,6 +6,7 @@
66
7import pytz7import pytz
88
9from storm.exceptions import IntegrityError
9from storm.expr import In, SQL10from storm.expr import In, SQL
10from storm.locals import DateTime, Int, Reference, Storm, Unicode11from storm.locals import DateTime, Int, Reference, Storm, Unicode
1112
@@ -13,12 +14,13 @@
13from zope.interface import implements14from zope.interface import implements
1415
15from canonical.launchpad.interfaces.lpstorm import IMasterStore, IStore16from canonical.launchpad.interfaces.lpstorm import IMasterStore, IStore
17from lp.registry.interfaces.distribution import IDistributionSet
16from lp.registry.interfaces.sourcepackagename import (18from lp.registry.interfaces.sourcepackagename import (
17 ISourcePackageName, ISourcePackageNameSet)19 ISourcePackageName, ISourcePackageNameSet)
18from lp.registry.model.sourcepackagename import SourcePackageName20from lp.registry.model.sourcepackagename import SourcePackageName
19from lp.soyuz.interfaces.packageset import (21from lp.soyuz.interfaces.packageset import (
20 IPackageset, IPackagesetSet, NoSuchPackageSet)22 DuplicatePackagesetName, IPackageset, IPackagesetSet, NoSuchPackageSet)
2123from lp.soyuz.model.packagesetgroup import PackagesetGroup
2224
23def _order_result_set(result_set):25def _order_result_set(result_set):
24 """Default order for package set and source package name result sets."""26 """Default order for package set and source package name result sets."""
@@ -45,6 +47,12 @@
45 name = Unicode(name='name', allow_none=False)47 name = Unicode(name='name', allow_none=False)
46 description = Unicode(name='description', allow_none=False)48 description = Unicode(name='description', allow_none=False)
4749
50 distroseries_id = Int(name='distroseries', allow_none=False)
51 distroseries = Reference(distroseries_id, 'DistroSeries.id')
52
53 packagesetgroup_id = Int(name='packagesetgroup', allow_none=False)
54 packagesetgroup = Reference(packagesetgroup_id, 'PackagesetGroup.id')
55
48 def add(self, data):56 def add(self, data):
49 """See `IPackageset`."""57 """See `IPackageset`."""
50 handlers = (58 handlers = (
@@ -292,26 +300,66 @@
292 """See `IPackagesetSet`."""300 """See `IPackagesetSet`."""
293 implements(IPackagesetSet)301 implements(IPackagesetSet)
294302
295 def new(self, name, description, owner):303 def new(
304 self, name, description, owner, distroseries=None, related_set=None):
296 """See `IPackagesetSet`."""305 """See `IPackagesetSet`."""
297 store = IMasterStore(Packageset)306 store = IMasterStore(Packageset)
307
308 packagesetgroup = None
309 if related_set is not None:
310 # Use the packagesetgroup of the `related_set`.
311 packagesetgroup = related_set.packagesetgroup
312 else:
313 # We create the related internal PackagesetGroup for this
314 # packageset so that we can later see related package sets across
315 # distroserieses.
316 packagesetgroup = PackagesetGroup()
317 packagesetgroup.owner = owner
318 store.add(packagesetgroup)
319
320 if distroseries is None:
321 ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
322 distroseries = ubuntu.currentseries
323
298 packageset = Packageset()324 packageset = Packageset()
325 packageset.packagesetgroup = packagesetgroup
299 packageset.name = name326 packageset.name = name
300 packageset.description = description327 packageset.description = description
301 packageset.owner = owner328 packageset.owner = owner
329
330 packageset.distroseries = distroseries
331
302 store.add(packageset)332 store.add(packageset)
333
334 # We need to ensure that the cached statements are flushed so that
335 # the duplicate name constraint gets triggered here.
336 try:
337 store.flush()
338 except IntegrityError:
339 raise DuplicatePackagesetName()
340
303 return packageset341 return packageset
304342
305 def __getitem__(self, name):343 def __getitem__(self, name):
306 """See `IPackagesetSet`."""344 """See `IPackagesetSet`."""
307 return self.getByName(name)345 return self.getByName(name)
308346
309 def getByName(self, name):347 def getByName(self, name, distroseries=None):
310 """See `IPackagesetSet`."""348 """See `IPackagesetSet`."""
311 store = IStore(Packageset)349 store = IStore(Packageset)
312 if not isinstance(name, unicode):350 if not isinstance(name, unicode):
313 name = unicode(name, 'utf-8')351 name = unicode(name, 'utf-8')
314 package_set = store.find(Packageset, Packageset.name == name).one()352
353 extra_args = []
354 if distroseries is not None:
355 extra_args.append(Packageset.distroseries == distroseries)
356 else:
357 ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
358 extra_args.append(Packageset.distroseries == ubuntu.currentseries)
359
360 package_set = store.find(
361 Packageset, Packageset.name == name, *extra_args).one()
362
315 if package_set is None:363 if package_set is None:
316 raise NoSuchPackageSet(name)364 raise NoSuchPackageSet(name)
317 return package_set365 return package_set
318366
=== added file 'lib/lp/soyuz/model/packagesetgroup.py'
--- lib/lp/soyuz/model/packagesetgroup.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/model/packagesetgroup.py 2009-10-27 23:43:13 +0000
@@ -0,0 +1,30 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4__metaclass__ = type
5
6__all__ = [
7 'PackagesetGroup',
8 ]
9
10import pytz
11
12from storm.locals import DateTime, Int, Reference, Storm
13
14from zope.interface import implements
15
16from lp.soyuz.interfaces.packagesetgroup import IPackagesetGroup
17
18
19class PackagesetGroup(Storm):
20 """See `IPackageset`."""
21 implements(IPackagesetGroup)
22 __storm_table__ = 'PackagesetGroup'
23 id = Int(primary=True)
24
25 date_created = DateTime(
26 name='date_created', allow_none=False, tzinfo=pytz.UTC)
27
28 owner_id = Int(name='owner', allow_none=False)
29 owner = Reference(owner_id, 'Person.id')
30
031
=== added file 'lib/lp/soyuz/tests/test_packageset.py'
--- lib/lp/soyuz/tests/test_packageset.py 1970-01-01 00:00:00 +0000
+++ lib/lp/soyuz/tests/test_packageset.py 2009-10-27 23:43:13 +0000
@@ -0,0 +1,121 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test Packageset features."""
5
6from zope.component import getUtility
7
8from canonical.testing import LaunchpadZopelessLayer
9
10from lp.testing import TestCaseWithFactory
11from lp.registry.interfaces.distribution import IDistributionSet
12from lp.registry.interfaces.distroseries import DistroSeriesStatus
13from lp.soyuz.interfaces.packageset import (
14 DuplicatePackagesetName, IPackagesetSet)
15
16
17class TestPackagesetSetNew(TestCaseWithFactory):
18
19 layer = LaunchpadZopelessLayer
20
21 def setUp(self):
22 """Setup a distribution with multiple distroseries."""
23 super(TestPackagesetSetNew, self).setUp()
24 self.distribution = getUtility(IDistributionSet).getByName(
25 'ubuntu')
26 self.distroseries_current = self.distribution.currentseries
27 self.distroseries_experimental = self.factory.makeDistroRelease(
28 distribution = self.distribution, name="experimental",
29 status=DistroSeriesStatus.EXPERIMENTAL)
30
31 self.person1 = self.factory.makePerson(
32 name='hacker', displayname=u'Happy Hacker')
33
34 self.packageset_set = getUtility(IPackagesetSet)
35
36 def test_new_defaults_to_current_distroseries(self):
37 # If the distroseries is not provided, the current development
38 # distroseries will be assumed.
39 packageset = self.packageset_set.new(
40 u'kernel', u'Contains all OS kernel packages', self.person1)
41
42 self.failUnlessEqual(
43 self.distroseries_current, packageset.distroseries)
44
45 def test_new_with_specified_distroseries(self):
46 # A distroseries can be provided when creating a package set.
47 packageset = self.packageset_set.new(
48 u'kernel', u'Contains all OS kernel packages', self.person1,
49 distroseries=self.distroseries_experimental)
50
51 self.failUnlessEqual(
52 self.distroseries_experimental, packageset.distroseries)
53
54 def test_new_creates_new_packageset_group(self):
55 # Creating a new packageset should also create a new packageset
56 # group with the same owner.
57 packageset = self.packageset_set.new(
58 u'kernel', u'Contains all OS kernel packages', self.person1,
59 distroseries=self.distroseries_experimental)
60
61 self.failUnlessEqual(
62 self.person1, packageset.packagesetgroup.owner)
63
64 def test_new_duplicate_name_for_same_distroseries(self):
65 # Creating a packageset with a duplicate name for the
66 # given distroseries will fail.
67 packageset = self.packageset_set.new(
68 u'kernel', u'Contains all OS kernel packages', self.person1,
69 distroseries=self.distroseries_experimental)
70
71 self.failUnlessRaises(
72 DuplicatePackagesetName, self.packageset_set.new,
73 u'kernel', u'A packageset with a duplicate name', self.person1,
74 distroseries=self.distroseries_experimental)
75
76 def test_new_duplicate_name_for_different_distroseries(self):
77 # Creating a packageset with a duplicate name but for a different
78 # series is no problem.
79 packageset = self.packageset_set.new(
80 u'kernel', u'Contains all OS kernel packages', self.person1)
81
82 packageset2 = self.packageset_set.new(
83 u'kernel', u'A packageset with a duplicate name', self.person1,
84 distroseries=self.distroseries_experimental)
85 self.assertEqual(packageset.name, packageset2.name)
86
87 def test_new_related_packageset(self):
88 # Creating a new package set while specifying a `related_set` should
89 # have the effect that the former ends up in the same group as the
90 # latter.
91 pset1 = self.packageset_set.new(
92 u'kernel', u'Contains all OS kernel packages', self.person1)
93
94 pset2 = self.packageset_set.new(
95 u'kernel', u'A related package set.', self.person1,
96 distroseries=self.distroseries_experimental, related_set=pset1)
97 self.assertEqual(pset1.packagesetgroup, pset2.packagesetgroup)
98
99 def test_get_by_name_in_current_distroseries(self):
100 # IPackagesetSet.getByName() will return the package set in the
101 # current distroseries if the optional `distroseries` parameter is
102 # omitted.
103 pset1 = self.packageset_set.new(
104 u'kernel', u'Contains all OS kernel packages', self.person1)
105 pset2 = self.packageset_set.new(
106 u'kernel', u'A related package set.', self.person1,
107 distroseries=self.distroseries_experimental, related_set=pset1)
108 pset_found = getUtility(IPackagesetSet).getByName('kernel')
109 self.assertEqual(pset1, pset_found)
110
111 def test_get_by_name_in_specified_distroseries(self):
112 # IPackagesetSet.getByName() will return the package set in the
113 # specified distroseries.
114 pset1 = self.packageset_set.new(
115 u'kernel', u'Contains all OS kernel packages', self.person1)
116 pset2 = self.packageset_set.new(
117 u'kernel', u'A related package set.', self.person1,
118 distroseries=self.distroseries_experimental, related_set=pset1)
119 pset_found = getUtility(IPackagesetSet).getByName(
120 'kernel', distroseries=self.distroseries_experimental)
121 self.assertEqual(pset2, pset_found)

Subscribers

People subscribed via source and target branches

to status/vote changes: