Created
January 20, 2017 23:29
-
-
Save jberry-suse/ebef106a308ec22d082519d42dc3277e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/issue-diff.py b/issue-diff.py | |
index dd5e819..51cfe45 100755 | |
--- a/issue-diff.py | |
+++ b/issue-diff.py | |
@@ -3,7 +3,7 @@ | |
from __future__ import print_function | |
import argparse | |
-#import bugzilla | |
+import bugzilla | |
import dateutil.parser | |
from datetime import timedelta, datetime | |
from dateutil.tz import tzlocal | |
@@ -24,22 +24,47 @@ from osclib.cache import Cache | |
# either summary or one in which ISSUE_SUMMARY is then placed must be unicode. | |
# For example, translation-update-upstream contains bsc#877707 which has a | |
# unicode character in its summary. | |
-BUG_SUMMARY = 'Missing issue references from {project}/{package} to {factory}/{package}' | |
+BUG_SUMMARY = 'Missing issue references from {project}/{package} in {factory}/{package}' | |
BUG_TEMPLATE = u'{message_start}\n\n{issues}' | |
MESSAGE_START = 'The following issues were referenced in the changelog for {project}/{package}, but where not found in {factory}/{package} after {newest} days. Review the issues and submit changes to {factory} as necessary.' | |
-ISSUE_SUMMARY = u'[{label}]({url}) owned by @{owner}: {summary}' | |
-ISSUE_SUMMARY_PLAIN = '[{label}]({url})' | |
- | |
- | |
-def create_bug(api, summary, description): | |
- createinfo = api.build_createbug( | |
- product='??', # TODO | |
- version='??', | |
- component='??', | |
+ISSUE_SUMMARY = u'[{label}]({url}) owned by {owner}: {summary}' | |
+ISSUE_SUMMARY_PLAIN = u'[{label}]({url})' | |
+ | |
+ | |
+def bug_create(bugzilla_api, meta, cc, summary, description): | |
+ createinfo = bugzilla_api.build_createbug( | |
+ product=meta[0], | |
+ component=meta[1], | |
+ version=meta[2], | |
+ severity='normal', | |
+ op_sys='Linux', | |
+ platform='PC', | |
+ cc=cc, | |
summary=summary, | |
description=description) | |
+ newbug = bugzilla_api.createbug(createinfo) | |
+ | |
+ return newbug.id | |
+ | |
+def bug_meta_get(bugzilla_api, bug_id): | |
+ bug = bugzilla_api.getbug(bug_id) | |
+ return (bug.product, bug.component, bug.version) | |
- return createinfo.id | |
+def bug_meta(bugzilla_api, defaults, trackers, issues): | |
+ # Extract meta from the first bug from bnc tracker or fallback to defaults. | |
+ prefix = trackers['bnc'][:3] | |
+ for issue in issues: | |
+ if issue.startswith(prefix): | |
+ return bug_meta_get(bugzilla_api, issue[4:]) | |
+ | |
+ return defaults | |
+ | |
+def bugzilla_init(apiurl): | |
+ bugzilla_api = bugzilla.Bugzilla(apiurl) | |
+ if not bugzilla_api.logged_in: | |
+ print('Bugzilla credentials required to create bugs.') | |
+ bugzilla_api.interactive_login() | |
+ return bugzilla_api | |
def prompt_continue(change_count): | |
allowed = ['y', 'n', ''] | |
@@ -64,7 +89,7 @@ def prompt_continue(change_count): | |
def prompt_interactive(changes, project, factory, package, newest): | |
with tempfile.NamedTemporaryFile(suffix='.yml') as temp: | |
- temp.write(yaml.dump(changes, default_flow_style=False, default_style="'") + '\n') | |
+ temp.write(yaml.safe_dump(changes, default_flow_style=False, default_style="'") + '\n') | |
temp.write('# {}/{}\n'.format(project, package)) | |
temp.write('# comment or remove lines to whitelist issues') | |
temp.flush() | |
@@ -116,7 +141,7 @@ def issues_get(apiurl, project, package, trackers, db): | |
if summary is not None: | |
summary = summary.text | |
- owner = issue.find('owner/login') | |
+ owner = issue.find('owner/email') | |
if owner is not None: | |
owner = owner.text | |
@@ -217,12 +242,15 @@ def main(args): | |
print('Comparing {} against {}'.format(args.project, args.factory)) | |
+ bugzilla_api = bugzilla_init(args.bugzilla_apiurl) | |
+ bugzilla_defaults = (args.bugzilla_product, args.bugzilla_component, args.bugzilla_version) | |
+ | |
trackers = issue_trackers(apiurl) | |
packages_project = package_list(apiurl, args.project) | |
packages_factory = package_list(apiurl_default, args.factory) | |
packages = set(packages_project).intersection(set(packages_factory)) | |
new = 0 | |
- for package in packages: | |
+ for package in sorted(packages): | |
issues_project = issues_get(apiurl, args.project, package, trackers, db) | |
issues_factory = issues_get(apiurl_default, args.factory, package, trackers, db) | |
@@ -252,10 +280,14 @@ def main(args): | |
# Determine if any real changes (vs typos) and create text issue list. | |
issues = [] | |
+ cc = [] | |
if len(changes_after) > 0: | |
for issue, summary in changes.items(): | |
if issue in changes_after: | |
issues.append('- ' + summary) | |
+ owner = issues_project[issue]['owner'] | |
+ if owner is not None: | |
+ cc.append(owner) | |
# Prompt user about how to continue. | |
response = prompt_continue(len(issues)) | |
@@ -272,9 +304,11 @@ def main(args): | |
project=args.project, factory=args.factory, package=package, newest=args.newest), | |
issues='\n'.join(issues)) | |
- # TODO Lookup bugzilla component. | |
- bug_id = '17' | |
- #bug_id = bug_create(bugzilla_api, summary, message) | |
+ # Determine bugzilla meta information to use when creating bug. | |
+ meta = bug_meta(bugzilla_api, bugzilla_defaults, trackers, changes.keys()) | |
+ if args.bugzilla_cc: | |
+ cc.append(args.bugzilla_cc) | |
+ bug_id = bug_create(bugzilla_api, meta, cc, summary, message) | |
# Mark changes in db. | |
notified, whitelisted = 0, 0 | |
@@ -283,7 +317,7 @@ def main(args): | |
db[package] = {} | |
if issue in changes_after: | |
- db[package][issue] = bug_id | |
+ db[package][issue] = str(bug_id) | |
notified += 1 | |
else: | |
db[package][issue] = 'whitelist' | |
@@ -291,7 +325,7 @@ def main(args): | |
# Write out changes after each package to avoid loss. | |
with open(db_file, 'w') as outfile: | |
- yaml.dump(db, outfile, default_flow_style=False, default_style="'") | |
+ yaml.safe_dump(db, outfile, default_flow_style=False, default_style="'") | |
if notified > 0: | |
print('{}: {} notified in bug #{}, {} whitelisted'.format(package, notified, bug_id, whitelisted)) | |
@@ -315,7 +349,11 @@ if __name__ == '__main__': | |
'of previously handled issues to avoid repeats and kept in sync via a git repository.' | |
parser = argparse.ArgumentParser(description=description) | |
parser.add_argument('-A', '--apiurl', default='https://api.suse.de', metavar='URL', help='OBS instance API URL') | |
- parser.add_argument('--bugzilla-apiurl', default='apibugzilla.suse.com', metavar='URL', help='bugzilla API URL') | |
+ parser.add_argument('--bugzilla-apiurl', required=True, metavar='URL', help='bugzilla API URL') | |
+ parser.add_argument('--bugzilla-product', default='SUSE Linux Enterprise Desktop 12 SP2', metavar='PRODUCT', help='default bugzilla product') | |
+ parser.add_argument('--bugzilla-component', default='Other', metavar='COMPONENT', help='default bugzilla component') | |
+ parser.add_argument('--bugzilla-version', default='GM', metavar='VERSION', help='default bugzilla version') | |
+ parser.add_argument('--bugzilla-cc', metavar='EMAIL', help='bugzilla address added to cc on all bugs created') | |
parser.add_argument('-d', '--debug', action='store_true', help='print info useful for debugging') | |
parser.add_argument('-f', '--factory', default='openSUSE:Factory', metavar='PROJECT', help='factory project to use as baseline for comparison') | |
parser.add_argument('-p', '--project', default='SUSE:SLE-12-SP2:GA', metavar='PROJECT', help='project to check for issues that have are not found in factory') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment