From 0d06435860b37b4088db9c9b218bf00e9b5d5257 Mon Sep 17 00:00:00 2001 From: rossella Date: Mon, 23 Nov 2015 12:53:45 +0000 Subject: [PATCH] Add a script to create review dashboard for a milestone This script queries launchpad to get: 1) Bug number of bugs tagged with rfe-approved 2) Bug number of critical/high bugs 3) list of blueprints targeted for the milestone passed as param With this information the scripts prints queries that can be used in Gerrit directly and creates a .dash file that can be used by gerrit-dash-creator to output a dashboard url. Change-Id: I09f8c04c6c609d4791bd5af825105ba092831e43 --- tools/milestone-review-dash.py | 142 +++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 tools/milestone-review-dash.py diff --git a/tools/milestone-review-dash.py b/tools/milestone-review-dash.py new file mode 100755 index 000000000..76eca2750 --- /dev/null +++ b/tools/milestone-review-dash.py @@ -0,0 +1,142 @@ +#!/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 sys + +from launchpadlib.launchpad import Launchpad + + +def is_milestone_valid(project, name): + milestone_names = [] + for s in project.active_milestones: + milestone_names.append(s.name) + if name == s.name: + return True + print("No active milestone found") + print("List of active milestones %s" % milestone_names) + return False + + +def _search_task(project, **kwargs): + bugs = project.searchTasks(**kwargs) + if not bugs: + return + gerrit_query = "(" + for b in bugs: + gerrit_query += ("topic:bug/%d OR " % b.bug.id) + gerrit_query = gerrit_query[:-4] + gerrit_query += ")\n\n" + return gerrit_query + + +def get_approved_rfe_query(project): + return _search_task(project, **{'tags': ['rfe-approved']}) + + +def get_critical_bugs_query(project): + return _search_task(project, + **{'status': ["In Progress"], 'importance': ["Critical"]}) + + +def get_high_bugs_query(project): + return _search_task(project, + **{'status': ["In Progress"], 'importance': ["High"]}) + + +def get_specs_query(project, milestone): + query = "(" + for s in project.valid_specifications: + if s.milestone is not None: + if s.milestone.name == milestone: + query += ("topic:bp/%s OR " % s.name) + if query == "(": + # no blueprint was found + return + query = query[:-4] + query += ")\n" + return query + + +def write_section(f, section_name, query): + print(section_name) + if query: + f.write("[section \"") + f.write(section_name) + f.write("\"]\n") + f.write("query = ") + f.write(query) + print(query) + else: + print("No result found\n") + + +def write_queries_for_project(f, project, milestone): + query = get_approved_rfe_query(project) + section_name = "Approved RFE %s" % project.name + write_section(f, section_name, query) + + query = get_critical_bugs_query(project) + section_name = "Critical Bugs %s" % project.name + write_section(f, section_name, query) + + query = get_high_bugs_query(project) + section_name = "High Bugs %s" % project.name + write_section(f, section_name, query) + + query = get_specs_query(project, milestone) + section_name = "Blueprints %s" % project.name + write_section(f, section_name, query) + + +parser = argparse.ArgumentParser( + description='Create dashboard for critical/high bugs, approved rfe and' + ' blueprints. A .dash file will be created in the current' + ' folder that you can serve as input for gerrit-dash-creator.' + ' The output of the script can be used to query Gerrit' + ' directly.') +parser.add_argument('milestone', type=str, help='The release milestone') +parser.add_argument('-o', '--output', type=str, help='Output file') + +args = parser.parse_args() +milestone = args.milestone +if args.output: + file_name = args.output +else: + file_name = milestone + '.dash' + +cachedir = "~/.launchpadlib/cache/" +launchpad = Launchpad.login_anonymously('just testing', 'production', cachedir, + version="devel") +neutron = launchpad.projects['neutron'] +neutron_client = launchpad.projects['python-neutronclient'] +if not is_milestone_valid(neutron, milestone): + sys.exit() + +with open(file_name, 'w') as f: + title = "[dashboard]\ntitle = Neutron %s Review Inbox\n" % milestone + f.write(title) + f.write("description = Review Inbox\n") + f.write("foreach = (project:openstack/neutron OR " + "project:openstack/python-neutronclient OR " + "project:openstack/neutron-specs OR " + "project:openstack/neutron-fwaas OR " + "project:openstack/neutron-lbaas OR " + "project:openstack/neutron-vpnaas) status:open NOT owner:self " + "NOT label:Workflow<=-1 " + "NOT label:Code-Review>=-2,self branch:master\n") + f.write("\n") + + print("Querying Launchpad, this might take a while...") + write_queries_for_project(f, neutron, milestone) + write_queries_for_project(f, neutron_client, milestone) -- 2.45.2