Add the BugTracker framework and Bugzilla/JIRA bug infoboxes.

Review Request #6047 — Created July 2, 2014 and submitted

Information

Review Board
master
193
138ff8c...

Reviewers

This change adds a new interface to the hosting service app for deeper
integration with bug trackers. At the moment, this interface defines three
methods to fetch information about a given bug, which are used to provide a
hover infobox that shows the summary, description, and status.

This interface is currently implemented by the existing Bugzilla backend, and
by a new JIRA backend.

The next steps for this is to implement the interface for more bug-tracker
backends, and to start adding capabilities such that Review Board can do things
like add a comment to a bug when a review request linking to it is published.

This change is based on these changes by Tomi Äijö: * https://reviews.reviewboard.org/r/5531/ * https://reviews.reviewboard.org/r/5769/ * https://reviews.reviewboard.org/r/5745/

I've made several changes to Tomi's original implementation. The bug infobox
formatting has been cleaned up a bit, especially with regards to the formatting
of the description text. The caching steps are now done in a helper inside the
BugTracker class so we don't have to re-implement it everywhere. I've also made
it so that failures to fetch the bug result in no infobox, rather than an
infobox which just has the ID and nothing else.

  • Tested the bug infobox with a bug tracker configured to point to
    https://bugzilla.mozilla.org, and https://jira.atlassian.com. Saw that bug
    information was fetched correctly and that the infobox looked good.
  • Tested invalid bug numbers and saw that the infobox request returned 404 and
    no infobox was displayed.
  • Tested that links to existing bug trackers (Google Code, etc) worked well.
  • Tested that newly-added bugs linked correctly.
  • Ran unit tests.
Description From Last Updated

'logging' imported but unused

reviewbotreviewbot

Col: 80 E501 line too long (83 > 79 characters)

reviewbotreviewbot

'logging' imported but unused

reviewbotreviewbot

Col: 80 E501 line too long (92 > 79 characters)

reviewbotreviewbot

list comprehension redefines 'file_attachment' from line 584

reviewbotreviewbot

Is there ever a time when bug_url could be None? I would expect it to fail in that case. Also, …

chipx86chipx86

This _bug_id thing seems a bit iffy. If the bug tracker happens to have that text, we'll replace it. Can …

chipx86chipx86

Instead of all these methods, I think we should have a get_bug_info function that returns any and all detail that …

chipx86chipx86

Why not cache_memoize?

chipx86chipx86

In the past, people have complained that URLField didn't validate non-FQDN URLs. I don't know if this is still the …

chipx86chipx86

Blank line before this.

chipx86chipx86

And here.

chipx86chipx86

And here.

chipx86chipx86

We should catch exceptions here. That URL may not exist, or it may not contain what we expect.

chipx86chipx86

Same.

chipx86chipx86

No need for the variable. PyFlakes will just yell.

chipx86chipx86

Should there be a space after the '/'?

chipx86chipx86

I really don't like defining instance defaults as class members. It complicates their purpose.

chipx86chipx86

Blank line above. Same with the ones below.

chipx86chipx86

Can we move this to format_html while here?

chipx86chipx86

Blank line before.

chipx86chipx86

We're no longer explicitly returning a value if a bug tracker is not configured. We should still have a return …

chipx86chipx86

Can we pull this out into another urlpatterns in this file, so that we only have to have the bugs/... …

chipx86chipx86

list comprehension redefines 'file_attachment' from line 584

reviewbotreviewbot

You can return this directly.

chipx86chipx86

Should probably be a @cached_property

chipx86chipx86

No need for , None)

chipx86chipx86

Should be one statement.

chipx86chipx86

Should be #bug_infobox (here and where the actual element is created).

chipx86chipx86

This can be folded up into the rule above it.

chipx86chipx86

Swap these. Alphabetical order.

chipx86chipx86

I never got around to moving the old infobox into a view, but I think if we're going to introduce …

chipx86chipx86

#bug_infobox

chipx86chipx86

What's the migration plans for bug trackers containing %s? Again, I don't think we should use _bug_id as the placeholder. …

chipx86chipx86

list comprehension redefines 'file_attachment' from line 584

reviewbotreviewbot
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
  2. reviewboard/datagrids/columns.py (Diff revision 1)
     
     
    Show all issues
     'logging' imported but unused
    
  3. reviewboard/hostingsvcs/bugzilla.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (83 > 79 characters)
    
  4. reviewboard/reviews/builtin_fields.py (Diff revision 1)
     
     
    Show all issues
     'logging' imported but unused
    
  5. reviewboard/reviews/urls.py (Diff revision 1)
     
     
    Show all issues
    Col: 80
     E501 line too long (92 > 79 characters)
    
  6. reviewboard/reviews/views.py (Diff revision 1)
     
     
    Show all issues
     list comprehension redefines 'file_attachment' from line 584
    
  7. 
      
david
reviewbot
  1. Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
    
    Tool: Pyflakes
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
  2. reviewboard/reviews/views.py (Diff revision 2)
     
     
    Show all issues
     list comprehension redefines 'file_attachment' from line 584
    
  3. 
      
chipx86
  1. Much of this is probably the original code, but nonetheless, some comments.

    Really excited to finally get this in!

  2. reviewboard/datagrids/columns.py (Diff revision 2)
     
     
     
     
     
    Show all issues

    Is there ever a time when bug_url could be None? I would expect it to fail in that case.

    Also, should be local_site_reverse.

  3. reviewboard/datagrids/columns.py (Diff revision 2)
     
     
    Show all issues

    This _bug_id thing seems a bit iffy. If the bug tracker happens to have that text, we'll replace it. Can we instead just reverse on demand?

    IIRC, Django caches found URL regexes based on names, so I don't expect it'll add much overhead.

  4. reviewboard/hostingsvcs/bugtracker.py (Diff revision 2)
     
     
    Show all issues

    Instead of all these methods, I think we should have a get_bug_info function that returns any and all detail that the tracker can provide. That way there are fewer calls and fewer functions that must be implemented. It'll also be a lot easier to extend the capabilities in the future.

    We're basically doing this anyway in _get_bug. So, I'd suggest simplifing all this down to get_bug_info() and _get_bug_info_uncached().

  5. reviewboard/hostingsvcs/bugtracker.py (Diff revision 2)
     
     
     
     
     
     
     
     
    Show all issues

    Why not cache_memoize?

  6. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    In the past, people have complained that URLField didn't validate non-FQDN URLs. I don't know if this is still the case, but if so, we may want to use CharField.

  7. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    Blank line before this.

  8. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    And here.

  9. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    And here.

  10. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    We should catch exceptions here. That URL may not exist, or it may not contain what we expect.

  11. reviewboard/hostingsvcs/bugzilla.py (Diff revision 2)
     
     
    Show all issues

    Same.

  12. reviewboard/hostingsvcs/jira.py (Diff revision 2)
     
     
    Show all issues

    No need for the variable. PyFlakes will just yell.

    1. Leftover from prior debugging.

  13. reviewboard/hostingsvcs/jira.py (Diff revision 2)
     
     
    Show all issues

    Should there be a space after the '/'?

    1. rstrip treats the string as a set of characters to strip, so yes.

  14. reviewboard/hostingsvcs/jira.py (Diff revision 2)
     
     
    Show all issues

    I really don't like defining instance defaults as class members. It complicates their purpose.

  15. reviewboard/hostingsvcs/jira.py (Diff revision 2)
     
     
    Show all issues

    Blank line above. Same with the ones below.

  16. reviewboard/reviews/builtin_fields.py (Diff revision 2)
     
     
    Show all issues

    Can we move this to format_html while here?

  17. reviewboard/reviews/builtin_fields.py (Diff revision 2)
     
     
    Show all issues

    Blank line before.

  18. reviewboard/reviews/builtin_fields.py (Diff revision 2)
     
     
    Show all issues

    We're no longer explicitly returning a value if a bug tracker is not configured. We should still have a return in all cases.

    Maybe just define a bug_url = None above, set it only when we call reverse, and return it at the end? That way, only one return statement.

  19. reviewboard/reviews/urls.py (Diff revision 2)
     
     
     
     
    Show all issues

    Can we pull this out into another urlpatterns in this file, so that we only have to have the bugs/... prefix defined once? We can then just include(bugs_urlpatterns) here.

  20. reviewboard/reviews/views.py (Diff revision 2)
     
     
     
     
     
     
     
     
     
    Show all issues

    You can return this directly.

  21. reviewboard/scmtools/models.py (Diff revision 2)
     
     
     
    Show all issues

    Should probably be a @cached_property

  22. reviewboard/scmtools/models.py (Diff revision 2)
     
     
    Show all issues

    No need for , None)

  23. reviewboard/scmtools/models.py (Diff revision 2)
     
     
     
    Show all issues

    Should be one statement.

  24. reviewboard/static/rb/css/common.less (Diff revision 2)
     
     
    Show all issues

    Should be #bug_infobox (here and where the actual element is created).

  25. reviewboard/static/rb/css/common.less (Diff revision 2)
     
     
     
     
     
    Show all issues

    This can be folded up into the rule above it.

  26. reviewboard/static/rb/css/common.less (Diff revision 2)
     
     
     
     
     
     
     
     
    Show all issues

    Swap these. Alphabetical order.

  27. reviewboard/static/rb/js/common.js (Diff revision 2)
     
     
    Show all issues

    I never got around to moving the old infobox into a view, but I think if we're going to introduce a new one, we should start by making it a proper view.

    1. I think I'd like to do that as a subsequent cleanup.

    2. Works for me.

  28. reviewboard/static/rb/js/common.js (Diff revision 2)
     
     
     
     
     
    Show all issues

    #bug_infobox

  29. Show all issues

    What's the migration plans for bug trackers containing %s?

    Again, I don't think we should use _bug_id as the placeholder. If we really must, maybe __bug_id__, since that's far less likely to conflict.

    1. This no longer passes the actual bug URL to the page. Instead, it passes a URL that goes to the bug_url view, which does the actual substitution and redirects. It's pretty unlikely that _bug_id is going to be part of the reviewboard URL, but just in case, I'll make it a crazier substitution.

  30. 
      
david
reviewbot
  1. Tool: Pyflakes
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
    
    Tool: PEP8 Style Checker
    Processed Files:
        reviewboard/reviews/views.py
        reviewboard/hostingsvcs/jira.py
        reviewboard/datagrids/columns.py
        reviewboard/scmtools/models.py
        reviewboard/reviews/urls.py
        reviewboard/reviews/builtin_fields.py
        reviewboard/hostingsvcs/bugzilla.py
        setup.py
        reviewboard/hostingsvcs/bugtracker.py
    
    Ignored Files:
        reviewboard/static/rb/js/dashboard/views/dashboardView.js
        reviewboard/templates/reviews/reviewable_page_data.js
        reviewboard/static/rb/js/views/reviewRequestEditorView.js
        reviewboard/static/rb/css/common.less
        reviewboard/templates/reviews/bug_infobox.html
        reviewboard/static/rb/js/common.js
    
    
  2. reviewboard/reviews/views.py (Diff revision 3)
     
     
    Show all issues
     list comprehension redefines 'file_attachment' from line 584
    
  3. 
      
chipx86
  1. Ship It!

  2. 
      
david
Review request changed
Status:
Completed
Change Summary:
Pushed to master (aecb3a0)