blob: dc6a6951032cb96e14108c72b5a9b60abffbd655 [file] [log] [blame]
#!/usr/bin/env python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
from itertools import tee, izip, chain
import json
import git
from collections import Counter
'''
This script is for one-time conversion of Allura's own tickets from SourceForge
host to forge-allura.apache.org hosting
Change path variables here:
'''
filename = "/var/local/allura/tickets.json" # Absolute path to exported tickets.json
output = "/var/local/allura/updated_tickets.json" # Absolute path to the output
ticket_list = "/var/local/allura/ticket_ids.list"
top_usernames = "/var/local/allura/top_usernames.list"
gitrepository = "/var/local/allura" # Path to allura repository
g = git.Git(gitrepository)
reviews = ['code-review', 'design-review']
with open(filename, 'r') as json_file:
data = json.loads(json_file.read())
def pairwise(iterable):
"""s -> (s0,s1), (s1,s2), (s2, s3), ..."""
a, b = tee(iterable)
next(b, None)
return izip(a, b)
tags = ['asf_release_1.0.0', 'asf_release_1.0.0-RC1', 'asf_release_1.0.1', 'asf_release_1.1.0', 'HEAD']
tag_log = dict()
for tag1, tag2 in pairwise(tags):
log = g.log('%s...%s' % (tag1, tag2), '--pretty=oneline')
tag_log[tag2] = log
ticket_tag = dict()
tickets = data.pop('tickets')
for ticket in tickets:
for key, value in tag_log.iteritems():
if "[#%s]" % ticket['ticket_num'] in value:
ticket_tag[ticket['ticket_num']] = key
continue
data.pop('milestones', None)
data.pop('saved_bins', None)
updated = []
for ticket in tickets:
if not ticket['private'] or ticket['ticket_num'] == 6054:
if ticket['status'] in reviews:
ticket['status'] = 'review'
milestone = ticket_tag.get(ticket['ticket_num'], None)
if not milestone:
if ticket['status'] == 'closed':
milestone = tags[0]
ticket['custom_fields']['_milestone'] = milestone if milestone and milestone != 'HEAD' else 'unreleased'
if '_size' in ticket['custom_fields'].keys():
size = ticket['custom_fields']['_size']
if size:
ticket['labels'].append("sf-%d" % int(size))
ticket['custom_fields'].pop('_size', None)
if '_qa' in ticket['custom_fields'].keys():
ticket['custom_fields']['_reviewer'] = ticket['custom_fields']['_qa']
ticket['custom_fields'].pop('_qa', None)
updated.append(ticket)
tags[-1] = 'unreleased'
data['tickets'] = updated
# Remove milestones from the list
custom_fields = filter(lambda d: d.get('name') not in ['_milestone', 'name', '_size', '_qa'], data['custom_fields'])
data['custom_fields'] = custom_fields
milestones = {
"milestones": [
dict(name=milestone_name,
old_name=milestone_name,
default=False,
complete=False,
due_date="",
description="")
for milestone_name in tags
],
"name": "_milestone",
"show_in_search": False,
"label": "Milestone",
"type": "milestone",
"options": ""
}
data['custom_fields'].append(milestones)
data['custom_fields'].append({
"show_in_search": True,
"label": "Reviewer",
"type": "user",
"options": "",
"name": "_reviewer"
})
data['milestones'] = milestones
data['saved_bins'] = []
# Count top used usernames
assigned_to = [ticket.get('assigned_to', None) for ticket in updated]
reported_by = [ticket.get('reported_by', None) for ticket in updated]
reviewed_by = [ticket['custom_fields'].get('_reviewer', None) for ticket in updated]
posts = [ticket['discussion_thread']['posts'] for ticket in updated]
post_authors = [post.get('author', None) for post in list(chain(*posts))]
usernames = filter(lambda x: bool(x), chain(assigned_to, reported_by, reviewed_by, post_authors))
top_users = Counter(usernames).most_common(50)
with open(output, 'w') as outfile:
json.dump(data, outfile, indent=2)
with open(ticket_list, 'w') as outfile:
outfile.write('\n'.join(sorted([str(ticket['ticket_num']) for ticket in updated])))
with open(top_usernames, 'w') as outfile:
lines = ["%s - %s" % (username, frequency) for username, frequency in top_users]
outfile.write('\n'.join(lines))