diff --git a/debian/tools/patchupdate.py b/debian/tools/patchupdate.py index 8c42d3fb..8e71ca37 100755 --- a/debian/tools/patchupdate.py +++ b/debian/tools/patchupdate.py @@ -40,8 +40,8 @@ import subprocess import sys import tempfile import textwrap -import urllib import xmlrpclib +import ConfigParser _devnull = open(os.devnull, 'wb') @@ -52,6 +52,7 @@ cached_patch_result = {} class config(object): path_cache = ".patchupdate.cache" + path_config = os.path.expanduser("~/.config/patchupdate.conf") path_patches = "patches" path_changelog = "debian/changelog" @@ -66,6 +67,10 @@ class config(object): path_IfDefined = "9999-IfDefined.patch" bugtracker_url = "https://bugs.winehq.org/xmlrpc.cgi" + bugtracker_defaultcc = ["michael@fds-team.de", "sebastian@fds-team.de"] + bugtracker_user = None + bugtracker_pass = None + github_url = "https://github.com/wine-compholio/wine-staging" class PatchUpdaterError(RuntimeError): @@ -430,7 +435,41 @@ def resolve_dependencies(all_patches, index = None, depends = None, auto_deps = _resolve(depends) return resolved -def check_bug_status(all_patches): +def sync_bug_status(bugtracker, bug, url): + """Automatically updates the STAGED information of a referenced bug.""" + + # We don't want to reopen bugs + if bug['status'] not in ["UNCONFIRMED", "NEW", "ASSIGNED", "REOPENED", "STAGED"]: + return + + if config.bugtracker_user is None or config.bugtracker_pass is None: + raise PatchUpdaterError("Can't update bug without username/password set") + + changes = { 'ids' : bug['id'], + 'Bugzilla_login' : config.bugtracker_user, + 'Bugzilla_password' : config.bugtracker_pass } + + # Update bug status + if bug['status'] != "STAGED": + changes['status'] = "STAGED" + + # Update patchset URL + if bug['cf_staged_patchset'] != url: + changes['cf_staged_patchset'] = url + + # Add missing CC contacts + missing_cc = [] + for cc in config.bugtracker_defaultcc: + if cc not in bug['cc']: + missing_cc.append(cc) + if len(missing_cc): + changes["cc"] = {"add" : missing_cc} + + bugtracker.Bug.update(changes) + +def check_bug_status(all_patches, sync_bugs=False): + """Checks the information in the referenced bugs and corrects them if sync_bugs is set.""" + all_bugids = set() url_map = {} @@ -455,13 +494,15 @@ def check_bug_status(all_patches): once = False print " #%d - \"%s\" - %s %s - %s" % (bug['id'], bug['summary'], bug['status'], bug['resolution'], bug['cf_staged_patchset']) + if sync_bugs: + sync_bug_status(bugtracker, bug, url_map[bug['id']]) once = True for bug in staged_bugs['bugs']: if bug['id'] not in all_bugids: if once: print "" - print "WARNING: The following bugs are incorrectly markes as STAGED:" + print "WARNING: The following bugs are incorrectly marked as STAGED:" print "" once = False print " #%d - \"%s\" - %s %s" % (bug['id'], bug['summary'], bug['status'], @@ -872,11 +913,22 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Automatic patch dependency checker and apply script/README.md generator.") parser.add_argument('--skip-checks', action='store_true', help="Skip dependency checks") parser.add_argument('--commit', type=_check_commit_hash, help="Use given commit hash instead of HEAD") + parser.add_argument('--sync-bugs', action='store_true', help="Update bugs in bugtracker (requires admin rights)") args = parser.parse_args() tools_directory = os.path.dirname(os.path.realpath(__file__)) os.chdir(os.path.join(tools_directory, "./../..")) + config_parser = ConfigParser.ConfigParser() + config_parser.read(config.path_config) + + try: + config.bugtracker_user = config_parser.get('bugtracker', 'username') + config.bugtracker_pass = config_parser.get('bugtracker', 'password') + except (ConfigParser.NoSectionError, ConfigParser.NoOptionError): + config.bugtracker_user = None + config.bugtracker_pass = None + try: # Get information about Wine and Staging version @@ -888,7 +940,7 @@ if __name__ == "__main__": stable_patches = read_patchset(revision="v%s" % latest_staging_version) # Check bugzilla - check_bug_status(all_patches) + check_bug_status(all_patches, sync_bugs=args.sync_bugs) # Update autogenerated files generate_ifdefined(all_patches, skip_checks=args.skip_checks)