[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

reportbug: support for mentors.debian.org pseudo package



package: reportbug
version: 6.2.1
severity: wishlist

Hi,

I've written a patch to tentatively support a mentors.debian.org pseudo
package (in order to better track and support the incredible volume of
sponsorship requests and such). Note that there is still ongoing
discussion about the right way to do this [0], and we would need to get
the mentors.d.o psuedo package added to the bts first anyway, but I
think the existence of this patch is needed first to illustrate the
potential usefulness of a bts-based mentors workflow.

In the meantime, would you mind reviewing the patch and determining
whether its good enough to adopt in reportbug, or if it needs some
fixing? If you do have comments, I'll do my best to address them.
Thanks!

Best wishes,
Mike

[0] http://lists.debian.org/debian-mentors/2011/09/msg00070.html
diff -Nru reportbug-6.2.1/bin/reportbug reportbug-6.2.1gilbert1/bin/reportbug
--- reportbug-6.2.1/bin/reportbug	2011-09-10 17:07:54.000000000 -0400
+++ reportbug-6.2.1gilbert1/bin/reportbug	2011-09-29 00:22:40.000000000 -0400
@@ -495,7 +495,7 @@
                 False):
                 return get_package_name(bts, mode)
 
-        if package in ('ftp.debian.org', 'release.debian.org'):
+        if package in ('ftp.debian.org', 'release.debian.org', 'mentors.debian.org'):
             if not ui.yes_no(
                 'Are you sure you want to file a bug on %s?' % (package),
                 'Yes, I am a developer or know what I\'m doing.',
@@ -1980,7 +1980,7 @@
 
         if (rtype == 'debbugs' and not self.options.tags and
             not (notatty or self.options.kudos or exinfo) and
-            package not in ('wnpp', 'ftp.debian.org', 'release.debian.org') and
+            package not in ('wnpp', 'ftp.debian.org', 'release.debian.org', 'mentors.debian.org') and
             mode > MODE_NOVICE and self.options.tagsmenu):
             tags = debbugs.get_tags(severity, mode)
 
diff -Nru reportbug-6.2.1/debian/changelog reportbug-6.2.1gilbert1/debian/changelog
--- reportbug-6.2.1/debian/changelog	2011-09-10 17:07:54.000000000 -0400
+++ reportbug-6.2.1gilbert1/debian/changelog	2011-09-29 00:16:40.000000000 -0400
@@ -1,3 +1,9 @@
+reportbug (6.2.1gilbert1) unstable; urgency=low
+
+  * Add support for mentors.debian.org pseudo package.
+
+ -- Michael Gilbert <michael.s.gilbert@gmail.com>  Thu, 29 Sep 2011 00:16:21 -0400
+
 reportbug (6.2.1) unstable; urgency=low
 
   * bin/reportbug
diff -Nru reportbug-6.2.1/reportbug/debbugs.py reportbug-6.2.1gilbert1/reportbug/debbugs.py
--- reportbug-6.2.1/reportbug/debbugs.py	2011-09-10 17:07:54.000000000 -0400
+++ reportbug-6.2.1gilbert1/reportbug/debbugs.py	2011-09-29 00:24:03.000000000 -0400
@@ -36,6 +36,7 @@
 import urllib
 import textwrap
 import pprint
+import tarfile
 # SOAP interface to Debian BTS
 import debianbts
 from collections import defaultdict
@@ -174,6 +175,7 @@
     'installation-reports' : 'Problems with installing Debian',
     'listarchives' :  'Problems with the WWW mailing list archives',
     'lists.debian.org' : 'The mailing lists, debian-*@lists.debian.org.',
+    'mentors.debian.org' : 'Requests for package mentoring and sponsorship.',
     'mirrors' : 'Problems with Debian archive mirrors.',
     'nm.debian.org' : 'New Maintainer process and nm.debian.org website',
     'press' : 'Press release issues',
@@ -383,6 +385,205 @@
 
     return (subject, severity, headers, pseudos, body, query)
 
+def handle_debian_mentors(package, bts, ui, fromaddr, timeout, online=True, http_proxy=None):
+    tag = ui.menu('What sort of request is this? (if you are trying to report a bug '
+                  'in an existing package, please press Enter to exit reportbug)', {
+        'new':              "a sponsorship request for a brand new package",
+        'update':           "a sponsorship request for an update to a package you've gotten sponsored and uploaded previously",
+        'release-critical': "a sponsorship request for a package fixing a release-critical bug",
+        'proposed-update':  "a sponsorship request for a proposed-update to stable/oldstable",
+        'nmu':              "a sponsorship request for a non-maintainer upload to unstable",
+        'security':         "a sponsorship request for a package fixing a security issue",
+        'backport':         "a sponsorship request for a backport to stable/oldstable",
+        'other' :           "none of the other options",
+        }, 'Choose the request type: ', empty_ok=True)
+    if not tag:
+        ui.long_message('To report a bug in a package, please use the name of the '
+            + 'package, not mentors.debian.org.\n')
+        raise SystemExit
+
+    severity = 'normal'
+    if tag == 'other':
+        return
+
+    query = False
+    package = ui.get_string('Please enter the name of the package: ')
+    if not package:
+        ui.log_message('Writing a generic bug report.\n')
+        return
+
+    # make sure package is already in the archive if this is one of the update options
+    if tag != 'new':
+        info = utils.get_source_package(package)
+        if info:
+            info = utils.get_package_status(info[0][0])
+        if not info:
+            ui.long_message( 'Package \'%s\' doesn\'t currently exist in ' % package \
+                    + 'the Debian archive; you probably want to select \'new\' ' \
+                    + 'for the request type.')
+            sys.exit(1)
+
+    # initial values in case something goes wrong
+    fname = '[your'
+    lname = 'name]'
+    author = '[fill in name and email of upstream]'
+    homepage = '[fill in url of upstream\'s web site]'
+    license = '[fill in license of upstream code]'
+    section = '[fill in debian package section]'
+
+    # collect info on this package from its mentors page
+    isdep5 = False
+    mentorsok = False
+    if online:
+        mentors = urllib.urlopen('http://mentors.debian.net/package/%s' % package)
+        mentorsinfo = re.sub(r'<.*?>', '', mentors.read()).split()
+        mentors.close()
+
+        try:
+            fname = mentorsinfo[mentorsinfo.index('Uploader:')+1]
+            lname = mentorsinfo[mentorsinfo.index('Uploader:')+2]
+            version = mentorsinfo[mentorsinfo.index('Version:')+1]
+            section = mentorsinfo[mentorsinfo.index('Section:')+1]
+            dscurl = mentorsinfo[mentorsinfo.index('package:')+1]
+            mentorsok = True
+        except ValueError:
+            pass
+
+    # move on to processing the package's .dsc
+    if not mentorsok:
+        version = ui.get_string('Please enter the version of the package: ')
+        if not version:
+            ui.log_message("A version number is required, not sending report\n")
+            sys.exit(1)
+
+        # NOTE: not very robust, but we just want a placeholder when mentors not available
+        dscurl = 'http://http://mentors.debian.net/debian/pool/main/%s/%s_%s.dsc' % \
+                (package[0], package, version)
+    else:
+        dsc = urllib.urlopen(dscurl)
+        dscinfo = dsc.read().split()
+        dsc.close()
+
+        homepage = dscinfo[dscinfo.index('Homepage:')+1]
+        pformat = dscinfo[dscinfo.index('Format:')+1]
+        tarname = dscinfo[dscinfo.index('Files:')+6]
+
+        # download and extract the package's debian/copyright to get licensing info
+        if pformat == '3.0':
+            tarpath,httplib = urllib.urlretrieve(os.path.join(os.path.dirname(dscurl), \
+                    tarname))
+            tar = tarfile.open(tarpath)
+            copyright = tar.extractfile( tar.getmember( 'debian/copyright' ) )
+            copyinfo = copyright.readlines()
+            copyright.close()
+            os.remove(tarpath)
+
+            authors = []
+            licenses = []
+            for line in copyinfo:
+                if line.startswith('Format:'):
+                    isdep5 = line.lower().find( 'dep5' ) >= 0
+                if line.startswith('Copyright:') and line.find(lname) < 0 \
+                        and line.find(fname) < 0:
+                    authors.append( ' '.join(line.strip('\n').split()[1::]))
+                if line.startswith('License:'):
+                    lic = ' '.join( line.strip('\n').split()[1::] )
+                    if lic not in licenses:
+                        licenses.append( lic )
+            if isdep5:
+                license = ', '.join( licenses)
+                author = '\n              '.join( authors )
+
+    # select additional teams to carbon-copy on this report
+    headers = []
+    if section == 'games':
+        headers.append('X-Debbugs-CC: debian-devel-games@lists.debian.org')
+    if section == 'java':
+        headers.append('X-Debbugs-CC: debian-java@lists.debian.org')
+    if section == 'perl':
+        headers.append('X-Debbugs-CC: debian-perl@lists.debian.org')
+    if section == 'python':
+        headers.append('X-Debbugs-CC: debian-python@lists.debian.org')
+    if section == 'python':
+        headers.append('X-Debbugs-CC: debian-haskell@lists.debian.org')
+    if section == 'ruby':
+        headers.append('X-Debbugs-CC: debian-ruby@lists.debian.org')
+    if section == 'science' or section == 'math':
+        headers.append('X-Debbugs-CC: debian-science@lists.debian.org')
+    if section == 'gnome':
+        headers.append('X-Debbugs-CC: debian-gtk-gnome@lists.debian.org')
+    if section == 'kde':
+        headers.append('X-Debbugs-CC: debian-kde@lists.debian.org')
+    if section == 'tex':
+        headers.append('X-Debbugs-CC: debian-tex-maint@lists.debian.org')
+    if section == 'hamradio':
+        headers.append('X-Debbugs-CC: debian-hams@lists.debian.org')
+    if section == 'embedded':
+        headers.append('X-Debbugs-CC: debian-embedded@lists.debian.org')
+    if section == 'php':
+        headers.append('X-Debbugs-CC: pkg-php-maint@lists.alioth.debian.org')
+    if section == 'fonts':
+        headers.append('X-Debbugs-CC: pkg-fonts-devel@lists.alioth.debian.org')
+    if tag == 'release-critical' or tag == 'proposed-update':
+        headers.append('X-Debbugs-CC: debian-release@lists.debian.org')
+    if tag == 'security':
+        headers.append('X-Debbugs-CC: debian-security@lists.debian.org')
+    if tag == 'backport':
+        headers.append('X-Debbugs-CC: debian-backports@lists.debian.org')
+
+    # fill in the report template
+    pseudos = []
+    pseudos.append('User: mentors.debian.org@packages.debian.org')
+    pseudos.append('Usertags: %s' % tag)
+    subject = 'request for sponsorship (%s): package %s/%s' % (tag, package, version)
+    body = 'Dear mentors,\n\n'
+    body += 'I am requesting sponsorship for '
+
+    if tag == 'new':
+        body += 'a package that is new to the Debian archive:'
+    elif tag == 'update':
+        body += 'an update to a package that I\'ve gotten\n'
+        body += 'sponsored and uploaded previously:'
+    elif tag == 'release-critical':
+        body += 'a package that fixes a release-critical issue:'
+    elif tag == 'proposed-update':
+        body += 'a package that is a proposed-update for the\n'
+        body += 'stable/oldstable release:'
+    elif tag == 'nmu':
+        body += 'a non-maintainer upload of an existing Debian\n'
+        body += 'package:'
+    elif tag == 'security': 
+        body += 'a package that fixes a security issue:'
+    elif tag == 'backport':
+        body += 'a testing package that I\'ve backported to the\n'
+        body += 'stable/oldstable release:'
+    body += '\n\n'
+
+    if not mentorsok:
+        body += '    [reportbug was unable to find package \'%s\' on mentors.debian.net\n' % package
+        body += '    (or you\'re currently offline); if your work were available there,\n'
+        body += '    reportbug could have completed all of this report automatically]\n\n'
+    body += '    Package : %s\n' % package
+    body += '    Version : %s\n' % version
+    body += '    Section : %s\n' % section
+    body += '    URL     : %s\n' % homepage
+    body += '    License : %s\n' % license
+    body += '    Authors : %s\n' % author
+    if mentorsok and not isdep5:
+        body += '    [If your package were using the dep5 copyright file format, reportbug\n'
+        body += '    could have automatically populated authorship info for you]\n'
+    body += '\nFor more information, please visit the mentors URL or download the package\n'
+    body += 'via dget:\n\n'
+    if not mentorsok:
+        body += '    [make sure the following information is correct]\n'
+    body += '    http://mentors.debian.net/package/%s\n' % package
+    body += '    dget -x %s\n\n' % dscurl
+    body += 'Thank you very much for your guidance, support, and assistance with this\n'
+    body += 'modest contribution to the Debian ecosystem.\n\n' 
+    body += 'Kindest regards,\n'
+    body += '%s %s\n' % (fname, lname)
+
+    return (subject, severity, headers, pseudos, body, query)
 
 def handle_debian_release(package, bts, ui, fromaddr, timeout, online=True, http_proxy=None):
     body = ''
@@ -674,7 +875,8 @@
               'specials' :
                 { 'wnpp': handle_wnpp,
                   'ftp.debian.org': handle_debian_ftp,
-                  'release.debian.org': handle_debian_release },
+                  'release.debian.org': handle_debian_release,
+                  'mentors.debian.org': handle_debian_mentors },
               # Dependency packages
               'deppkgs' : ('gcc', 'g++', 'cpp', 'gcj', 'gpc', 'gobjc',
                            'chill', 'gij', 'g77', 'python', 'python-base',

Reply to: