Modernize branch_changer.py script.

maintainer-scripts/ChangeLog:

	* branch_changer.py: Modernize and fix flake8 issues.
	* setup.cfg: New file.
This commit is contained in:
Martin Liska 2021-04-08 14:45:01 +02:00
parent ac24fa46e4
commit 9e07b0bfe8
2 changed files with 45 additions and 30 deletions

View File

@ -16,7 +16,8 @@
# #
# Sample usages of the script: # Sample usages of the script:
# #
# $ ./maintainer-scripts/branch_changer.py api_key --new-target-milestone=6.2:6.3 --comment '6.2 has been released....' --add-known-to-fail=6.2 --limit 3 # $ ./maintainer-scripts/branch_changer.py api_key --new-target-milestone=6.2:6.3 \
# --comment '6.2 has been released....' --add-known-to-fail=6.2 --limit 3
# #
# The invocation will set target milestone to 6.3 for all issues that # The invocation will set target milestone to 6.3 for all issues that
# have mistone equal to 6.2. Apart from that, a comment is added to these # have mistone equal to 6.2. Apart from that, a comment is added to these
@ -24,7 +25,8 @@
# At maximum 3 issues will be modified and the script will run # At maximum 3 issues will be modified and the script will run
# in dry mode (no issues are modified), unless you append --doit option. # in dry mode (no issues are modified), unless you append --doit option.
# #
# $ ./maintainer-scripts/branch_changer.py api_key --new-target-milestone=5.5:6.3 --comment 'GCC 5 branch is being closed' --remove 5 --limit 3 # $ ./maintainer-scripts/branch_changer.py api_key --new-target-milestone=5.5:6.3 \
# --comment 'GCC 5 branch is being closed' --remove 5 --limit 3
# #
# Very similar to previous invocation, but instead of adding to known-to-fail, # Very similar to previous invocation, but instead of adding to known-to-fail,
# '5' release is removed from all issues that have the regression prefix. # '5' release is removed from all issues that have the regression prefix.
@ -35,17 +37,19 @@
# issues that contain '7' in its regression prefix. # issues that contain '7' in its regression prefix.
# #
import requests
import json
import argparse import argparse
import json
import re import re
from semantic_version import Version import requests
from semantic_version import SimpleSpec
base_url = 'https://gcc.gnu.org/bugzilla/rest.cgi/' base_url = 'https://gcc.gnu.org/bugzilla/rest.cgi/'
statuses = ['UNCONFIRMED', 'ASSIGNED', 'SUSPENDED', 'NEW', 'WAITING', 'REOPENED'] statuses = ['UNCONFIRMED', 'ASSIGNED', 'SUSPENDED', 'NEW', 'WAITING', 'REOPENED']
search_summary = ' Regression]' search_summary = ' Regression]'
regex = '(.*\[)([0-9\./]*)( [rR]egression])(.*)' regex = r'(.*\[)([0-9\./]*)( [rR]egression])(.*)'
class Bug: class Bug:
def __init__(self, data): def __init__(self, data):
@ -59,7 +63,7 @@ class Bug:
def parse_summary(self): def parse_summary(self):
m = re.match(regex, self.data['summary']) m = re.match(regex, self.data['summary'])
if m != None: if m:
self.versions = m.group(2).split('/') self.versions = m.group(2).split('/')
self.is_regression = True self.is_regression = True
self.regex_match = m self.regex_match = m
@ -116,15 +120,16 @@ class Bug:
print(' changing target milestone: "%s" to "%s" (same branch)' % (old_milestone, new_milestone)) print(' changing target milestone: "%s" to "%s" (same branch)' % (old_milestone, new_milestone))
elif self.is_regression and new_major in self.versions: elif self.is_regression and new_major in self.versions:
args['target_milestone'] = new_milestone args['target_milestone'] = new_milestone
print(' changing target milestone: "%s" to "%s" (regresses with the new milestone)' % (old_milestone, new_milestone)) print(' changing target milestone: "%s" to "%s" (regresses with the new milestone)'
% (old_milestone, new_milestone))
else: else:
print(' not changing target milestone: not a regression or does not regress with the new milestone') print(' not changing target milestone: not a regression or does not regress with the new milestone')
if 'target_milestone' in args and comment != None: if 'target_milestone' in args and comment:
print(' adding comment: "%s"' % comment) print(' adding comment: "%s"' % comment)
args['comment'] = {'comment': comment} args['comment'] = {'comment': comment}
if new_fail_version != None: if new_fail_version:
if self.add_known_to_fail(new_fail_version): if self.add_known_to_fail(new_fail_version):
s = self.serialize_known_to_fail() s = self.serialize_known_to_fail()
print(' changing known_to_fail: "%s" to "%s"' % (self.data['cf_known_to_fail'], s)) print(' changing known_to_fail: "%s" to "%s"' % (self.data['cf_known_to_fail'], s))
@ -137,8 +142,8 @@ class Bug:
return False return False
def serialize_summary(self): def serialize_summary(self):
assert self.versions != None assert not self.versions
assert self.is_regression == True assert self.is_regression
new_version = '/'.join(self.versions) new_version = '/'.join(self.versions)
new_summary = self.regex_match.group(1) + new_version + self.regex_match.group(3) + self.regex_match.group(4) new_summary = self.regex_match.group(1) + new_version + self.regex_match.group(3) + self.regex_match.group(4)
@ -146,7 +151,7 @@ class Bug:
def serialize_known_to_fail(self): def serialize_known_to_fail(self):
assert type(self.fail_versions) is list assert type(self.fail_versions) is list
return ', '.join(sorted(self.fail_versions, key = lambda x: Version(x, partial = True))) return ', '.join(sorted(self.fail_versions, key=lambda x: SimpleSpec(x)))
def modify_bug(self, api_key, params, doit): def modify_bug(self, api_key, params, doit):
u = base_url + 'bug/' + str(self.data['id']) u = base_url + 'bug/' + str(self.data['id'])
@ -158,7 +163,7 @@ class Bug:
data.update(params) data.update(params)
if doit: if doit:
r = requests.put(u, data = json.dumps(data), headers = {"content-type": "text/javascript"}) r = requests.put(u, data=json.dumps(data), headers={'content-type': 'text/javascript'})
print(r) print(r)
@staticmethod @staticmethod
@ -173,15 +178,16 @@ class Bug:
r = requests.get(u, params=query) r = requests.get(u, params=query)
return [Bug(x) for x in r.json()['bugs']] return [Bug(x) for x in r.json()['bugs']]
def search(api_key, remove, add, limit, doit): def search(api_key, remove, add, limit, doit):
bugs = Bug.get_bugs(api_key, {'api_key': api_key, 'summary': search_summary, 'bug_status': statuses}) bugs = Bug.get_bugs(api_key, {'api_key': api_key, 'summary': search_summary, 'bug_status': statuses})
bugs = list(filter(lambda x: x.is_regression, bugs)) bugs = list(filter(lambda x: x.is_regression, bugs))
modified = 0 modified = 0
for bug in bugs: for bug in bugs:
if remove != None: if remove:
bug.remove_release(remove) bug.remove_release(remove)
if add != None: if add:
bug.add_release(add) bug.add_release(add)
if bug.update_summary(api_key, doit): if bug.update_summary(api_key, doit):
@ -191,6 +197,7 @@ def search(api_key, remove, add, limit, doit):
print('\nModified PRs: %d' % modified) print('\nModified PRs: %d' % modified)
def replace_milestone(api_key, limit, old_milestone, new_milestone, comment, add_known_to_fail, doit): def replace_milestone(api_key, limit, old_milestone, new_milestone, comment, add_known_to_fail, doit):
bugs = Bug.get_bugs(api_key, {'api_key': api_key, 'bug_status': statuses, 'target_milestone': old_milestone}) bugs = Bug.get_bugs(api_key, {'api_key': api_key, 'bug_status': statuses, 'target_milestone': old_milestone})
@ -203,23 +210,26 @@ def replace_milestone(api_key, limit, old_milestone, new_milestone, comment, add
print('\nModified PRs: %d' % modified) print('\nModified PRs: %d' % modified)
parser = argparse.ArgumentParser(description='') parser = argparse.ArgumentParser(description='')
parser.add_argument('api_key', help='API key') parser.add_argument('api_key', help='API key')
parser.add_argument('--remove', nargs='?', help='Remove a release from summary') parser.add_argument('--remove', nargs='?', help='Remove a release from summary')
parser.add_argument('--add', nargs='?', help='Add a new release to summary, e.g. 6:7 will add 7 where 6 is included') parser.add_argument('--add', nargs='?', help='Add a new release to summary, e.g. 6:7 will add 7 where 6 is included')
parser.add_argument('--limit', nargs='?', help='Limit number of bugs affected by the script') parser.add_argument('--limit', nargs='?', help='Limit number of bugs affected by the script')
parser.add_argument('--doit', action='store_true', help='Really modify BUGs in the bugzilla') parser.add_argument('--doit', action='store_true', help='Really modify BUGs in the bugzilla')
parser.add_argument('--new-target-milestone', help = 'Set a new target milestone, e.g. 4.9.3:4.9.4 will set milestone to 4.9.4 for all PRs having milestone set to 4.9.3') parser.add_argument('--new-target-milestone', help='Set a new target milestone, '
parser.add_argument('--add-known-to-fail', help = 'Set a new known to fail for all PRs affected by --new-target-milestone') 'e.g. 4.9.3:4.9.4 will set milestone to 4.9.4 for all PRs having milestone set to 4.9.3')
parser.add_argument('--add-known-to-fail', help='Set a new known to fail '
'for all PRs affected by --new-target-milestone')
parser.add_argument('--comment', help='Comment a PR for which we set a new target milestore') parser.add_argument('--comment', help='Comment a PR for which we set a new target milestore')
args = parser.parse_args() args = parser.parse_args()
# Python3 does not have sys.maxint # Python3 does not have sys.maxint
args.limit = int(args.limit) if args.limit != None else 10**10 args.limit = int(args.limit) if args.limit else 10**10
if args.remove != None or args.add != None: if args.remove or args.add:
search(args.api_key, args.remove, args.add, args.limit, args.doit) search(args.api_key, args.remove, args.add, args.limit, args.doit)
if args.new_target_milestone != None: if args.new_target_milestone:
t = args.new_target_milestone.split(':') t = args.new_target_milestone.split(':')
assert len(t) == 2 assert len(t) == 2
replace_milestone(args.api_key, args.limit, t[0], t[1], args.comment, args.add_known_to_fail, args.doit) replace_milestone(args.api_key, args.limit, t[0], t[1], args.comment, args.add_known_to_fail, args.doit)

View File

@ -0,0 +1,5 @@
[flake8]
max-line-length = 120
[tool:pytest]
addopts = -vv --flake8