Merge lp:~edwin-grubbs/launchpad/bug-597738-bug-service-status into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Approved by: Edwin Grubbs
Approved revision: no longer in the source branch.
Merged at revision: 11547
Proposed branch: lp:~edwin-grubbs/launchpad/bug-597738-bug-service-status
Merge into: lp:launchpad
Prerequisite: lp:~jcsackett/launchpad/deprecate-official_codehosting
Diff against target: 550 lines (+193/-107)
13 files modified
lib/lp/answers/browser/questiontarget.py (+0/-16)
lib/lp/answers/browser/tests/test_questiontarget.py (+0/-24)
lib/lp/answers/templates/unknown-support.pt (+4/-5)
lib/lp/bugs/browser/bugtarget.py (+11/-6)
lib/lp/bugs/model/bugtask.py (+1/-0)
lib/lp/bugs/stories/bugs/xx-front-page-info.txt (+21/-8)
lib/lp/bugs/templates/bugtarget-bugs.pt (+62/-24)
lib/lp/registry/browser/productseries.py (+19/-2)
lib/lp/registry/doc/product.txt (+6/-0)
lib/lp/registry/interfaces/product.py (+3/-0)
lib/lp/registry/model/product.py (+38/-21)
lib/lp/testing/factory.py (+27/-0)
lib/lp/testing/menu.py (+1/-1)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-597738-bug-service-status
Reviewer Review Type Date Requested Status
Curtis Hovey (community) ui Approve
Henning Eggers (community) ui* Approve
Deryck Hodge (community) ui Abstain
Jelmer Vernooij (community) code Approve
Review via email: mp+34250@code.launchpad.net

Description of the change

Summary
-------

This branch provides the user with more information about filing bugs on
the bugs.launchpad.net/$project page. This branch also takes advantage
of the new bug_tracking_usage attribute that returns an enum as opposed
to the old official_malone boolean. If the project is not using
Launchpad as the bug tracker, the page will also inform the user of any
ubuntu packages linked to the project under which bugs can be filed.

This branch is dependent on
lp:~jcsackett/launchpad/deprecate-official_codehosting

Implementation details
----------------------

lib/lp/answers/browser/questiontarget.py
lib/lp/answers/browser/tests/test_questiontarget.py
lib/lp/answers/templates/unknown-support.pt
lib/lp/bugs/browser/bugtarget.py
lib/lp/bugs/stories/bugs/xx-front-page-info.txt
lib/lp/bugs/templates/bugtarget-bugs.pt
lib/lp/registry/doc/product.txt
lib/lp/registry/interfaces/product.py
lib/lp/registry/model/product.py

Tests
-----

./bin/test -vv -t 'xx-front-page-info.txt|doc/product.txt'

Demo and Q/A
------------

* Open http://launchpad.dev/firefox/+configure-bugtracker
  * Switch the "Bugs are tracked" field between the values.
* Open http://bugs.launchpad.dev/firefox
  * If bugs are tracked in launchpad, a bug table should be shown.
  * If bugs are tracked externally, the page should contain:
      <meta name="robots" content="noindex,nofollow"/>
      <strong>Bugs are tracked in _SOME BUGTRACKER_.</strong>

      <a>Getting started with bug tracking in Launchpad.</a>
      Firefox bug reports are also tracked in <a>mozilla-firefox in Ubuntu</a>.

  * If launchpad doesn't know where bugs are tracked, it should contain:
      <meta name="robots" content="noindex,nofollow"/>
      <strong>
      Launchpad does not know where to forward bug reports to contact the*
      developers of Mozilla Firefox.
      </strong>

      <a>Getting started with bug tracking in Launchpad.</a>
      Firefox bug reports are tracked in <a>mozilla-firefox in Ubuntu</a>.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

The text "Mozilla Firefox bug reports are tracked in: mozilla-firefox in ubuntu, mozilla-firefox in ubuntu." is a bit confusing. The text is repeated, but I would also argue that the text should mention somehow that those places are not for the bugs for upstream Firefox.

Perhaps something like: "Launchpad keeps track of bug reports for <a>mozilla-firefox in Ubuntu</a>."

review: Needs Fixing (code)
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

> The text "Mozilla Firefox bug reports are tracked in: mozilla-firefox in
> ubuntu, mozilla-firefox in ubuntu." is a bit confusing. The text is repeated,
> but I would also argue that the text should mention somehow that those places
> are not for the bugs for upstream Firefox.
>
> Perhaps something like: "Launchpad keeps track of bug reports for <a>mozilla-
> firefox in Ubuntu</a>."

Hi Jelmer,

Thanks for the review. I've made the wording changes you suggested, and I resolved the merge conflict with devel. When I removed the code that made the results distinct on the distro, I didn't realize that what was really necessary was to make it distinct on the distro/sourcepackagename. I did that, so now you won't see the odd duplicates on that page. I also added some testing for that text.

-Edwin

Revision history for this message
Jelmer Vernooij (jelmer) :
review: Approve (code)
Revision history for this message
Deryck Hodge (deryck) wrote :

Since I'm not a UI reviewer, I'll abstain from review; however, as a bugs guy looking at the change, I'm not sure the language is quite right for the case where we don't know where bugs are tracked. Saying Launchpad "does not know where to forward bug reports" assumes the project doesn't host itself on Launchpad. I think it would read better as Launchpad "does not know where $project tracks its bugs." Or something like that.

Just my .02c. :-) Nice work, otherwise.

Cheers,
deryck

review: Abstain (ui)
Revision history for this message
Henning Eggers (henninge) wrote :

Hi Edwin!
Thanks for adding these helpful comments. I think the help link is very important. Although you don't mention it it looks like you did the same for answers. Generally this looks good to me although I have a few small comments.

"Launchpad does not know where to forward bug reports to contact the developers of Mozilla Firefox."
That sentence seems to either be missing a "to" or I am misunderstanding it. Maybe it should simply be "Launchpad does not know where to forward bug reports to." or even just "Bugs are not tracked in Launchpad". The latter is consistent with "Bugs are tracked in The Mozilla.org Bug Tracker."

I wonder if the next line should be prefixed with "Hint: Launchpad keeps track of ..." to make clear it's a hint and not contradicting the previous line. The same line on the answers page should be worded similarly.

Actually, I think these wording questions are Matt Revell's domain .... ;-)

OK, here is the real UI issue I have:
"Launchpad allows your project to track questions and create FAQs." sits right on top the helpful links. There should at least be some padding in between those but really I think that line should go away completely. It can be integrated in the help link, e.g. "Getting started with offering support for your project." which explains a bit more what this is about.

With that last change in place, I can approve the UI here. That's it. ;-)

Henning

review: Approve (ui*)
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

> Hi Edwin!
> Thanks for adding these helpful comments. I think the help link is very
> important. Although you don't mention it it looks like you did the same for
> answers. Generally this looks good to me although I have a few small comments.
>
> "Launchpad does not know where to forward bug reports to contact the
> developers of Mozilla Firefox."
> That sentence seems to either be missing a "to" or I am misunderstanding it.
> Maybe it should simply be "Launchpad does not know where to forward bug
> reports to." or even just "Bugs are not tracked in Launchpad". The latter is
> consistent with "Bugs are tracked in The Mozilla.org Bug Tracker."

The reason for the wordiness is that I'm trying to explain to the user the difference between reporting a bug on ubuntu's firefox package and reporting a bug to the actual developers, since this page will suggest reporting a bug on the package if the project doesn't use Launchpad as their bug tracker. I want to avoid saying "Bugs are not tracked in Launchpad. You can submit a bug for the firefox package." since that sounds contradictory.

How does this sound? "Mozilla Firefox must be configured in order for Launchpad to forward bugs to the project's developers."

> I wonder if the next line should be prefixed with "Hint: Launchpad keeps track
> of ..." to make clear it's a hint and not contradicting the previous line. The
> same line on the answers page should be worded similarly.
>
> Actually, I think these wording questions are Matt Revell's domain .... ;-)
>
> OK, here is the real UI issue I have:
> "Launchpad allows your project to track questions and create FAQs." sits right
> on top the helpful links. There should at least be some padding in between
> those but really I think that line should go away completely. It can be
> integrated in the help link, e.g. "Getting started with offering support for
> your project." which explains a bit more what this is about.

I think that getting rid of the text looks cleaner than integrating it with the help link, but I don't know how important it is to explain that "offering support" means tracking questions and creating FAQs.

I'll let the secondary UI reviewer weigh in before I change the branch.

> With that last change in place, I can approve the UI here. That's it. ;-)
>
> Henning

Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (5.8 KiB)

Hi Edwin, et al.

I have some concerns about the consistency of the unknown/external/lp
states for all bug targets and some of their states. I think we need to
address all of these and I think we need to plan one or more branches to
complete the bugs app front page for bugtargets

(distro) https://bugs.launchpad.dev/kubuntu as Admin

    I see a message about forwarding bugs, but I know distros cannot
    have remote bug trackers. The choice is Launchpad or does not use
    Launchpad. The current message is better

    This is a fair example of why we do not use context/title inline.

    I see "_Enable bug tracking._" I think there should be an edit icon
    preceding it.

