gerrit-dash-creator/gerrit_dash_creator/cmd/bugs.py

176 lines
5.5 KiB
Python
Executable File

#!/usr/bin/env python
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import argparse
import configparser
import os
import sys
from launchpadlib import launchpad
from gerrit_dash_creator.cmd import creator
CACHE_DIR = os.path.expanduser('~/.cache/launchpadlib/')
SERVICE_ROOT = 'production'
def print_dash_url(opts, bugs):
config = configparser.ConfigParser()
config.add_section('dashboard')
title = ','.join(opts.projects)
if opts.milestone:
title += ' milestone:%s' % opts.milestone
if opts.tag:
title += ' AND'
if opts.tag:
title += ' tag:%s' % opts.tag
config.set('dashboard', 'title', title)
config.set('dashboard', 'description', 'Bug Fix Inbox')
proj_q = ['project:openstack/%s' % proj for proj in opts.projects]
config.set('dashboard', 'foreach',
'(%s) status:open ' % ' OR '.join(proj_q))
for label in bugs:
for prio in bugs[label]:
if len(bugs[label][prio]) == 0:
continue
sect = 'section "%s Importance %s"' % (label, prio)
if prio == 'None':
sect = 'section "%s"' % label
config.add_section(sect)
config.set(sect, 'query',
' OR '.join(['change:%s' % bug
for bug in bugs[label][prio]]))
print(creator.generate_dashboard_url(config))
def pretty_milestone(milestone_url):
if milestone_url is None:
return 'Unassigned'
# https://api.launchpad.net/1.0/heat/+milestone/next:
return str(milestone_url).split('/')[-1]
def review_id_from_bug(bug, project_name):
reviews = set()
reviews_ignored = set()
for msg in bug.bug.messages:
try:
lines = str(msg.content).split('\n')
except UnicodeEncodeError:
print('non-ascii in bug %s' % bug.web_link)
continue
proposed = 'ix proposed to %s' % project_name
merged = 'ix merged to %s' % project_name
abandoned = 'Change abandoned on %s' % project_name
if proposed in msg.subject:
for line in lines:
if 'Review: ' in line:
reviews.add(line.split('/')[-1])
if merged in msg.subject or abandoned in msg.subject:
for line in lines:
if 'Review' in line:
reviews_ignored.add(line.split('/')[-1])
live_reviews = (reviews - reviews_ignored)
if len(live_reviews) == 0:
print('bug %s has no reviews set to Triaged state' % bug.web_link)
return live_reviews
def get_options():
"""Parse command line arguments and options."""
parser = argparse.ArgumentParser(
description='Create a Gerrit dashboard URL from launchpad '
'"In Progress bugs')
parser.add_argument('projects', nargs='+',
metavar='projects',
help='Launchpad Projects')
parser.add_argument('--milestone', default=None,
help='Project Milestone')
parser.add_argument('--tag', default=None,
help='Project Tag')
return parser.parse_args()
def process_project(lp, opts, project_name, bugs):
project = lp.projects[project_name]
if opts.tag is None and opts.milestone is not None:
from_milestone = project.getMilestone(name=opts.milestone)
if not from_milestone:
print('Origin milestone %s does not exist' %
opts.milestone)
sys.exit(1)
review_bugtasks = from_milestone.searchTasks(status=['In Progress'])
else:
review_bugtasks = project.searchTasks(status=['In Progress'])
for bug in review_bugtasks:
importance = bug.importance
milestone = pretty_milestone(bug.milestone)
tags = bug.bug.tags
label = None
if opts.tag is not None:
if opts.tag in tags:
label = 'Tag:%s' % opts.tag
if opts.milestone is not None:
if milestone == opts.milestone:
label = 'Milestone:%s' % milestone
if opts.tag is None and opts.milestone is None:
# just place by milestone
label = 'Milestone:%s' % milestone
importance = 'None'
if label is None:
continue
if label not in bugs:
bugs[label] = {}
if importance not in bugs[label]:
bugs[label][importance] = []
for rev_no in review_id_from_bug(bug, project_name):
bugs[label][importance].append(rev_no)
print('[%s] %s -> %s' % (importance,
bug.web_link, rev_no))
def main():
"""Entrypoint."""
opts = get_options()
lpad = launchpad.Launchpad.login_anonymously(sys.argv[0],
SERVICE_ROOT,
CACHE_DIR)
bugs = {}
for proj in opts.projects:
process_project(lpad, opts, proj, bugs)
print('')
print_dash_url(opts, bugs)
return 0
if __name__ == '__main__':
sys.exit(main())