Merge lp:~cjohnston/launchpad/ppa-rtm-fixes into lp:launchpad
- ppa-rtm-fixes
- Merge into devel
Proposed by
Chris Johnston
Status: | Rejected |
---|---|
Rejected by: | William Grant |
Proposed branch: | lp:~cjohnston/launchpad/ppa-rtm-fixes |
Merge into: | lp:launchpad |
Diff against target: |
504 lines (+130/-57) 9 files modified
lib/lp/code/javascript/tests/test_requestbuild_overlay.html (+1/-1) lib/lp/soyuz/browser/archive.py (+2/-3) lib/lp/soyuz/browser/tests/archive-views.txt (+8/-8) lib/lp/soyuz/doc/vocabularies.txt (+13/-13) lib/lp/soyuz/model/archive.py (+7/-1) lib/lp/soyuz/stories/ppa/xx-edit-dependencies.txt (+47/-10) lib/lp/soyuz/tests/test_archive.py (+25/-1) lib/lp/soyuz/tests/test_vocabularies.py (+1/-1) lib/lp/soyuz/vocabularies.py (+26/-19) |
To merge this branch: | bzr merge lp:~cjohnston/launchpad/ppa-rtm-fixes |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
William Grant (wgrant) : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/code/javascript/tests/test_requestbuild_overlay.html' | |||
2 | --- lib/lp/code/javascript/tests/test_requestbuild_overlay.html 2012-10-26 09:54:28 +0000 | |||
3 | +++ lib/lp/code/javascript/tests/test_requestbuild_overlay.html 2014-08-29 01:29:58 +0000 | |||
4 | @@ -73,7 +73,7 @@ | |||
5 | 73 | <script type="text/x-template" id="requestbuilds-form-template"> | 73 | <script type="text/x-template" id="requestbuilds-form-template"> |
6 | 74 | <div class="form" id="launchpad-form-widgets"> | 74 | <div class="form" id="launchpad-form-widgets"> |
7 | 75 | <select id="field.archive" name="field.archive" size="1" > | 75 | <select id="field.archive" name="field.archive" size="1" > |
9 | 76 | <option selected="selected" value="mark/ppa"> | 76 | <option selected="selected" value="~mark/ubuntu/ppa"> |
10 | 77 | PPA for Mark Shuttleworth</option> | 77 | PPA for Mark Shuttleworth</option> |
11 | 78 | </select> | 78 | </select> |
12 | 79 | <input name="field.archive-empty-marker" type="hidden" value="1" /> | 79 | <input name="field.archive-empty-marker" type="hidden" value="1" /> |
13 | 80 | 80 | ||
14 | === modified file 'lib/lp/soyuz/browser/archive.py' | |||
15 | --- lib/lp/soyuz/browser/archive.py 2014-08-01 08:47:00 +0000 | |||
16 | +++ lib/lp/soyuz/browser/archive.py 2014-08-29 01:29:58 +0000 | |||
17 | @@ -1391,6 +1391,7 @@ | |||
18 | 1391 | for archive in archives: | 1391 | for archive in archives: |
19 | 1392 | label = '%s [%s]' % (archive.displayname, archive.reference) | 1392 | label = '%s [%s]' % (archive.displayname, archive.reference) |
20 | 1393 | terms.append(SimpleTerm(archive, archive.reference, label)) | 1393 | terms.append(SimpleTerm(archive, archive.reference, label)) |
21 | 1394 | terms.sort(key=lambda x: x.value.reference) | ||
22 | 1394 | return SimpleVocabulary(terms) | 1395 | return SimpleVocabulary(terms) |
23 | 1395 | 1396 | ||
24 | 1396 | 1397 | ||
25 | @@ -1627,10 +1628,8 @@ | |||
26 | 1627 | canonical_url(dependency), archive_dependency.title) | 1628 | canonical_url(dependency), archive_dependency.title) |
27 | 1628 | else: | 1629 | else: |
28 | 1629 | dependency_label = archive_dependency.title | 1630 | dependency_label = archive_dependency.title |
29 | 1630 | dependency_token = '%s/%s' % ( | ||
30 | 1631 | dependency.owner.name, dependency.name) | ||
31 | 1632 | term = SimpleTerm( | 1631 | term = SimpleTerm( |
33 | 1633 | dependency, dependency_token, dependency_label) | 1632 | dependency, dependency.reference, dependency_label) |
34 | 1634 | terms.append(term) | 1633 | terms.append(term) |
35 | 1635 | return form.Fields( | 1634 | return form.Fields( |
36 | 1636 | List(__name__='selected_dependencies', | 1635 | List(__name__='selected_dependencies', |
37 | 1637 | 1636 | ||
38 | === modified file 'lib/lp/soyuz/browser/tests/archive-views.txt' | |||
39 | --- lib/lp/soyuz/browser/tests/archive-views.txt 2014-07-24 09:37:03 +0000 | |||
40 | +++ lib/lp/soyuz/browser/tests/archive-views.txt 2014-08-29 01:29:58 +0000 | |||
41 | @@ -716,7 +716,7 @@ | |||
42 | 716 | 716 | ||
43 | 717 | Let's emulate a dependency addition. Note that the form contains, a | 717 | Let's emulate a dependency addition. Note that the form contains, a |
44 | 718 | empty 'selected_dependencies' (as it was rendered in the empty | 718 | empty 'selected_dependencies' (as it was rendered in the empty |
46 | 719 | request) and 'dependency_candidate' contains a valid PPA owner name. | 719 | request) and 'dependency_candidate' contains a valid PPA name. |
47 | 720 | Validation checks are documented in | 720 | Validation checks are documented in |
48 | 721 | pagetests/ppa/xx-edit-dependencies.txt. | 721 | pagetests/ppa/xx-edit-dependencies.txt. |
49 | 722 | 722 | ||
50 | @@ -724,7 +724,7 @@ | |||
51 | 724 | ... cprov.archive, name="+edit-dependencies", | 724 | ... cprov.archive, name="+edit-dependencies", |
52 | 725 | ... form={ | 725 | ... form={ |
53 | 726 | ... 'field.selected_dependencies': [], | 726 | ... 'field.selected_dependencies': [], |
55 | 727 | ... 'field.dependency_candidate': 'mark/ppa', | 727 | ... 'field.dependency_candidate': '~mark/ubuntu/ppa', |
56 | 728 | ... 'field.primary_dependencies': 'UPDATES', | 728 | ... 'field.primary_dependencies': 'UPDATES', |
57 | 729 | ... 'field.primary_components': 'ALL_COMPONENTS', | 729 | ... 'field.primary_components': 'ALL_COMPONENTS', |
58 | 730 | ... 'field.actions.save': 'Save', | 730 | ... 'field.actions.save': 'Save', |
59 | @@ -762,7 +762,7 @@ | |||
60 | 762 | PPA for Mark Shuttleworth | 762 | PPA for Mark Shuttleworth |
61 | 763 | 763 | ||
62 | 764 | >>> print dependency.token | 764 | >>> print dependency.token |
64 | 765 | mark/ppa | 765 | ~mark/ubuntu/ppa |
65 | 766 | 766 | ||
66 | 767 | >>> print dependency.title.escapedtext | 767 | >>> print dependency.title.escapedtext |
67 | 768 | <a href="http://launchpad.dev/~mark/+archive/ubuntu/ppa">PPA for Mark | 768 | <a href="http://launchpad.dev/~mark/+archive/ubuntu/ppa">PPA for Mark |
68 | @@ -794,7 +794,7 @@ | |||
69 | 794 | PPA for Mark Shuttleworth | 794 | PPA for Mark Shuttleworth |
70 | 795 | 795 | ||
71 | 796 | >>> print dependency.token | 796 | >>> print dependency.token |
73 | 797 | mark/ppa | 797 | ~mark/ubuntu/ppa |
74 | 798 | 798 | ||
75 | 799 | >>> print dependency.title | 799 | >>> print dependency.title |
76 | 800 | PPA for Mark Shuttleworth | 800 | PPA for Mark Shuttleworth |
77 | @@ -805,7 +805,7 @@ | |||
78 | 805 | >>> view = create_initialized_view( | 805 | >>> view = create_initialized_view( |
79 | 806 | ... cprov.archive, name="+edit-dependencies", | 806 | ... cprov.archive, name="+edit-dependencies", |
80 | 807 | ... form={ | 807 | ... form={ |
82 | 808 | ... 'field.selected_dependencies': ['mark/ppa'], | 808 | ... 'field.selected_dependencies': ['~mark/ubuntu/ppa'], |
83 | 809 | ... 'field.dependency_candidate': '', | 809 | ... 'field.dependency_candidate': '', |
84 | 810 | ... 'field.primary_dependencies': 'UPDATES', | 810 | ... 'field.primary_dependencies': 'UPDATES', |
85 | 811 | ... 'field.primary_components': 'ALL_COMPONENTS', | 811 | ... 'field.primary_components': 'ALL_COMPONENTS', |
86 | @@ -849,7 +849,7 @@ | |||
87 | 849 | >>> view.widgets.get('primary_dependencies')._getCurrentValue() | 849 | >>> view.widgets.get('primary_dependencies')._getCurrentValue() |
88 | 850 | <DBItem PackagePublishingPocket.UPDATES, (20) Updates> | 850 | <DBItem PackagePublishingPocket.UPDATES, (20) Updates> |
89 | 851 | 851 | ||
91 | 852 | A similar widget is used for the primary archive component overrides , | 852 | A similar widget is used for the primary archive component overrides, |
92 | 853 | which contains two pre-defined options. By default all PPAs use all | 853 | which contains two pre-defined options. By default all PPAs use all |
93 | 854 | ubuntu components available to satisfy build dependencies, i.e. the | 854 | ubuntu components available to satisfy build dependencies, i.e. the |
94 | 855 | 'multiverse' component. | 855 | 'multiverse' component. |
95 | @@ -965,7 +965,7 @@ | |||
96 | 965 | <DBItem PackagePublishingPocket.UPDATES, (20) Updates> | 965 | <DBItem PackagePublishingPocket.UPDATES, (20) Updates> |
97 | 966 | 966 | ||
98 | 967 | Dependencies on private PPAs can be only set if the user performing | 967 | Dependencies on private PPAs can be only set if the user performing |
100 | 968 | the action also have permission to view the private PPA and if the | 968 | the action also has permission to view the private PPA and if the |
101 | 969 | context PPA is also private. | 969 | context PPA is also private. |
102 | 970 | 970 | ||
103 | 971 | The latter guarantee that the P3A buildd_secret won't get exposed in | 971 | The latter guarantee that the P3A buildd_secret won't get exposed in |
104 | @@ -988,7 +988,7 @@ | |||
105 | 988 | 988 | ||
106 | 989 | >>> add_private_form = { | 989 | >>> add_private_form = { |
107 | 990 | ... 'field.selected_dependencies': [], | 990 | ... 'field.selected_dependencies': [], |
109 | 991 | ... 'field.dependency_candidate': 'pirulito-team/ppa', | 991 | ... 'field.dependency_candidate': '~pirulito-team/ubuntu/ppa', |
110 | 992 | ... 'field.primary_dependencies': 'UPDATES', | 992 | ... 'field.primary_dependencies': 'UPDATES', |
111 | 993 | ... 'field.primary_components': 'FOLLOW_PRIMARY', | 993 | ... 'field.primary_components': 'FOLLOW_PRIMARY', |
112 | 994 | ... 'field.actions.save': 'Save', | 994 | ... 'field.actions.save': 'Save', |
113 | 995 | 995 | ||
114 | === modified file 'lib/lp/soyuz/doc/vocabularies.txt' | |||
115 | --- lib/lp/soyuz/doc/vocabularies.txt 2013-07-12 06:14:22 +0000 | |||
116 | +++ lib/lp/soyuz/doc/vocabularies.txt 2014-08-29 01:29:58 +0000 | |||
117 | @@ -189,13 +189,13 @@ | |||
118 | 189 | * value: the IArchive object; | 189 | * value: the IArchive object; |
119 | 190 | * title: the first line of the PPA description text. | 190 | * title: the first line of the PPA description text. |
120 | 191 | 191 | ||
122 | 192 | >>> cprov_term = vocabulary.getTermByToken('cprov/ppa') | 192 | >>> cprov_term = vocabulary.getTermByToken('~cprov/ubuntu/ppa') |
123 | 193 | 193 | ||
124 | 194 | >>> print cprov_term.token | 194 | >>> print cprov_term.token |
126 | 195 | cprov/ppa | 195 | ~cprov/ubuntu/ppa |
127 | 196 | 196 | ||
128 | 197 | >>> print cprov_term.value | 197 | >>> print cprov_term.value |
130 | 198 | <Archive ...> | 198 | <... lp.soyuz.model.archive.Archive instance ...> |
131 | 199 | 199 | ||
132 | 200 | >>> print cprov_term.title | 200 | >>> print cprov_term.title |
133 | 201 | packages to help my friends. | 201 | packages to help my friends. |
134 | @@ -216,15 +216,15 @@ | |||
135 | 216 | 216 | ||
136 | 217 | >>> cprov_search = vocabulary.search(u'cprov') | 217 | >>> cprov_search = vocabulary.search(u'cprov') |
137 | 218 | >>> print_search_results(cprov_search) | 218 | >>> print_search_results(cprov_search) |
139 | 219 | cprov/ppa: packages to help my friends. | 219 | ~cprov/ubuntu/ppa: packages to help my friends. |
140 | 220 | 220 | ||
141 | 221 | >>> celso_search = vocabulary.search(u'celso') | 221 | >>> celso_search = vocabulary.search(u'celso') |
142 | 222 | >>> print_search_results(celso_search) | 222 | >>> print_search_results(celso_search) |
144 | 223 | cprov/ppa: packages to help my friends. | 223 | ~cprov/ubuntu/ppa: packages to help my friends. |
145 | 224 | 224 | ||
146 | 225 | >>> friends_search = vocabulary.search(u'friends') | 225 | >>> friends_search = vocabulary.search(u'friends') |
147 | 226 | >>> print_search_results(friends_search) | 226 | >>> print_search_results(friends_search) |
149 | 227 | cprov/ppa: packages to help my friends. | 227 | ~cprov/ubuntu/ppa: packages to help my friends. |
150 | 228 | 228 | ||
151 | 229 | We will create an additional PPA for Celso named 'testing' | 229 | We will create an additional PPA for Celso named 'testing' |
152 | 230 | 230 | ||
153 | @@ -242,15 +242,15 @@ | |||
154 | 242 | 242 | ||
155 | 243 | >>> cprov_search = vocabulary.search(u'cprov') | 243 | >>> cprov_search = vocabulary.search(u'cprov') |
156 | 244 | >>> print_search_results(cprov_search) | 244 | >>> print_search_results(cprov_search) |
159 | 245 | cprov/ppa: packages to help my friends. | 245 | ~cprov/ubuntu/ppa: packages to help my friends. |
160 | 246 | cprov/testing: testing packages. | 246 | ~cprov/ubuntu/testing: testing packages. |
161 | 247 | 247 | ||
162 | 248 | The vocabulary search also supports specific named PPA lookups | 248 | The vocabulary search also supports specific named PPA lookups |
163 | 249 | follwing the same combined syntax used to build unique tokens. | 249 | follwing the same combined syntax used to build unique tokens. |
164 | 250 | 250 | ||
166 | 251 | >>> named_search = vocabulary.search(u'cprov/testing') | 251 | >>> named_search = vocabulary.search(u'~cprov/ubuntu/testing') |
167 | 252 | >>> print_search_results(named_search) | 252 | >>> print_search_results(named_search) |
169 | 253 | cprov/testing: testing packages. | 253 | ~cprov/ubuntu/testing: testing packages. |
170 | 254 | 254 | ||
171 | 255 | As mentioned the PPA vocabulary term title only contains the first | 255 | As mentioned the PPA vocabulary term title only contains the first |
172 | 256 | line of the PPA description. | 256 | line of the PPA description. |
173 | @@ -258,14 +258,14 @@ | |||
174 | 258 | >>> cprov.archive.description = "Single line." | 258 | >>> cprov.archive.description = "Single line." |
175 | 259 | >>> flush_database_updates() | 259 | >>> flush_database_updates() |
176 | 260 | 260 | ||
178 | 261 | >>> cprov_term = vocabulary.getTermByToken('cprov/ppa') | 261 | >>> cprov_term = vocabulary.getTermByToken('~cprov/ubuntu/ppa') |
179 | 262 | >>> print cprov_term.title | 262 | >>> print cprov_term.title |
180 | 263 | Single line. | 263 | Single line. |
181 | 264 | 264 | ||
182 | 265 | >>> cprov.archive.description = "First line\nSecond line." | 265 | >>> cprov.archive.description = "First line\nSecond line." |
183 | 266 | >>> flush_database_updates() | 266 | >>> flush_database_updates() |
184 | 267 | 267 | ||
186 | 268 | >>> cprov_term = vocabulary.getTermByToken('cprov/ppa') | 268 | >>> cprov_term = vocabulary.getTermByToken('~cprov/ubuntu/ppa') |
187 | 269 | >>> print cprov_term.title | 269 | >>> print cprov_term.title |
188 | 270 | First line | 270 | First line |
189 | 271 | 271 | ||
190 | @@ -274,7 +274,7 @@ | |||
191 | 274 | >>> cprov.archive.description = None | 274 | >>> cprov.archive.description = None |
192 | 275 | >>> flush_database_updates() | 275 | >>> flush_database_updates() |
193 | 276 | 276 | ||
195 | 277 | >>> cprov_term = vocabulary.getTermByToken('cprov/ppa') | 277 | >>> cprov_term = vocabulary.getTermByToken('~cprov/ubuntu/ppa') |
196 | 278 | >>> print cprov_term.title | 278 | >>> print cprov_term.title |
197 | 279 | No description available | 279 | No description available |
198 | 280 | 280 | ||
199 | 281 | 281 | ||
200 | === modified file 'lib/lp/soyuz/model/archive.py' | |||
201 | --- lib/lp/soyuz/model/archive.py 2014-08-14 10:08:28 +0000 | |||
202 | +++ lib/lp/soyuz/model/archive.py 2014-08-29 01:29:58 +0000 | |||
203 | @@ -1,4 +1,4 @@ | |||
205 | 1 | # Copyright 2009-2013 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2014 Canonical Ltd. This software is licensed under the |
206 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
207 | 3 | 3 | ||
208 | 4 | """Database class for table Archive.""" | 4 | """Database class for table Archive.""" |
209 | @@ -1076,7 +1076,13 @@ | |||
210 | 1076 | raise ArchiveDependencyError( | 1076 | raise ArchiveDependencyError( |
211 | 1077 | "Non-primary archives only support the '%s' component." % | 1077 | "Non-primary archives only support the '%s' component." % |
212 | 1078 | dependency.default_component.name) | 1078 | dependency.default_component.name) |
213 | 1079 | if dependency.distribution != self.distribution: | ||
214 | 1080 | raise ArchiveDependencyError( | ||
215 | 1081 | "This dependency uses a different archive.") | ||
216 | 1079 | 1082 | ||
217 | 1083 | if not dependency.enabled: | ||
218 | 1084 | raise ArchiveDependencyError( | ||
219 | 1085 | "This dependency is not active.") | ||
220 | 1080 | return ArchiveDependency( | 1086 | return ArchiveDependency( |
221 | 1081 | archive=self, dependency=dependency, pocket=pocket, | 1087 | archive=self, dependency=dependency, pocket=pocket, |
222 | 1082 | component=component) | 1088 | component=component) |
223 | 1083 | 1089 | ||
224 | === modified file 'lib/lp/soyuz/stories/ppa/xx-edit-dependencies.txt' | |||
225 | --- lib/lp/soyuz/stories/ppa/xx-edit-dependencies.txt 2014-07-24 09:37:03 +0000 | |||
226 | +++ lib/lp/soyuz/stories/ppa/xx-edit-dependencies.txt 2014-08-29 01:29:58 +0000 | |||
227 | @@ -112,7 +112,7 @@ | |||
228 | 112 | is rendered on top of the page and the list of dependencies available | 112 | is rendered on top of the page and the list of dependencies available |
229 | 113 | for removal is updated. | 113 | for removal is updated. |
230 | 114 | 114 | ||
232 | 115 | >>> admin_browser.getControl("Add PPA dependency").value = 'mark/ppa' | 115 | >>> admin_browser.getControl("Add PPA dependency").value = '~mark/ubuntu/ppa' |
233 | 116 | >>> admin_browser.getControl("Save").click() | 116 | >>> admin_browser.getControl("Save").click() |
234 | 117 | >>> print_feedback_messages(admin_browser.contents) | 117 | >>> print_feedback_messages(admin_browser.contents) |
235 | 118 | Dependency added: PPA for Mark Shuttleworth | 118 | Dependency added: PPA for Mark Shuttleworth |
236 | @@ -123,7 +123,7 @@ | |||
237 | 123 | 123 | ||
238 | 124 | Trying to add a dependency that is already recorded results in a error. | 124 | Trying to add a dependency that is already recorded results in a error. |
239 | 125 | 125 | ||
241 | 126 | >>> admin_browser.getControl("Add PPA dependency").value = 'mark/ppa' | 126 | >>> admin_browser.getControl("Add PPA dependency").value = '~mark/ubuntu/ppa' |
242 | 127 | >>> admin_browser.getControl("Save").click() | 127 | >>> admin_browser.getControl("Save").click() |
243 | 128 | >>> print_feedback_messages(admin_browser.contents) | 128 | >>> print_feedback_messages(admin_browser.contents) |
244 | 129 | There is 1 error. | 129 | There is 1 error. |
245 | @@ -132,7 +132,7 @@ | |||
246 | 132 | Trying to add a dependency for the context PPA itself also results in | 132 | Trying to add a dependency for the context PPA itself also results in |
247 | 133 | a error. | 133 | a error. |
248 | 134 | 134 | ||
250 | 135 | >>> admin_browser.getControl("Add PPA dependency").value = 'cprov/ppa' | 135 | >>> admin_browser.getControl("Add PPA dependency").value = '~cprov/ubuntu/ppa' |
251 | 136 | >>> admin_browser.getControl("Save").click() | 136 | >>> admin_browser.getControl("Save").click() |
252 | 137 | >>> print_feedback_messages(admin_browser.contents) | 137 | >>> print_feedback_messages(admin_browser.contents) |
253 | 138 | There is 1 error. | 138 | There is 1 error. |
254 | @@ -140,7 +140,7 @@ | |||
255 | 140 | 140 | ||
256 | 141 | If it's a new dependency everything is fine. | 141 | If it's a new dependency everything is fine. |
257 | 142 | 142 | ||
259 | 143 | >>> admin_browser.getControl("Add PPA dependency").value = 'no-priv/ppa' | 143 | >>> admin_browser.getControl("Add PPA dependency").value = '~no-priv/ubuntu/ppa' |
260 | 144 | >>> admin_browser.getControl("Save").click() | 144 | >>> admin_browser.getControl("Save").click() |
261 | 145 | >>> print_feedback_messages(admin_browser.contents) | 145 | >>> print_feedback_messages(admin_browser.contents) |
262 | 146 | Dependency added: PPA for No Privileges Person | 146 | Dependency added: PPA for No Privileges Person |
263 | @@ -234,7 +234,7 @@ | |||
264 | 234 | 234 | ||
265 | 235 | >>> admin_browser.getControl( | 235 | >>> admin_browser.getControl( |
266 | 236 | ... name="field.selected_dependencies").value = [ | 236 | ... name="field.selected_dependencies").value = [ |
268 | 237 | ... 'mark/ppa', 'no-priv/ppa'] | 237 | ... '~mark/ubuntu/ppa', '~no-priv/ubuntu/ppa'] |
269 | 238 | >>> admin_browser.getControl("Save").click() | 238 | >>> admin_browser.getControl("Save").click() |
270 | 239 | >>> print_feedback_messages(admin_browser.contents) | 239 | >>> print_feedback_messages(admin_browser.contents) |
271 | 240 | Dependencies removed: | 240 | Dependencies removed: |
272 | @@ -258,6 +258,43 @@ | |||
273 | 258 | ... user_browser.contents, 'archive-dependencies') | 258 | ... user_browser.contents, 'archive-dependencies') |
274 | 259 | None | 259 | None |
275 | 260 | 260 | ||
276 | 261 | We should also make sure that a user is unable to add a disabled PPA as a | ||
277 | 262 | dependency. | ||
278 | 263 | |||
279 | 264 | # Disable Mark's PPA. | ||
280 | 265 | >>> login('foo.bar@canonical.com') | ||
281 | 266 | >>> from zope.component import getUtility | ||
282 | 267 | >>> from lp.registry.interfaces.person import IPersonSet | ||
283 | 268 | >>> mark = getUtility(IPersonSet).getByName('mark') | ||
284 | 269 | >>> mark.archive.disable() | ||
285 | 270 | >>> logout() | ||
286 | 271 | |||
287 | 272 | # Attempt to add Mark's PPA | ||
288 | 273 | >>> admin_browser.getControl("Add PPA dependency").value = '~mark/ubuntu/ppa' | ||
289 | 274 | >>> admin_browser.getControl("Save").click() | ||
290 | 275 | >>> print_feedback_messages(admin_browser.contents) | ||
291 | 276 | There is 1 error. | ||
292 | 277 | Invalid value | ||
293 | 278 | |||
294 | 279 | # When the page is reloaded, there shouldn't be any dependencies. | ||
295 | 280 | >>> admin_browser.reload() | ||
296 | 281 | >>> print_ppa_dependencies(admin_browser.contents) | ||
297 | 282 | No dependencies recorded for this PPA yet. | ||
298 | 283 | |||
299 | 284 | Re-enable Mark's PPA for subsequent tests. | ||
300 | 285 | |||
301 | 286 | >>> login('foo.bar@canonical.com') | ||
302 | 287 | >>> mark.archive.enable() | ||
303 | 288 | >>> logout() | ||
304 | 289 | |||
305 | 290 | Clear the page. | ||
306 | 291 | |||
307 | 292 | >>> admin_browser.getControl("Add PPA dependency").value = '' | ||
308 | 293 | >>> admin_browser.getControl("Save").click() | ||
309 | 294 | >>> admin_browser.reload() | ||
310 | 295 | >>> print_ppa_dependencies(admin_browser.contents) | ||
311 | 296 | No dependencies recorded for this PPA yet. | ||
312 | 297 | |||
313 | 261 | == Primary dependencies == | 298 | == Primary dependencies == |
314 | 262 | 299 | ||
315 | 263 | A user can modify how a PPA depends on its corresponding | 300 | A user can modify how a PPA depends on its corresponding |
316 | @@ -420,7 +457,7 @@ | |||
317 | 420 | 457 | ||
318 | 421 | First we will create a PPA dependency for No privileged' PPA. | 458 | First we will create a PPA dependency for No privileged' PPA. |
319 | 422 | 459 | ||
321 | 423 | >>> admin_browser.getControl("Add PPA dependency").value = 'no-priv/ppa' | 460 | >>> admin_browser.getControl("Add PPA dependency").value = '~no-priv/ubuntu/ppa' |
322 | 424 | >>> admin_browser.getControl("Save").click() | 461 | >>> admin_browser.getControl("Save").click() |
323 | 425 | >>> print_feedback_messages(admin_browser.contents) | 462 | >>> print_feedback_messages(admin_browser.contents) |
324 | 426 | Dependency added: PPA for No Privileges Person | 463 | Dependency added: PPA for No Privileges Person |
325 | @@ -450,12 +487,12 @@ | |||
326 | 450 | RELEASE. | 487 | RELEASE. |
327 | 451 | 488 | ||
328 | 452 | >>> admin_browser.getControl( | 489 | >>> admin_browser.getControl( |
330 | 453 | ... name="field.selected_dependencies").value = ['no-priv/ppa'] | 490 | ... name="field.selected_dependencies").value = ['~no-priv/ubuntu/ppa'] |
331 | 454 | 491 | ||
332 | 455 | >>> admin_browser.getControl( | 492 | >>> admin_browser.getControl( |
333 | 456 | ... "Use all Ubuntu components available.").selected = True | 493 | ... "Use all Ubuntu components available.").selected = True |
334 | 457 | 494 | ||
336 | 458 | >>> admin_browser.getControl("Add PPA dependency").value = 'mark/ppa' | 495 | >>> admin_browser.getControl("Add PPA dependency").value = '~mark/ubuntu/ppa' |
337 | 459 | 496 | ||
338 | 460 | >>> admin_browser.getControl( | 497 | >>> admin_browser.getControl( |
339 | 461 | ... "Basic (only released packages).").selected = True | 498 | ... "Basic (only released packages).").selected = True |
340 | @@ -513,9 +550,9 @@ | |||
341 | 513 | 550 | ||
342 | 514 | >>> admin_browser.getLink('Edit PPA dependencies').click() | 551 | >>> admin_browser.getLink('Edit PPA dependencies').click() |
343 | 515 | 552 | ||
345 | 516 | >>> admin_browser.getControl("Add PPA dependency").value = 'no-priv/ppa' | 553 | >>> admin_browser.getControl("Add PPA dependency").value = '~no-priv/ubuntu/ppa' |
346 | 517 | >>> admin_browser.getControl( | 554 | >>> admin_browser.getControl( |
348 | 518 | ... name="field.selected_dependencies").value = ['mark/ppa'] | 555 | ... name="field.selected_dependencies").value = ['~mark/ubuntu/ppa'] |
349 | 519 | >>> admin_browser.getControl( | 556 | >>> admin_browser.getControl( |
350 | 520 | ... "Default (security dependencies and recommended updates)." | 557 | ... "Default (security dependencies and recommended updates)." |
351 | 521 | ... ).selected = True | 558 | ... ).selected = True |
352 | 522 | 559 | ||
353 | === modified file 'lib/lp/soyuz/tests/test_archive.py' | |||
354 | --- lib/lp/soyuz/tests/test_archive.py 2014-08-07 07:53:27 +0000 | |||
355 | +++ lib/lp/soyuz/tests/test_archive.py 2014-08-29 01:29:58 +0000 | |||
356 | @@ -1,4 +1,4 @@ | |||
358 | 1 | # Copyright 2009-2013 Canonical Ltd. This software is licensed under the | 1 | # Copyright 2009-2014 Canonical Ltd. This software is licensed under the |
359 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). |
360 | 3 | 3 | ||
361 | 4 | """Test Archive features.""" | 4 | """Test Archive features.""" |
362 | @@ -1415,6 +1415,30 @@ | |||
363 | 1415 | PackagePublishingPocket.RELEASE) | 1415 | PackagePublishingPocket.RELEASE) |
364 | 1416 | self.assertContentEqual(archive.dependencies, [archive_dependency]) | 1416 | self.assertContentEqual(archive.dependencies, [archive_dependency]) |
365 | 1417 | 1417 | ||
366 | 1418 | def test_dependency_has_different_distribution(self): | ||
367 | 1419 | # A public archive may not depend on a private archive. | ||
368 | 1420 | archive = self.factory.makeArchive() | ||
369 | 1421 | distro = self.factory.makeDistribution() | ||
370 | 1422 | dependency = self.factory.makeArchive( | ||
371 | 1423 | distribution=distro, owner=archive.owner) | ||
372 | 1424 | with person_logged_in(archive.owner): | ||
373 | 1425 | with ExpectedException( | ||
374 | 1426 | ArchiveDependencyError, | ||
375 | 1427 | "This dependency uses a different archive."): | ||
376 | 1428 | archive.addArchiveDependency( | ||
377 | 1429 | dependency, PackagePublishingPocket.RELEASE) | ||
378 | 1430 | |||
379 | 1431 | def test_dependency_is_disabled(self): | ||
380 | 1432 | # A public archive may not depend on a private archive. | ||
381 | 1433 | archive = self.factory.makeArchive() | ||
382 | 1434 | dependency = self.factory.makeArchive( | ||
383 | 1435 | owner=archive.owner, enabled=False) | ||
384 | 1436 | with person_logged_in(archive.owner): | ||
385 | 1437 | with ExpectedException( | ||
386 | 1438 | ArchiveDependencyError, | ||
387 | 1439 | "This dependency is not active."): | ||
388 | 1440 | archive.addArchiveDependency( | ||
389 | 1441 | dependency, PackagePublishingPocket.RELEASE) | ||
390 | 1418 | 1442 | ||
391 | 1419 | class TestArchiveDependencies(TestCaseWithFactory): | 1443 | class TestArchiveDependencies(TestCaseWithFactory): |
392 | 1420 | 1444 | ||
393 | 1421 | 1445 | ||
394 | === modified file 'lib/lp/soyuz/tests/test_vocabularies.py' | |||
395 | --- lib/lp/soyuz/tests/test_vocabularies.py 2014-06-11 08:29:40 +0000 | |||
396 | +++ lib/lp/soyuz/tests/test_vocabularies.py 2014-08-29 01:29:58 +0000 | |||
397 | @@ -22,5 +22,5 @@ | |||
398 | 22 | term = vocab.toTerm(archive) | 22 | term = vocab.toTerm(archive) |
399 | 23 | self.assertThat(term, MatchesStructure.byEquality( | 23 | self.assertThat(term, MatchesStructure.byEquality( |
400 | 24 | value=archive, | 24 | value=archive, |
402 | 25 | token='%s/%s' % (archive.owner.name, archive.name), | 25 | token=archive.reference, |
403 | 26 | title='No description available')) | 26 | title='No description available')) |
404 | 27 | 27 | ||
405 | === modified file 'lib/lp/soyuz/vocabularies.py' | |||
406 | --- lib/lp/soyuz/vocabularies.py 2013-09-10 06:28:26 +0000 | |||
407 | +++ lib/lp/soyuz/vocabularies.py 2014-08-29 01:29:58 +0000 | |||
408 | @@ -1,4 +1,4 @@ | |||
410 | 1 | # Copyright 2009-2013 Canonical Ltd. This software is licensed under the GNU | 1 | # Copyright 2009-2014 Canonical Ltd. This software is licensed under the GNU |
411 | 2 | # Affero General Public License version 3 (see the file LICENSE). | 2 | # Affero General Public License version 3 (see the file LICENSE). |
412 | 3 | 3 | ||
413 | 4 | """Soyuz vocabularies.""" | 4 | """Soyuz vocabularies.""" |
414 | @@ -20,6 +20,7 @@ | |||
415 | 20 | from zope.component import getUtility | 20 | from zope.component import getUtility |
416 | 21 | from zope.interface import implements | 21 | from zope.interface import implements |
417 | 22 | from zope.schema.vocabulary import SimpleTerm | 22 | from zope.schema.vocabulary import SimpleTerm |
418 | 23 | from zope.security.interfaces import Unauthorized | ||
419 | 23 | 24 | ||
420 | 24 | from lp.registry.model.distroseries import DistroSeries | 25 | from lp.registry.model.distroseries import DistroSeries |
421 | 25 | from lp.registry.model.person import Person | 26 | from lp.registry.model.person import Person |
422 | @@ -32,6 +33,7 @@ | |||
423 | 32 | SQLObjectVocabularyBase, | 33 | SQLObjectVocabularyBase, |
424 | 33 | ) | 34 | ) |
425 | 34 | from lp.soyuz.enums import ArchivePurpose | 35 | from lp.soyuz.enums import ArchivePurpose |
426 | 36 | from lp.soyuz.interfaces.archive import IArchiveSet | ||
427 | 35 | from lp.soyuz.model.archive import Archive | 37 | from lp.soyuz.model.archive import Archive |
428 | 36 | from lp.soyuz.model.component import Component | 38 | from lp.soyuz.model.component import Component |
429 | 37 | from lp.soyuz.model.distroarchseries import DistroArchSeries | 39 | from lp.soyuz.model.distroarchseries import DistroArchSeries |
430 | @@ -88,6 +90,7 @@ | |||
431 | 88 | _orderBy = ['Person.name, Archive.name'] | 90 | _orderBy = ['Person.name, Archive.name'] |
432 | 89 | _clauseTables = ['Person'] | 91 | _clauseTables = ['Person'] |
433 | 90 | _filter = And( | 92 | _filter = And( |
434 | 93 | Archive._enabled == True, | ||
435 | 91 | Person.q.id == Archive.q.ownerID, | 94 | Person.q.id == Archive.q.ownerID, |
436 | 92 | Archive.q.purpose == ArchivePurpose.PPA) | 95 | Archive.q.purpose == ArchivePurpose.PPA) |
437 | 93 | displayname = 'Select a PPA' | 96 | displayname = 'Select a PPA' |
438 | @@ -95,35 +98,33 @@ | |||
439 | 95 | 98 | ||
440 | 96 | def toTerm(self, archive): | 99 | def toTerm(self, archive): |
441 | 97 | """See `IVocabulary`.""" | 100 | """See `IVocabulary`.""" |
447 | 98 | description = archive.description | 101 | try: |
448 | 99 | if description: | 102 | description = archive.description |
449 | 100 | summary = description.splitlines()[0] | 103 | if description: |
450 | 101 | else: | 104 | summary = description.splitlines()[0] |
451 | 102 | summary = "No description available" | 105 | else: |
452 | 106 | summary = "No description available" | ||
453 | 107 | except Unauthorized: | ||
454 | 108 | summary = None | ||
455 | 103 | 109 | ||
457 | 104 | token = '%s/%s' % (archive.owner.name, archive.name) | 110 | token = archive.reference |
458 | 105 | 111 | ||
459 | 106 | return SimpleTerm(archive, token, summary) | 112 | return SimpleTerm(archive, token, summary) |
460 | 107 | 113 | ||
461 | 108 | def getTermByToken(self, token): | 114 | def getTermByToken(self, token): |
462 | 109 | """See `IVocabularyTokenized`.""" | 115 | """See `IVocabularyTokenized`.""" |
463 | 110 | try: | 116 | try: |
465 | 111 | owner_name, archive_name = token.split('/') | 117 | owner_name, distro_name, archive_name = token.split('/') |
466 | 112 | except ValueError: | 118 | except ValueError: |
467 | 113 | raise LookupError(token) | 119 | raise LookupError(token) |
468 | 114 | 120 | ||
477 | 115 | clause = And( | 121 | obj = getUtility(IArchiveSet).getByReference(token) |
470 | 116 | self._filter, | ||
471 | 117 | Person.name == owner_name, | ||
472 | 118 | Archive.name == archive_name) | ||
473 | 119 | |||
474 | 120 | obj = self._table.selectOne( | ||
475 | 121 | clause, clauseTables=self._clauseTables) | ||
476 | 122 | |||
478 | 123 | if obj is None: | 122 | if obj is None: |
481 | 124 | raise LookupError(token) | 123 | return LookupError(token) |
482 | 125 | else: | 124 | elif obj.enabled: |
483 | 126 | return self.toTerm(obj) | 125 | return self.toTerm(obj) |
484 | 126 | else: | ||
485 | 127 | raise LookupError(token) | ||
486 | 127 | 128 | ||
487 | 128 | def search(self, query, vocab_filter=None): | 129 | def search(self, query, vocab_filter=None): |
488 | 129 | """Return a resultset of archives. | 130 | """Return a resultset of archives. |
489 | @@ -135,8 +136,14 @@ | |||
490 | 135 | 136 | ||
491 | 136 | query = query.lower() | 137 | query = query.lower() |
492 | 137 | 138 | ||
493 | 139 | if query.startswith('~'): | ||
494 | 140 | query = query.strip('~') | ||
495 | 138 | try: | 141 | try: |
497 | 139 | owner_name, archive_name = query.split('/') | 142 | query_split = query.split('/') |
498 | 143 | if len(query_split) == 3: | ||
499 | 144 | owner_name, distro_name, archive_name = query_split | ||
500 | 145 | else: | ||
501 | 146 | owner_name, archive_name = query_split | ||
502 | 140 | except ValueError: | 147 | except ValueError: |
503 | 141 | clause = And( | 148 | clause = And( |
504 | 142 | self._filter, | 149 | self._filter, |