(dsp) https://bugs.launchpad.dev/kubuntu/+source/mozilla-firefox

    Oh my! This implies kubuntu does use bugs. I get an oops if I try to
    report bug.
    /me looks at fedora on lpnet.
    https://bugs.edge.launchpad.net/fedora/+source/mozilla-firefox
    also prompts me to report a bug and it too oopses :(
    ^ This is a separate issue but this is exactly the kind of
      mis-communication we are trying to fix. bridging the grape is not
      done until we address this.
      https://bugs.edge.launchpad.net/malone/+bug/635302

(project) https://bugs.launchpad.dev/gnome-terminal with bug tracker

    Looks good.

(project) https://bugs.launchpad.dev/thunderbird after linking to two packages

    I see
        Launchpad keeps track of bug reports for _cnews in ubuntu_,
        _pmount in ubuntu_.
    which is very odd. Some projects produce 20 packages and some have
    names nothing like the upstream project in Lp. I am not sure Launchpad
    is tracking this bugs, Ubuntu is. Maybe
        Ubuntu tracks bugs related to packages derived from this project:
        _cnews in ubuntu_, _pmount in ubuntu_.

(project group) https://bugs.launchpad.dev/launchpad-mirrors

    Implies the project groups has projects that track bugs. This is not
    True. The page should state that none of the group's project use
    Launchpad to track bugs. There is nothing to configure since the behaviour
    is derived from the state of member projects. The answers app tells the
    user that Lp does not know where support is managed.

> === modified file 'lib/lp/bugs/templates/bugtarget-bugs.pt'
> --- lib/lp/bugs/templates/bugtarget-bugs.pt 2010-08-04 11:01:15 +0000
> +++ lib/lp/bugs/templates/bugtarget-bugs.pt 2010-09-10 14:33:54 +0000
> ...
>
> @@ -162,27 +166,55 @@
>
> <p id="no-bugs-report"><a href="+filebug">Report a bug.</a></p>
> </tal:no_hot_bugs>
> - </tal:uses_malone>
> -
> - <tal:not_uses_malone condition="not: view/uses_launchpad_bugtracker"
> - tal:define ="configure_bugtracker context/menu:overview/configure_bugtracker | nothing">
> - <p id="no-malone"><strong><tal:project_title replace="context/title" /> does not use Launchpad for
> - bug tracking.</strong></p>
> - <p tal:condition="view/external_bugtracker"
> - id="bugtracker"><strong>Bugs are tracked in
> - <tal:bugtracker replace="structure view/bugtracker" />.</strong>
> - </p>
> -
> - <p tal:condition="context/required:launchpad.Edi...

Read more...

review: Needs Information (ui)
Revision history for this message
Curtis Hovey (sinzui) wrote :

> > Hi Edwin!
> > Thanks for adding these helpful comments. I think the help link is very
> > important. Although you don't mention it it looks like you did the same for
> > answers. Generally this looks good to me although I have a few small
> comments.
> >
> > "Launchpad does not know where to forward bug reports to contact the
> > developers of Mozilla Firefox."
> > That sentence seems to either be missing a "to" or I am misunderstanding
> it.
> > Maybe it should simply be "Launchpad does not know where to forward bug
> > reports to." or even just "Bugs are not tracked in Launchpad". The latter is
> > consistent with "Bugs are tracked in The Mozilla.org Bug Tracker."
>
>
> The reason for the wordiness is that I'm trying to explain to the user the
> difference between reporting a bug on ubuntu's firefox package and reporting a
> bug to the actual developers, since this page will suggest reporting a bug on
> the package if the project doesn't use Launchpad as their bug tracker. I want
> to avoid saying "Bugs are not tracked in Launchpad. You can submit a bug for
> the firefox package." since that sounds contradictory.
>
> How does this sound? "Mozilla Firefox must be configured in order for
> Launchpad to forward bugs to the project's developers."

I think this text is fine. I think part of the problem is really about the Ubuntu case. Ubuntu is not tracking project bugs, it is tracking package bugs:

Ubuntu tracks bugs related to packages derived from this project:
        _cnews in ubuntu_, _pmount in ubuntu_.

...

> > integrated in the help link, e.g. "Getting started with offering support for
> > your project." which explains a bit more what this is about.
>
>
> I think that getting rid of the text looks cleaner than integrating it with
> the help link, but I don't know how important it is to explain that "offering
> support" means tracking questions and creating FAQs.

Instead of support, maybe we should just say "questions and FAQs", because that is what we want to know. I will be adding fields for mailing lists and forums for answers in my after hours, so I expect the external page will clearly state where the user can find the answers to his or her questions.

Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :
Download full text (7.3 KiB)

> Hi Edwin, et al.
>
> I have some concerns about the consistency of the unknown/external/lp
> states for all bug targets and some of their states. I think we need to
> address all of these and I think we need to plan one or more branches to
> complete the bugs app front page for bugtargets
>
> (distro) https://bugs.launchpad.dev/kubuntu as Admin
>
> I see a message about forwarding bugs, but I know distros cannot
> have remote bug trackers. The choice is Launchpad or does not use
> Launchpad. The current message is better

I have added a conditional to display the old message if the context cannot have an external bug tracker.

> This is a fair example of why we do not use context/title inline.
>
> I see "_Enable bug tracking._" I think there should be an edit icon
> preceding it.

I have added the sprite to this link.

> (dsp) https://bugs.launchpad.dev/kubuntu/+source/mozilla-firefox
>
> Oh my! This implies kubuntu does use bugs. I get an oops if I try to
> report bug.
> /me looks at fedora on lpnet.
> https://bugs.edge.launchpad.net/fedora/+source/mozilla-firefox
> also prompts me to report a bug and it too oopses :(
> ^ This is a separate issue but this is exactly the kind of
> mis-communication we are trying to fix. bridging the grape is not
> done until we address this.
> https://bugs.edge.launchpad.net/malone/+bug/635302

The DSP's default view is +bugs instead of +bugs-index, so it has no logic to inform the user that Launchpad doesn't track bugs for the DSP.

> (project) https://bugs.launchpad.dev/gnome-terminal with bug tracker
>
> Looks good.
>
> (project) https://bugs.launchpad.dev/thunderbird after linking to two packages
>
> I see
> Launchpad keeps track of bug reports for _cnews in ubuntu_,
> _pmount in ubuntu_.
> which is very odd. Some projects produce 20 packages and some have
> names nothing like the upstream project in Lp. I am not sure Launchpad
> is tracking this bugs, Ubuntu is. Maybe
> Ubuntu tracks bugs related to packages derived from this project:
> _cnews in ubuntu_, _pmount in ubuntu_.

I have made that change to the wording.

> (project group) https://bugs.launchpad.dev/launchpad-mirrors
>
> Implies the project groups has projects that track bugs. This is not
> True. The page should state that none of the group's project use
> Launchpad to track bugs. There is nothing to configure since the behaviour
> is derived from the state of member projects. The answers app tells the
> user that Lp does not know where support is managed.

Just like DSPs, ProjectGroups use +bugs instead of +bugs-index, so it will take some work in a later branch to fix.

> > === modified file 'lib/lp/bugs/templates/bugtarget-bugs.pt'
> > --- lib/lp/bugs/templates/bugtarget-bugs.pt 2010-08-04 11:01:15 +0000
> > +++ lib/lp/bugs/templates/bugtarget-bugs.pt 2010-09-10 14:33:54 +0000
> > ...
> >
> > @@ -162,27 +166,55 @@
> >
> > <p id="no-bugs-report"><a href="+filebug">Report a bug.</a></p>
> > </tal:no_hot_bugs>
> > - </tal:uses_malone>
> > -
> > - <tal:not_uses_...

Read more...

Revision history for this message
Curtis Hovey (sinzui) wrote :

Thanks for examining these issue and explaining what is happening. I think your branch is fine to land. We can discuss next steps in a separate thread. The series.title is an interesting issue because the attr is in the process of being removed from distroseries as a part of the Derivative distro work.

review: Approve (ui)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/answers/browser/questiontarget.py'
2--- lib/lp/answers/browser/questiontarget.py 2010-09-03 13:32:42 +0000
3+++ lib/lp/answers/browser/questiontarget.py 2010-09-14 13:29:47 +0000
4@@ -507,22 +507,6 @@
5 question.sourcepackagename.name)
6
7 @property
8- def ubuntu_packages(self):
9- """The Ubuntu `IDistributionSourcePackage`s linked to the context.
10-
11- If the context is an `IProduct` and it has `IPackaging` links to
12- Ubuntu, a list is returned. Otherwise None is returned
13- """
14- if IProduct.providedBy(self.context):
15- ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
16- packages = [
17- package for package in self.context.distrosourcepackages
18- if package.distribution == ubuntu]
19- if len(packages) > 0:
20- return packages
21- return None
22-
23- @property
24 def can_configure_answers(self):
25 """Can the user configure answers for the `IQuestionTarget`."""
26 target = self.context
27
28=== modified file 'lib/lp/answers/browser/tests/test_questiontarget.py'
29--- lib/lp/answers/browser/tests/test_questiontarget.py 2010-09-06 09:11:43 +0000
30+++ lib/lp/answers/browser/tests/test_questiontarget.py 2010-09-14 13:29:47 +0000
31@@ -135,30 +135,6 @@
32 self.assertViewTemplate(question_set, 'question-listing.pt')
33
34
35-class TestSearchQuestionsView_ubuntu_packages(TestSearchQuestionsView):
36- """Test the behaviour of SearchQuestionsView.ubuntu_packages."""
37-
38- def test_nonproduct_ubuntu_packages(self):
39- distribution = self.factory.makeDistribution()
40- view = create_initialized_view(distribution, '+questions')
41- packages = view.ubuntu_packages
42- self.assertEqual(None, packages)
43-
44- def test_product_ubuntu_packages_unlinked(self):
45- product = self.factory.makeProduct()
46- view = create_initialized_view(product, '+questions')
47- packages = view.ubuntu_packages
48- self.assertEqual(None, packages)
49-
50- def test_product_ubuntu_packages_linked(self):
51- product = self.factory.makeProduct()
52- self.linkPackage(product, 'cow')
53- view = create_initialized_view(product, '+questions')
54- packages = view.ubuntu_packages
55- self.assertEqual(1, len(packages))
56- self.assertEqual('cow', packages[0].name)
57-
58-
59 class TestSearchQuestionsViewUnknown(TestSearchQuestionsView):
60 """Test the behaviour of SearchQuestionsView unknown support."""
61
62
63=== modified file 'lib/lp/answers/templates/unknown-support.pt'
64--- lib/lp/answers/templates/unknown-support.pt 2010-08-05 17:14:05 +0000
65+++ lib/lp/answers/templates/unknown-support.pt 2010-09-14 13:29:47 +0000
66@@ -21,9 +21,9 @@
67 </p>
68
69 <p id="ubuntu-support"
70- tal:define="packages view/ubuntu_packages"
71+ tal:define="packages context/ubuntu_packages | nothing"
72 tal:condition="packages">
73- <tal:project replace="context/displayname" /> questions are also
74+ <tal:project replace="context/displayname" /> questions are
75 tracked in: <tal:packages repeat="package packages">
76 <tal:package replace="structure package/fmt:link" /><tal:comma
77 condition="not:repeat/package/end">, </tal:comma></tal:packages>.
78@@ -31,10 +31,9 @@
79
80 <p id="configure-support"
81 tal:condition="view/can_configure_answers">
82- Launchpad allows your project to track questions and create FAQs.
83- <br /><a class="sprite maybe"
84+ <a class="sprite maybe"
85 href="https://help.launchpad.net/Answers">Getting started
86- with support tracking in Launchpad</a>.
87+ tracking questions and FAQs in Launchpad</a>.
88 <br /><a tal:replace="structure context/menu:overview/configure_answers/fmt:link" />
89 </p>
90 </div>
91
92=== modified file 'lib/lp/bugs/browser/bugtarget.py'
93--- lib/lp/bugs/browser/bugtarget.py 2010-09-03 03:12:39 +0000
94+++ lib/lp/bugs/browser/bugtarget.py 2010-09-14 13:29:47 +0000
95@@ -1252,13 +1252,18 @@
96 bug_statuses_to_show.append(BugTaskStatus.FIXRELEASED)
97
98 @property
99- def uses_launchpad_bugtracker(self):
100- """Whether this distro or product tracks bugs in launchpad.
101-
102- :returns: boolean
103+ def can_have_external_bugtracker(self):
104+ return (IProduct.providedBy(self.context)
105+ or IProductSeries.providedBy(self.context))
106+
107+ @property
108+ def bug_tracking_usage(self):
109+ """Whether the context tracks bugs in launchpad.
110+
111+ :returns: ServiceUsage enum value
112 """
113 service_usage = IServiceUsage(self.context)
114- return service_usage.bug_tracking_usage == ServiceUsage.LAUNCHPAD
115+ return service_usage.bug_tracking_usage
116
117 @property
118 def external_bugtracker(self):
119@@ -1278,7 +1283,7 @@
120
121 :returns: str which may contain HTML.
122 """
123- if self.uses_launchpad_bugtracker:
124+ if self.bug_tracking_usage == ServiceUsage.LAUNCHPAD:
125 return 'Launchpad'
126 elif self.external_bugtracker:
127 return BugTrackerFormatterAPI(self.external_bugtracker).link(None)
128
129=== modified file 'lib/lp/bugs/model/bugtask.py'
130--- lib/lp/bugs/model/bugtask.py 2010-09-03 03:12:39 +0000
131+++ lib/lp/bugs/model/bugtask.py 2010-09-14 13:29:47 +0000
132@@ -159,6 +159,7 @@
133 from lp.soyuz.model.publishing import SourcePackagePublishingHistory
134 from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
135
136+
137 debbugsseveritymap = {
138 None: BugTaskImportance.UNDECIDED,
139 'wishlist': BugTaskImportance.WISHLIST,
140
141=== modified file 'lib/lp/bugs/stories/bugs/xx-front-page-info.txt'
142--- lib/lp/bugs/stories/bugs/xx-front-page-info.txt 2010-05-08 15:29:56 +0000
143+++ lib/lp/bugs/stories/bugs/xx-front-page-info.txt 2010-09-14 13:29:47 +0000
144@@ -19,7 +19,8 @@
145 >>> anon_browser.open('http://bugs.launchpad.dev/test-project')
146 >>> uses_malone_p = find_tag_by_id(anon_browser.contents, 'no-malone')
147 >>> print extract_text(uses_malone_p)
148- Simple Test Project does not use Launchpad for bug tracking.
149+ Test-project must be configured in order for Launchpad to forward bugs to
150+ the project's developers.
151
152 Only users who have permission to do so can enable bug tracking
153 for a project.
154@@ -53,7 +54,7 @@
155 >>> bug_list = find_tag_by_id(
156 ... anon_browser.contents, 'no-bugs-filed')
157 >>> print extract_text(bug_list)
158- There are currently no bugs filed against Project Uses Malone.
159+ There are currently no bugs filed against Uses-malone.
160
161 Since there are no bugs at all filed for the project, no search box is
162 shown.
163@@ -100,7 +101,7 @@
164 >>> bug_list = find_tag_by_id(
165 ... anon_browser.contents, 'no-bugs-filed')
166 >>> print extract_text(bug_list)
167- There are currently no open bugs filed against Project Uses Malone.
168+ There are currently no open bugs filed against Uses-malone.
169
170 But since the project has a bug, the search box is still visible.
171
172@@ -112,8 +113,7 @@
173 Advanced search
174
175 Projects that use an external bug tracker will list the tracker on a
176-bugs home page in addition to the message that the project does not
177-use Launchpad for bug tracking.
178+bugs home page.
179
180 >>> login('foo.bar@canonical.com')
181 >>> some_tracker = factory.makeBugTracker(
182@@ -121,9 +121,22 @@
183 >>> test_project.bugtracker = some_tracker
184 >>> logout()
185 >>> anon_browser.open('http://bugs.launchpad.dev/test-project')
186- >>> uses_malone_p = find_tag_by_id(anon_browser.contents, 'no-malone')
187- >>> print extract_text(uses_malone_p)
188- Simple Test Project does not use Launchpad for bug tracking.
189 >>> tracker_text = find_tag_by_id(anon_browser.contents, 'bugtracker')
190 >>> print extract_text(tracker_text)
191 Bugs are tracked in tracker.example.com/.
192+
193+Projects that are linked to an Ubuntu distro source package and that
194+don't use Launchpad for bug tracking will inform the user that a bug can
195+be reported on the project's source packages.
196+
197+ >>> login('foo.bar@canonical.com')
198+ >>> factory.makePackagingLink(
199+ ... productseries=test_project.development_focus,
200+ ... sourcepackagename='test-project-package',
201+ ... in_ubuntu=True)
202+ >>> logout()
203+ >>> anon_browser.open('http://bugs.launchpad.dev/test-project')
204+ >>> print extract_text(
205+ ... find_tag_by_id(anon_browser.contents, 'also-in-ubuntu'))
206+ Ubuntu also tracks bugs for packages derived from this project:
207+ test-project-package in ubuntu.
208
209=== modified file 'lib/lp/bugs/templates/bugtarget-bugs.pt'
210--- lib/lp/bugs/templates/bugtarget-bugs.pt 2010-08-04 11:01:15 +0000
211+++ lib/lp/bugs/templates/bugtarget-bugs.pt 2010-09-14 13:29:47 +0000
212@@ -10,12 +10,15 @@
213 i18n:domain="malone"
214 >
215 <metal:block fill-slot="head_epilogue">
216+ <meta tal:condition="not: view/bug_tracking_usage/enumvalue:LAUNCHPAD"
217+ name="robots" content="noindex,nofollow" />
218 <style type="text/css">
219 p#more-hot-bugs {float:right; margin-top:7px;}
220 </style>
221 </metal:block>
222 <body>
223- <tal:side metal:fill-slot="side" condition="view/uses_launchpad_bugtracker">
224+ <tal:side metal:fill-slot="side"
225+ condition="view/bug_tracking_usage/enumvalue:LAUNCHPAD">
226 <div id="involvement" class="portlet">
227 <ul class="involvement">
228 <li style="border: none">
229@@ -95,7 +98,8 @@
230
231
232
233- <tal:uses_malone condition="view/uses_launchpad_bugtracker">
234+ <tal:uses_launchpad_bugtracker
235+ condition="view/bug_tracking_usage/enumvalue:LAUNCHPAD">
236 <tal:has_bugtasks condition="context/has_bugtasks">
237 <div class="search-box" style="margin-bottom:2em">
238 <metal:search
239@@ -158,31 +162,65 @@
240 <tal:no_hot_bugs condition="not: view/hot_bugs_info/bugtasks">
241 <p id="no-bugs-filed"><strong>There are currently no
242 <span tal:condition="context/has_bugtasks">open</span> bugs filed
243- against <tal:project_title replace="context/title" />.</strong></p>
244+ against <tal:displayname replace="context/displayname" />.</strong></p>
245
246 <p id="no-bugs-report"><a href="+filebug">Report a bug.</a></p>
247 </tal:no_hot_bugs>
248- </tal:uses_malone>
249-
250- <tal:not_uses_malone condition="not: view/uses_launchpad_bugtracker"
251- tal:define ="configure_bugtracker context/menu:overview/configure_bugtracker | nothing">
252- <p id="no-malone"><strong><tal:project_title replace="context/title" /> does not use Launchpad for
253- bug tracking.</strong></p>
254- <p tal:condition="view/external_bugtracker"
255- id="bugtracker"><strong>Bugs are tracked in
256- <tal:bugtracker replace="structure view/bugtracker" />.</strong>
257- </p>
258-
259- <p tal:condition="context/required:launchpad.Edit"
260- id="no-malone-edit"
261- >
262- <a tal:condition="configure_bugtracker"
263- tal:replace="structure configure_bugtracker/fmt:link"/>
264- <a tal:condition="not: configure_bugtracker"
265- tal:attributes="href string:${context/fmt:url/+edit}">
266- Enable bug tracking.</a>
267- </p>
268- </tal:not_uses_malone>
269+ </tal:uses_launchpad_bugtracker>
270+
271+ <p id="no-malone"
272+ tal:condition="view/bug_tracking_usage/enumvalue:UNKNOWN">
273+ <strong tal:condition="view/can_have_external_bugtracker">
274+ <tal:displayname replace="context/displayname" />
275+ must be configured in order for Launchpad to forward bugs to
276+ the project's developers.
277+ </strong>
278+ <strong tal:condition="not: view/can_have_external_bugtracker">
279+ <tal:displayname replace="context/displayname" />
280+ does not use Launchpad for bug tracking.
281+ </strong>
282+ </p>
283+
284+ <p tal:condition="view/external_bugtracker"
285+ id="bugtracker">
286+ <strong>Bugs are tracked in
287+ <tal:bugtracker replace="structure view/bugtracker" />.
288+ </strong>
289+ </p>
290+
291+ <tal:also_in_ubuntu
292+ condition="not: view/bug_tracking_usage/enumvalue:LAUNCHPAD">
293+ <p tal:define="packages context/ubuntu_packages | nothing"
294+ tal:condition="packages"
295+ id="also-in-ubuntu">
296+ Ubuntu
297+ <tal:also condition="view/external_bugtracker">also</tal:also>
298+ tracks bugs for packages derived from this project:
299+ <tal:packages repeat="package packages">
300+ <span style="white-space: nowrap"
301+ tal:content="structure package/fmt:link" /><tal:comma
302+ condition="not:repeat/package/end">,</tal:comma></tal:packages>.
303+ </p>
304+ </tal:also_in_ubuntu>
305+
306+ <div
307+ tal:condition="not: view/bug_tracking_usage/enumvalue:LAUNCHPAD"
308+ tal:define="configure_bugtracker context/menu:overview/configure_bugtracker | nothing">
309+ <a class="sprite maybe"
310+ href="https://help.launchpad.net/Bugs">Getting started
311+ with bug tracking in Launchpad</a>.
312+
313+ <p tal:condition="context/required:launchpad.Edit"
314+ id="no-malone-edit"
315+ >
316+ <a tal:condition="configure_bugtracker"
317+ tal:replace="structure configure_bugtracker/fmt:link"/>
318+ <a class="sprite edit"
319+ tal:condition="not: configure_bugtracker"
320+ tal:attributes="href string:${context/fmt:url/+edit}">
321+ Enable bug tracking.</a>
322+ </p>
323+ </div>
324
325 </div><!-- main -->
326 </body>
327
328=== modified file 'lib/lp/registry/browser/productseries.py'
329--- lib/lp/registry/browser/productseries.py 2010-09-09 18:21:55 +0000
330+++ lib/lp/registry/browser/productseries.py 2010-09-14 13:29:47 +0000
331@@ -280,12 +280,29 @@
332 usedfor = IProductSeries
333 facet = 'overview'
334 links = [
335- 'edit', 'delete', 'driver', 'link_branch', 'ubuntupkg',
336- 'create_milestone', 'create_release', 'rdf', 'subscribe',
337+ 'configure_bugtracker',
338+ 'create_milestone',
339+ 'create_release',
340+ 'delete',
341+ 'driver',
342+ 'edit',
343+ 'link_branch',
344+ 'rdf',
345 'set_branch',
346+ 'subscribe',
347+ 'ubuntupkg',
348 ]
349
350 @enabled_with_permission('launchpad.Edit')
351+ def configure_bugtracker(self):
352+ text = 'Configure bug tracker'
353+ summary = 'Specify where bugs are tracked for this project'
354+ return Link(
355+ canonical_url(self.context.product,
356+ view_name='+configure-bugtracker'),
357+ text, summary, icon='edit')
358+
359+ @enabled_with_permission('launchpad.Edit')
360 def edit(self):
361 """Return a link to edit this series."""
362 text = 'Change details'
363
364=== modified file 'lib/lp/registry/doc/product.txt'
365--- lib/lp/registry/doc/product.txt 2010-09-10 13:29:42 +0000
366+++ lib/lp/registry/doc/product.txt 2010-09-14 13:29:47 +0000
367@@ -225,6 +225,11 @@
368 >>> [(sp.name, sp.distribution.name) for sp in alsa.distrosourcepackages]
369 [(u'alsa-utils', u'debian'), (u'alsa-utils', u'ubuntu')]
370
371+For convenience, you can get just the distro source packages for Ubuntu.
372+
373+ >>> [(sp.name, sp.distribution.name) for sp in alsa.ubuntu_packages]
374+ [(u'alsa-utils', u'ubuntu')]
375+
376 The date_next_suggest_packaging attribute records the date when Launchpad can
377 resume suggesting Ubuntu packages that the project provides. A value of None
378 means that no user has ever confirmed that that the project has no Ubuntu
379@@ -714,6 +719,7 @@
380 ... print series.name
381 trunk
382
383+
384 Changing ownership
385 ==================
386
387
388=== modified file 'lib/lp/registry/interfaces/product.py'
389--- lib/lp/registry/interfaces/product.py 2010-08-31 00:02:42 +0000
390+++ lib/lp/registry/interfaces/product.py 2010-09-14 13:29:47 +0000
391@@ -644,6 +644,9 @@
392 distrosourcepackages = Attribute(_("List of distribution packages for "
393 "this product"))
394
395+ ubuntu_packages = Attribute(
396+ _("List of distribution packages for this product in Ubuntu"))
397+
398 series = exported(
399 doNotSnapshot(
400 CollectionField(value_type=Object(schema=IProductSeries))))
401
402=== modified file 'lib/lp/registry/model/product.py'
403--- lib/lp/registry/model/product.py 2010-09-03 11:05:21 +0000
404+++ lib/lp/registry/model/product.py 2010-09-14 13:29:47 +0000
405@@ -48,6 +48,9 @@
406 SQLBase,
407 sqlvalues,
408 )
409+from canonical.launchpad.components.decoratedresultset import (
410+ DecoratedResultSet,
411+ )
412 from canonical.launchpad.interfaces.launchpad import (
413 IHasIcon,
414 IHasLogo,
415@@ -64,6 +67,7 @@
416 MAIN_STORE,
417 )
418 from canonical.launchpad.webapp.sorting import sorted_version_numbers
419+
420 from lp.answers.interfaces.faqtarget import IFAQTarget
421 from lp.answers.interfaces.questioncollection import (
422 QUESTION_STATUS_DEFAULT_SEARCH,
423@@ -146,6 +150,7 @@
424 from lp.registry.model.productlicense import ProductLicense
425 from lp.registry.model.productrelease import ProductRelease
426 from lp.registry.model.productseries import ProductSeries
427+from lp.registry.model.sourcepackagename import SourcePackageName
428 from lp.registry.model.structuralsubscription import (
429 StructuralSubscriptionTargetMixin,
430 )
431@@ -829,28 +834,40 @@
432 (x.sourcepackagename.name, x.distroseries.name,
433 x.distroseries.distribution.name))
434
435- @property
436+ @cachedproperty
437 def distrosourcepackages(self):
438- from lp.registry.model.distributionsourcepackage \
439- import DistributionSourcePackage
440- clause = """ProductSeries.id=Packaging.productseries AND
441- ProductSeries.product = %s
442- """ % sqlvalues(self.id)
443- clauseTables = ['ProductSeries']
444- ret = Packaging.select(clause, clauseTables,
445- prejoins=["sourcepackagename", "distroseries.distribution"])
446- distros = set()
447- dsps = []
448- for packaging in ret:
449- distro = packaging.distroseries.distribution
450- if distro in distros:
451- continue
452- distros.add(distro)
453- dsps.append(DistributionSourcePackage(
454- sourcepackagename=packaging.sourcepackagename,
455- distribution=distro))
456- return sorted(dsps, key=lambda x:
457- (x.sourcepackagename.name, x.distribution.name))
458+ from lp.registry.model.distributionsourcepackage import (
459+ DistributionSourcePackage,
460+ )
461+ store = IStore(Packaging)
462+ origin = [
463+ Packaging,
464+ Join(SourcePackageName,
465+ Packaging.sourcepackagename == SourcePackageName.id),
466+ Join(ProductSeries, Packaging.productseries == ProductSeries.id),
467+ Join(DistroSeries, Packaging.distroseries == DistroSeries.id),
468+ Join(Distribution, DistroSeries.distribution == Distribution.id),
469+ ]
470+ result = store.using(*origin).find(
471+ (SourcePackageName, Distribution),
472+ ProductSeries.product == self)
473+ result = result.order_by(SourcePackageName.name, Distribution.name)
474+ result.config(distinct=True)
475+
476+ return [
477+ DistributionSourcePackage(
478+ sourcepackagename=sourcepackagename,
479+ distribution=distro)
480+ for sourcepackagename, distro in result]
481+
482+ @cachedproperty
483+ def ubuntu_packages(self):
484+ """The Ubuntu `IDistributionSourcePackage`s linked to the `IProduct`.
485+ """
486+ ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
487+ return [
488+ package for package in self.distrosourcepackages
489+ if package.distribution == ubuntu]
490
491 @property
492 def bugtargetdisplayname(self):
493
494=== modified file 'lib/lp/testing/factory.py'
495--- lib/lp/testing/factory.py 2010-09-09 20:12:02 +0000
496+++ lib/lp/testing/factory.py 2010-09-14 13:29:47 +0000
497@@ -182,6 +182,10 @@
498 from lp.registry.interfaces.mailinglistsubscription import (
499 MailingListAutoSubscribePolicy,
500 )
501+from lp.registry.interfaces.packaging import (
502+ IPackagingUtil,
503+ PackagingType,
504+ )
505 from lp.registry.interfaces.person import (
506 IPerson,
507 IPersonSet,
508@@ -993,6 +997,29 @@
509 removeSecurityProxy(branch).reviewer = reviewer
510 return branch
511
512+ def makePackagingLink(self, productseries=None, sourcepackagename=None,
513+ distroseries=None, packaging_type=None, owner=None,
514+ in_ubuntu=False):
515+ if productseries is None:
516+ productseries = self.makeProduct().development_focus
517+ if sourcepackagename is None or isinstance(sourcepackagename, str):
518+ sourcepackagename = self.makeSourcePackageName(sourcepackagename)
519+ if distroseries is None:
520+ distribution = None
521+ if in_ubuntu:
522+ distribution = getUtility(ILaunchpadCelebrities).ubuntu
523+ distroseries = self.makeDistroSeries(distribution=distribution)
524+ if packaging_type is None:
525+ packaging_type = PackagingType.PRIME
526+ if owner is None:
527+ owner = self.makePerson()
528+ return getUtility(IPackagingUtil).createPackaging(
529+ productseries=productseries,
530+ sourcepackagename=sourcepackagename,
531+ distroseries=distroseries,
532+ packaging=packaging_type,
533+ owner=owner)
534+
535 def makePackageBranch(self, sourcepackage=None, distroseries=None,
536 sourcepackagename=None, **kwargs):
537 """Make a package branch on an arbitrary package.
538
539=== modified file 'lib/lp/testing/menu.py'
540--- lib/lp/testing/menu.py 2010-09-12 11:43:36 +0000
541+++ lib/lp/testing/menu.py 2010-09-14 13:29:47 +0000
542@@ -11,7 +11,7 @@
543 def check_menu_links(menu):
544 context = menu.context
545 for link in menu.iterlinks():
546- if link.target.startswith('/'):
547+ if link.target.startswith(('/', 'http://')):
548 # The context is not the context of this target.
549 continue
550 if '?' in link.target: