mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 16:06:08 +00:00

This is an ongoing series of commits that are reformatting our Python code. Reformatting is done with `black`. If you end up having problems merging this commit because you have made changes to a python file, the best way to handle that is to run git checkout --ours <yourfile> and then reformat it with black. If you run into any problems, post to discourse about it and we will try to help. RFC Thread below: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D150761
227 lines
6.1 KiB
Python
227 lines
6.1 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""Methods for reporting bugs."""
|
|
|
|
import subprocess, sys, os
|
|
|
|
__all__ = ["ReportFailure", "BugReport", "getReporters"]
|
|
|
|
#
|
|
|
|
|
|
class ReportFailure(Exception):
|
|
"""Generic exception for failures in bug reporting."""
|
|
|
|
def __init__(self, value):
|
|
self.value = value
|
|
|
|
|
|
# Collect information about a bug.
|
|
|
|
|
|
class BugReport(object):
|
|
def __init__(self, title, description, files):
|
|
self.title = title
|
|
self.description = description
|
|
self.files = files
|
|
|
|
|
|
# Reporter interfaces.
|
|
|
|
import os
|
|
|
|
import email, mimetypes, smtplib
|
|
from email import encoders
|
|
from email.message import Message
|
|
from email.mime.base import MIMEBase
|
|
from email.mime.multipart import MIMEMultipart
|
|
from email.mime.text import MIMEText
|
|
|
|
# ===------------------------------------------------------------------------===#
|
|
# ReporterParameter
|
|
# ===------------------------------------------------------------------------===#
|
|
|
|
|
|
class ReporterParameter(object):
|
|
def __init__(self, n):
|
|
self.name = n
|
|
|
|
def getName(self):
|
|
return self.name
|
|
|
|
def getValue(self, r, bugtype, getConfigOption):
|
|
return getConfigOption(r.getName(), self.getName())
|
|
|
|
def saveConfigValue(self):
|
|
return True
|
|
|
|
|
|
class TextParameter(ReporterParameter):
|
|
def getHTML(self, r, bugtype, getConfigOption):
|
|
return """\
|
|
<tr>
|
|
<td class="form_clabel">%s:</td>
|
|
<td class="form_value"><input type="text" name="%s_%s" value="%s"></td>
|
|
</tr>""" % (
|
|
self.getName(),
|
|
r.getName(),
|
|
self.getName(),
|
|
self.getValue(r, bugtype, getConfigOption),
|
|
)
|
|
|
|
|
|
class SelectionParameter(ReporterParameter):
|
|
def __init__(self, n, values):
|
|
ReporterParameter.__init__(self, n)
|
|
self.values = values
|
|
|
|
def getHTML(self, r, bugtype, getConfigOption):
|
|
default = self.getValue(r, bugtype, getConfigOption)
|
|
return """\
|
|
<tr>
|
|
<td class="form_clabel">%s:</td><td class="form_value"><select name="%s_%s">
|
|
%s
|
|
</select></td>""" % (
|
|
self.getName(),
|
|
r.getName(),
|
|
self.getName(),
|
|
"\n".join(
|
|
[
|
|
"""\
|
|
<option value="%s"%s>%s</option>"""
|
|
% (o[0], o[0] == default and ' selected="selected"' or "", o[1])
|
|
for o in self.values
|
|
]
|
|
),
|
|
)
|
|
|
|
|
|
# ===------------------------------------------------------------------------===#
|
|
# Reporters
|
|
# ===------------------------------------------------------------------------===#
|
|
|
|
|
|
class EmailReporter(object):
|
|
def getName(self):
|
|
return "Email"
|
|
|
|
def getParameters(self):
|
|
return [TextParameter(x) for x in ["To", "From", "SMTP Server", "SMTP Port"]]
|
|
|
|
# Lifted from python email module examples.
|
|
def attachFile(self, outer, path):
|
|
# Guess the content type based on the file's extension. Encoding
|
|
# will be ignored, although we should check for simple things like
|
|
# gzip'd or compressed files.
|
|
ctype, encoding = mimetypes.guess_type(path)
|
|
if ctype is None or encoding is not None:
|
|
# No guess could be made, or the file is encoded (compressed), so
|
|
# use a generic bag-of-bits type.
|
|
ctype = "application/octet-stream"
|
|
maintype, subtype = ctype.split("/", 1)
|
|
if maintype == "text":
|
|
fp = open(path)
|
|
# Note: we should handle calculating the charset
|
|
msg = MIMEText(fp.read(), _subtype=subtype)
|
|
fp.close()
|
|
else:
|
|
fp = open(path, "rb")
|
|
msg = MIMEBase(maintype, subtype)
|
|
msg.set_payload(fp.read())
|
|
fp.close()
|
|
# Encode the payload using Base64
|
|
encoders.encode_base64(msg)
|
|
# Set the filename parameter
|
|
msg.add_header(
|
|
"Content-Disposition", "attachment", filename=os.path.basename(path)
|
|
)
|
|
outer.attach(msg)
|
|
|
|
def fileReport(self, report, parameters):
|
|
mainMsg = """\
|
|
BUG REPORT
|
|
---
|
|
Title: %s
|
|
Description: %s
|
|
""" % (
|
|
report.title,
|
|
report.description,
|
|
)
|
|
|
|
if not parameters.get("To"):
|
|
raise ReportFailure('No "To" address specified.')
|
|
if not parameters.get("From"):
|
|
raise ReportFailure('No "From" address specified.')
|
|
|
|
msg = MIMEMultipart()
|
|
msg["Subject"] = "BUG REPORT: %s" % (report.title)
|
|
# FIXME: Get config parameters
|
|
msg["To"] = parameters.get("To")
|
|
msg["From"] = parameters.get("From")
|
|
msg.preamble = mainMsg
|
|
|
|
msg.attach(MIMEText(mainMsg, _subtype="text/plain"))
|
|
for file in report.files:
|
|
self.attachFile(msg, file)
|
|
|
|
try:
|
|
s = smtplib.SMTP(
|
|
host=parameters.get("SMTP Server"), port=parameters.get("SMTP Port")
|
|
)
|
|
s.sendmail(msg["From"], msg["To"], msg.as_string())
|
|
s.close()
|
|
except:
|
|
raise ReportFailure("Unable to send message via SMTP.")
|
|
|
|
return "Message sent!"
|
|
|
|
|
|
class BugzillaReporter(object):
|
|
def getName(self):
|
|
return "Bugzilla"
|
|
|
|
def getParameters(self):
|
|
return [TextParameter(x) for x in ["URL", "Product"]]
|
|
|
|
def fileReport(self, report, parameters):
|
|
raise NotImplementedError
|
|
|
|
|
|
class RadarClassificationParameter(SelectionParameter):
|
|
def __init__(self):
|
|
SelectionParameter.__init__(
|
|
self,
|
|
"Classification",
|
|
[
|
|
["1", "Security"],
|
|
["2", "Crash/Hang/Data Loss"],
|
|
["3", "Performance"],
|
|
["4", "UI/Usability"],
|
|
["6", "Serious Bug"],
|
|
["7", "Other"],
|
|
],
|
|
)
|
|
|
|
def saveConfigValue(self):
|
|
return False
|
|
|
|
def getValue(self, r, bugtype, getConfigOption):
|
|
if bugtype.find("leak") != -1:
|
|
return "3"
|
|
elif bugtype.find("dereference") != -1:
|
|
return "2"
|
|
elif bugtype.find("missing ivar release") != -1:
|
|
return "3"
|
|
else:
|
|
return "7"
|
|
|
|
|
|
###
|
|
|
|
|
|
def getReporters():
|
|
reporters = []
|
|
reporters.append(EmailReporter())
|
|
return reporters
|