| # |
| # Copyright (C) 2005, 2007 The Trustees of Indiana University |
| # Author: Douglas Gregor |
| # |
| # Distributed under the Boost Software License, Version 1.0. (See |
| # accompanying file LICENSE_1_0.txt or copy at |
| # http://www.boost.org/LICENSE_1_0.txt) |
| # |
| import re |
| import smtplib |
| import os |
| import time |
| import string |
| import datetime |
| import sys |
| |
| report_author = "Douglas Gregor <dgregor@osl.iu.edu>" |
| boost_dev_list = "Boost Developer List <boost@lists.boost.org>" |
| boost_testing_list = "Boost Testing List <boost-testing@lists.boost.org>" |
| |
| def sorted_keys( dict ): |
| result = dict.keys() |
| result.sort() |
| return result |
| |
| |
| class Platform: |
| """ |
| All of the failures for a particular platform. |
| """ |
| def __init__(self, name): |
| self.name = name |
| self.failures = list() |
| self.maintainers = list() |
| return |
| |
| def addFailure(self, failure): |
| self.failures.append(failure) |
| return |
| |
| def isBroken(self): |
| return len(self.failures) > 300 |
| |
| def addMaintainer(self, maintainer): |
| """ |
| Add a new maintainer for this platform. |
| """ |
| self.maintainers.append(maintainer) |
| return |
| |
| class Failure: |
| """ |
| A single test case failure in the report. |
| """ |
| def __init__(self, test, platform): |
| self.test = test |
| self.platform = platform |
| return |
| |
| class Test: |
| """ |
| All of the failures for a single test name within a library. |
| """ |
| def __init__(self, library, name): |
| self.library = library |
| self.name = name |
| self.failures = list() |
| return |
| |
| def addFailure(self, failure): |
| self.failures.append(failure) |
| return |
| |
| def numFailures(self): |
| return len(self.failures) |
| |
| def numReportableFailures(self): |
| """ |
| Returns the number of failures that we will report to the |
| maintainers of the library. This doesn't count failures on |
| broken platforms. |
| """ |
| count = 0 |
| for failure in self.failures: |
| if not failure.platform.isBroken(): |
| count += 1 |
| pass |
| pass |
| return count |
| |
| class Library: |
| """ |
| All of the information about the failures in a single library. |
| """ |
| def __init__(self, name): |
| self.name = name |
| self.maintainers = list() |
| self.tests = list() |
| return |
| |
| def addTest(self, test): |
| """ |
| Add another test to the library. |
| """ |
| self.tests.append(test) |
| return |
| |
| def addMaintainer(self, maintainer): |
| """ |
| Add a new maintainer for this library. |
| """ |
| self.maintainers.append(maintainer) |
| return |
| |
| def numFailures(self): |
| count = 0 |
| for test in self.tests: |
| count += test.numFailures() |
| pass |
| return count |
| |
| def numReportableFailures(self): |
| count = 0 |
| for test in self.tests: |
| count += test.numReportableFailures() |
| pass |
| return count |
| |
| class Maintainer: |
| """ |
| Information about the maintainer of a library |
| """ |
| def __init__(self, name, email): |
| self.name = name |
| self.email = email |
| self.libraries = list() |
| return |
| |
| def addLibrary(self, library): |
| self.libraries.append(library) |
| return |
| |
| def composeEmail(self, report): |
| """ |
| Composes an e-mail to this maintainer with information about |
| the failures in his or her libraries, omitting those that come |
| from "broken" platforms. Returns the e-mail text if a message |
| needs to be sent, or None otherwise. |
| """ |
| |
| # Determine if we need to send a message to this developer. |
| requires_message = False |
| for library in self.libraries: |
| if library.numReportableFailures() > 0: |
| requires_message = True |
| break |
| |
| if not requires_message: |
| return None |
| |
| # Build the message header |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: """ |
| message += self.name + ' <' + self.email + '>' |
| message += """ |
| Reply-To: boost@lists.boost.org |
| Subject: Failures in your Boost libraries as of """ |
| message += str(datetime.date.today()) + " [" + report.branch + "]" |
| message += """ |
| |
| You are receiving this report because one or more of the libraries you |
| maintain has regression test failures that are not accounted for. |
| A full version of the report is sent to the Boost developer's mailing |
| list. |
| |
| Detailed report: |
| """ |
| message += ' ' + report.url + """ |
| |
| There are failures in these libraries you maintain: |
| """ |
| |
| # List the libraries this maintainer is responsible for and |
| # the number of reportable failures in that library. |
| for library in self.libraries: |
| num_failures = library.numReportableFailures() |
| if num_failures > 0: |
| message += ' ' + library.name + ' (' + str(num_failures) + ')\n' |
| pass |
| pass |
| |
| # Provide the details for the failures in each library. |
| for library in self.libraries: |
| if library.numReportableFailures() > 0: |
| message += '\n|' + library.name + '|\n' |
| for test in library.tests: |
| if test.numReportableFailures() > 0: |
| message += ' ' + test.name + ':' |
| for failure in test.failures: |
| if not failure.platform.isBroken(): |
| message += ' ' + failure.platform.name |
| pass |
| pass |
| message += '\n' |
| pass |
| pass |
| pass |
| pass |
| |
| return message |
| |
| class PlatformMaintainer: |
| """ |
| Information about the platform maintainer of a library |
| """ |
| def __init__(self, name, email): |
| self.name = name |
| self.email = email |
| self.platforms = list() |
| return |
| |
| def addPlatform(self, runner, platform): |
| self.platforms.append(platform) |
| return |
| |
| def composeEmail(self, report): |
| """ |
| Composes an e-mail to this platform maintainer if one or more of |
| the platforms s/he maintains has a large number of failures. |
| Returns the e-mail text if a message needs to be sent, or None |
| otherwise. |
| """ |
| |
| # Determine if we need to send a message to this developer. |
| requires_message = False |
| for platform in self.platforms: |
| if platform.isBroken(): |
| requires_message = True |
| break |
| |
| if not requires_message: |
| return None |
| |
| # Build the message header |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: """ |
| message += self.name + ' <' + self.email + '>' |
| message += """ |
| Reply-To: boost@lists.boost.org |
| Subject: Large number of Boost failures on a platform you maintain as of """ |
| message += str(datetime.date.today()) + " [" + report.branch + "]" |
| message += """ |
| |
| You are receiving this report because one or more of the testing |
| platforms that you maintain has a large number of Boost failures that |
| are not accounted for. A full version of the report is sent to the |
| Boost developer's mailing list. |
| |
| Detailed report: |
| """ |
| message += ' ' + report.url + """ |
| |
| The following platforms have a large number of failures: |
| """ |
| |
| for platform in self.platforms: |
| if platform.isBroken(): |
| message += (' ' + platform.name + ' (' |
| + str(len(platform.failures)) + ' failures)\n') |
| |
| return message |
| |
| class Report: |
| """ |
| The complete report of all failing test cases. |
| """ |
| def __init__(self, branch = 'trunk'): |
| self.branch = branch |
| self.date = None |
| self.url = None |
| self.libraries = dict() |
| self.platforms = dict() |
| self.maintainers = dict() |
| self.platform_maintainers = dict() |
| return |
| |
| def getPlatform(self, name): |
| """ |
| Retrieve the platform with the given name. |
| """ |
| if self.platforms.has_key(name): |
| return self.platforms[name] |
| else: |
| self.platforms[name] = Platform(name) |
| return self.platforms[name] |
| |
| def getMaintainer(self, name, email): |
| """ |
| Retrieve the maintainer with the given name and e-mail address. |
| """ |
| if self.maintainers.has_key(name): |
| return self.maintainers[name] |
| else: |
| self.maintainers[name] = Maintainer(name, email) |
| return self.maintainers[name] |
| |
| def getPlatformMaintainer(self, name, email): |
| """ |
| Retrieve the platform maintainer with the given name and |
| e-mail address. |
| """ |
| if self.platform_maintainers.has_key(name): |
| return self.platform_maintainers[name] |
| else: |
| self.platform_maintainers[name] = PlatformMaintainer(name, email) |
| return self.platform_maintainers[name] |
| |
| def parseIssuesEmail(self): |
| """ |
| Try to parse the issues e-mail file. Returns True if everything was |
| successful, false otherwise. |
| """ |
| # See if we actually got the file |
| if not os.path.isfile('issues-email.txt'): |
| return False |
| |
| # Determine the set of libraries that have unresolved failures |
| date_regex = re.compile('Report time: (.*)') |
| url_regex = re.compile(' (http://.*)') |
| library_regex = re.compile('\|(.*)\|') |
| failure_regex = re.compile(' ([^:]*): (.*)') |
| current_library = None |
| for line in file('issues-email.txt', 'r'): |
| # Check for the report time line |
| m = date_regex.match(line) |
| if m: |
| self.date = m.group(1) |
| continue |
| |
| # Check for the detailed report URL |
| m = url_regex.match(line) |
| if m: |
| self.url = m.group(1) |
| continue |
| |
| # Check for a library header |
| m = library_regex.match(line) |
| if m: |
| current_library = Library(m.group(1)) |
| self.libraries[m.group(1)] = current_library |
| continue |
| |
| # Check for a library test and its failures |
| m = failure_regex.match(line) |
| if m: |
| test = Test(current_library, m.group(1)) |
| for platform_name in re.split('\s*', m.group(2)): |
| if platform_name != '': |
| platform = self.getPlatform(platform_name) |
| failure = Failure(test, platform) |
| test.addFailure(failure) |
| platform.addFailure(failure) |
| pass |
| current_library.addTest(test) |
| continue |
| pass |
| |
| return True |
| |
| def getIssuesEmail(self): |
| """ |
| Retrieve the issues email from beta.boost.org, trying a few |
| times in case something wonky is happening. If we can retrieve |
| the file, calls parseIssuesEmail and return True; otherwise, |
| return False. |
| """ |
| base_url = "http://beta.boost.org/development/tests/" |
| base_url += self.branch |
| base_url += "/developer/"; |
| got_issues = False |
| |
| # Ping the server by looking for an HTML file |
| print "Pinging the server to initiate extraction..." |
| ping_url = base_url + "issues.html" |
| os.system('curl -O ' + ping_url) |
| os.system('rm -f issues.html') |
| |
| for x in range(30): |
| # Update issues-email.txt |
| url = base_url + "issues-email.txt" |
| print 'Retrieving issues email from ' + url |
| os.system('rm -f issues-email.txt') |
| os.system('curl -O ' + url) |
| |
| if self.parseIssuesEmail(): |
| return True |
| |
| print 'Failed to fetch issues email. ' |
| time.sleep (30) |
| |
| return False |
| |
| # Parses the file $BOOST_ROOT/libs/maintainers.txt to create a hash |
| # mapping from the library name to the list of maintainers. |
| def parseLibraryMaintainersFile(self): |
| """ |
| Parse the maintainers file in ../../../libs/maintainers.txt to |
| collect information about the maintainers of broken libraries. |
| """ |
| lib_maintainer_regex = re.compile('(\S+)\s*(.*)') |
| name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>') |
| at_regex = re.compile('\s*-\s*at\s*-\s*') |
| for line in file('../../../libs/maintainers.txt', 'r'): |
| if line.startswith('#'): |
| continue |
| m = lib_maintainer_regex.match (line) |
| if m: |
| libname = m.group(1) |
| if self.libraries.has_key(m.group(1)): |
| library = self.libraries[m.group(1)] |
| for person in re.split('\s*,\s*', m.group(2)): |
| nmm = name_email_regex.match(person) |
| if nmm: |
| name = nmm.group(1) |
| email = nmm.group(3) |
| email = at_regex.sub('@', email) |
| maintainer = self.getMaintainer(name, email) |
| maintainer.addLibrary(library) |
| library.addMaintainer(maintainer) |
| pass |
| pass |
| pass |
| pass |
| pass |
| pass |
| |
| # Parses the file $BOOST_ROOT/libs/platform_maintainers.txt to |
| # create a hash mapping from the platform name to the list of |
| # maintainers. |
| def parsePlatformMaintainersFile(self): |
| """ |
| Parse the platform maintainers file in |
| ../../../libs/platform_maintainers.txt to collect information |
| about the maintainers of the various platforms. |
| """ |
| platform_maintainer_regex = re.compile('([A-Za-z0-9_.-]*|"[^"]*")\s+(\S+)\s+(.*)') |
| name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>') |
| at_regex = re.compile('\s*-\s*at\s*-\s*') |
| for line in file('../../../libs/platform_maintainers.txt', 'r'): |
| if line.startswith('#'): |
| continue |
| m = platform_maintainer_regex.match (line) |
| if m: |
| platformname = m.group(2) |
| if self.platforms.has_key(platformname): |
| platform = self.platforms[platformname] |
| for person in re.split('\s*,\s*', m.group(3)): |
| nmm = name_email_regex.match(person) |
| if nmm: |
| name = nmm.group(1) |
| email = nmm.group(3) |
| email = at_regex.sub('@', email) |
| maintainer = self.getPlatformMaintainer(name, email) |
| maintainer.addPlatform(m.group(1), platform) |
| platform.addMaintainer(maintainer) |
| pass |
| pass |
| pass |
| pass |
| pass |
| |
| def numFailures(self): |
| count = 0 |
| for library in self.libraries: |
| count += self.libraries[library].numFailures() |
| pass |
| return count |
| |
| def numReportableFailures(self): |
| count = 0 |
| for library in self.libraries: |
| count += self.libraries[library].numReportableFailures() |
| pass |
| return count |
| |
| def composeSummaryEmail(self): |
| """ |
| Compose a message to send to the Boost developer's |
| list. Return the message and return it. |
| """ |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: boost@lists.boost.org |
| Reply-To: boost@lists.boost.org |
| Subject: [Report] """ |
| message += str(self.numFailures()) + " failures on " + branch |
| if branch != 'trunk': |
| message += ' branch' |
| message += " (" + str(datetime.date.today()) + ")" |
| message += """ |
| |
| Boost regression test failures |
| """ |
| message += "Report time: " + self.date + """ |
| |
| This report lists all regression test failures on high-priority platforms. |
| |
| Detailed report: |
| """ |
| |
| message += ' ' + self.url + '\n\n' |
| |
| if self.numFailures() == 0: |
| message += "No failures! Yay!\n" |
| return message |
| |
| # List the platforms that are broken |
| any_broken_platforms = self.numReportableFailures() < self.numFailures() |
| if any_broken_platforms: |
| message += """The following platforms have a large number of failures: |
| """ |
| for platform in sorted_keys( self.platforms ): |
| if self.platforms[platform].isBroken(): |
| message += (' ' + platform + ' (' |
| + str(len(self.platforms[platform].failures)) |
| + ' failures)\n') |
| |
| message += """ |
| Failures on these "broken" platforms will be omitted from the results below. |
| Please see the full report for information about these failures. |
| |
| """ |
| |
| # Display the number of failures |
| message += (str(self.numReportableFailures()) + ' failures in ' + |
| str(len(self.libraries)) + ' libraries') |
| if any_broken_platforms: |
| message += (' (plus ' + str(self.numFailures() - self.numReportableFailures()) |
| + ' from broken platforms)') |
| |
| message += '\n' |
| |
| # Display the number of failures per library |
| for k in sorted_keys( self.libraries ): |
| library = self.libraries[k] |
| num_failures = library.numFailures() |
| message += ' ' + library.name + ' (' |
| |
| if library.numReportableFailures() > 0: |
| message += (str(library.numReportableFailures()) |
| + " failures") |
| |
| if library.numReportableFailures() < num_failures: |
| if library.numReportableFailures() > 0: |
| message += ', plus ' |
| |
| message += (str(num_failures-library.numReportableFailures()) |
| + ' failures on broken platforms') |
| message += ')\n' |
| pass |
| |
| message += '\n' |
| |
| # Provide the details for the failures in each library. |
| for k in sorted_keys( self.libraries ): |
| library = self.libraries[k] |
| if library.numReportableFailures() > 0: |
| message += '\n|' + library.name + '|\n' |
| for test in library.tests: |
| if test.numReportableFailures() > 0: |
| message += ' ' + test.name + ':' |
| for failure in test.failures: |
| platform = failure.platform |
| if not platform.isBroken(): |
| message += ' ' + platform.name |
| message += '\n' |
| |
| return message |
| |
| def composeTestingSummaryEmail(self): |
| """ |
| Compose a message to send to the Boost Testing list. Returns |
| the message text if a message is needed, returns None |
| otherwise. |
| """ |
| brokenPlatforms = 0 |
| for platform in sorted_keys( self.platforms ): |
| if self.platforms[platform].isBroken(): |
| brokenPlatforms = brokenPlatforms + 1 |
| |
| if brokenPlatforms == 0: |
| return None; |
| |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: boost-testing@lists.boost.org |
| Reply-To: boost-testing@lists.boost.org |
| Subject: [Report] """ |
| message += str(brokenPlatforms) + " potentially broken platforms on " + branch |
| if branch != 'trunk': |
| message += ' branch' |
| message += " (" + str(datetime.date.today()) + ")" |
| message += """ |
| |
| Potentially broken platforms for Boost regression testing |
| """ |
| message += "Report time: " + self.date + """ |
| |
| This report lists the high-priority platforms that are exhibiting a |
| large number of regression test failures, which might indicate a problem |
| with the test machines or testing harness. |
| |
| Detailed report: |
| """ |
| |
| message += ' ' + self.url + '\n' |
| |
| message += """ |
| Platforms with a large number of failures: |
| """ |
| for platform in sorted_keys( self.platforms ): |
| if self.platforms[platform].isBroken(): |
| message += (' ' + platform + ' (' |
| + str(len(self.platforms[platform].failures)) |
| + ' failures)\n') |
| |
| return message |
| |
| # Send a message to "person" (a maintainer of a library that is |
| # failing). |
| # maintainers is the result of get_library_maintainers() |
| def send_individualized_message (branch, person, maintainers): |
| # There are several states we could be in: |
| # 0 Initial state. Eat everything up to the "NNN failures in MMM |
| # libraries" line |
| # 1 Suppress output within this library |
| # 2 Forward output within this library |
| state = 0 |
| |
| failures_in_lib_regex = re.compile('\d+ failur.*\d+ librar') |
| lib_failures_regex = re.compile(' (\S+) \((\d+)\)') |
| lib_start_regex = re.compile('\|(\S+)\|') |
| general_pass_regex = re.compile(' http://') |
| for line in file('issues-email.txt', 'r'): |
| if state == 0: |
| lfm = lib_failures_regex.match(line) |
| if lfm: |
| # Pass the line through if the current person is a |
| # maintainer of this library |
| if lfm.group(1) in maintainers and person in maintainers[lfm.group(1)]: |
| message += line |
| print line, |
| |
| elif failures_in_lib_regex.match(line): |
| message += "\nThere are failures in these libraries you maintain:\n" |
| elif general_pass_regex.match(line): |
| message += line |
| |
| lib_start = lib_start_regex.match(line) |
| if lib_start: |
| if state == 0: |
| message += '\n' |
| |
| if lib_start.group(1) in maintainers and person in maintainers[lib_start.group(1)]: |
| message += line |
| state = 2 |
| else: |
| state = 1 |
| else: |
| if state == 1: |
| pass |
| elif state == 2: |
| message += line |
| |
| if '--debug' in sys.argv: |
| print '-----------------Message text----------------' |
| print message |
| else: |
| print |
| |
| if '--send' in sys.argv: |
| print "Sending..." |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = 'Douglas Gregor <dgregor@osl.iu.edu>', |
| to_addrs = person[1], |
| msg = message) |
| print "Done." |
| |
| |
| # Send a message to the developer's list |
| def send_boost_developers_message(branch, maintainers, failing_libraries): |
| to_line = 'boost@lists.boost.org' |
| from_line = 'Douglas Gregor <dgregor@osl.iu.edu>' |
| |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: boost@lists.boost.org |
| Reply-To: boost@lists.boost.org |
| Subject: Boost regression testing notification (""" |
| |
| message += str(datetime.date.today()) + " [" + branch + "]" |
| message += ")" |
| |
| message += """ |
| |
| """ |
| |
| for line in file('issues-email.txt', 'r'): |
| # Right before the detailed report, put out a warning message if |
| # any libraries with failures to not have maintainers listed. |
| if line.startswith('Detailed report:'): |
| missing_maintainers = False |
| for lib in failing_libraries: |
| if not(lib in maintainers) or maintainers[lib] == list(): |
| missing_maintainers = True |
| |
| if missing_maintainers: |
| message += """WARNING: The following libraries have failing regression tests but do |
| not have a maintainer on file. Once a maintainer is found, add an |
| entry to libs/maintainers.txt to eliminate this message. |
| """ |
| |
| for lib in failing_libraries: |
| if not(lib in maintainers) or maintainers[lib] == list(): |
| message += ' ' + lib + '\n' |
| message += '\n' |
| |
| message += line |
| |
| if '--send' in sys.argv: |
| print 'Sending notification email...' |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = from_line, to_addrs = to_line, msg = message) |
| print 'Done.' |
| |
| if '--debug' in sys.argv: |
| print "----------Boost developer's message text----------" |
| print message |
| |
| ############################################################################### |
| # Main program # |
| ############################################################################### |
| |
| # Parse command-line options |
| branch = "trunk" |
| for arg in sys.argv: |
| if arg.startswith("--branch="): |
| branch = arg[len("--branch="):] |
| |
| report = Report(branch) |
| |
| # Try to parse the issues e-mail |
| if '--no-get' in sys.argv: |
| okay = report.parseIssuesEmail() |
| else: |
| okay = report.getIssuesEmail() |
| |
| if not okay: |
| print 'Aborting.' |
| if '--send' in sys.argv: |
| message = """From: Douglas Gregor <dgregor@osl.iu.edu> |
| To: Douglas Gregor <dgregor@osl.iu.edu> |
| Reply-To: boost@lists.boost.org |
| Subject: Regression status script failed on """ |
| message += str(datetime.date.today()) + " [" + branch + "]" |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = 'Douglas Gregor <dgregor@osl.iu.edu>', |
| to_addrs = 'dgregor@osl.iu.edu', |
| msg = message) |
| sys.exit(1) |
| |
| # Try to parse maintainers information |
| report.parseLibraryMaintainersFile() |
| report.parsePlatformMaintainersFile() |
| |
| # Generate individualized e-mail for library maintainers |
| for maintainer_name in report.maintainers: |
| maintainer = report.maintainers[maintainer_name] |
| |
| email = maintainer.composeEmail(report) |
| if email: |
| if '--send' in sys.argv: |
| print ('Sending notification email to ' + maintainer.name + '...') |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = report_author, |
| to_addrs = maintainer.email, |
| msg = email) |
| print 'done.\n' |
| else: |
| print 'Would send a notification e-mail to',maintainer.name |
| |
| if '--debug' in sys.argv: |
| print ('Message text for ' + maintainer.name + ':\n') |
| print email |
| |
| # Generate individualized e-mail for platform maintainers |
| for maintainer_name in report.platform_maintainers: |
| maintainer = report.platform_maintainers[maintainer_name] |
| |
| email = maintainer.composeEmail(report) |
| if email: |
| if '--send' in sys.argv: |
| print ('Sending notification email to ' + maintainer.name + '...') |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = report_author, |
| to_addrs = maintainer.email, |
| msg = email) |
| print 'done.\n' |
| else: |
| print 'Would send a notification e-mail to',maintainer.name |
| |
| if '--debug' in sys.argv: |
| print ('Message text for ' + maintainer.name + ':\n') |
| print email |
| |
| email = report.composeSummaryEmail() |
| if '--send' in sys.argv: |
| print 'Sending summary email to Boost developer list...' |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = report_author, |
| to_addrs = boost_dev_list, |
| msg = email) |
| print 'done.\n' |
| if '--debug' in sys.argv: |
| print 'Message text for summary:\n' |
| print email |
| |
| email = report.composeTestingSummaryEmail() |
| if email: |
| if '--send' in sys.argv: |
| print 'Sending summary email to Boost testing list...' |
| smtp = smtplib.SMTP('milliways.osl.iu.edu') |
| smtp.sendmail(from_addr = report_author, |
| to_addrs = boost_testing_list, |
| msg = email) |
| print 'done.\n' |
| if '--debug' in sys.argv: |
| print 'Message text for testing summary:\n' |
| print email |
| |
| if not ('--send' in sys.argv): |
| print 'Chickening out and not sending any e-mail.' |
| print 'Use --send to actually send e-mail, --debug to see e-mails.' |