Updated Branches: refs/heads/trunk ff464ff08 -> a91706404
Add a script for generating a Markdown formatted list of contributors from the CHANGES file. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a9170640 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a9170640 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a9170640 Branch: refs/heads/trunk Commit: a91706404508c8f3c0337391c0a702846e3fa349 Parents: ff464ff Author: Tomaz Muraus <[email protected]> Authored: Tue Dec 17 15:44:09 2013 +0100 Committer: Tomaz Muraus <[email protected]> Committed: Tue Dec 17 15:44:09 2013 +0100 ---------------------------------------------------------------------- contrib/generate_contributor_list.py | 131 ++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/a9170640/contrib/generate_contributor_list.py ---------------------------------------------------------------------- diff --git a/contrib/generate_contributor_list.py b/contrib/generate_contributor_list.py new file mode 100755 index 0000000..de9fa19 --- /dev/null +++ b/contrib/generate_contributor_list.py @@ -0,0 +1,131 @@ +#!/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. +# +# Script which generates markdown formatted list of contributors. It generates +# this list by parsing the "CHANGES" file. + +from __future__ import with_statement + +import re +import argparse +from collections import defaultdict + +JIRA_URL = 'https://issues.apache.org/jira/browse/LIBCLOUD-%s' +GITHUB_URL = 'https://github.com/apache/libcloud/pull/%s' + + +def parse_changes_file(file_path): + """ + Parse CHANGES file and return a dictionary with contributors. + + Dictionary maps contributor name to the JIRA tickets or Github pull + requests the user has worked on. + """ + # Maps contributor name to a list of JIRA tickets + contributors_map = defaultdict(set) + + in_entry = False + active_tickets = [] + + with open(file_path, 'r') as fp: + for line in fp: + line = line.strip() + + if line.startswith('-') or line.startswith('*)'): + in_entry = True + active_tickets = [] + + if in_entry and line == '': + in_entry = False + + if in_entry: + match = re.search(r'\((.+?)\)$', line) + + if match: + active_tickets = match.groups()[0] + active_tickets = active_tickets.split(', ') + active_tickets = [ticket for ticket in active_tickets if + ticket.startswith('LIBCLOUD-') or + ticket.startswith('GITHUB-')] + + match = re.search(r'^\[(.+?)\]$', line) + + if match: + contributors = match.groups()[0] + contributors = contributors.split(',') + contributors = [name.strip() for name in contributors] + + for name in contributors: + contributors_map[name].update(set(active_tickets)) + + return contributors_map + + +def convert_to_markdown(contributors_map): + + # Contributors are sorted in ascending lexiographical order based on their + # last name + def compare(item1, item2): + lastname1 = item1.split(' ')[-1].lower() + lastname2 = item2.split(' ')[-1].lower() + return cmp(lastname1, lastname2) + + names = contributors_map.keys() + names = sorted(names, cmp=compare) + + result = [] + for name in names: + tickets = contributors_map[name] + + tickets_string = [] + + for ticket in tickets: + if '-' not in ticket: + # Invalid ticket number + continue + + number = ticket.split('-')[1] + + if ticket.startswith('LIBCLOUD-'): + url = JIRA_URL % (number) + elif ticket.startswith('GITHUB-') or ticket.startswith('GH-'): + url = GITHUB_URL % (number) + + values = {'ticket': ticket, 'url': url} + tickets_string.append('[%(ticket)s](%(url)s)' % values) + + tickets_string = ', '.join(tickets_string) + line = '* %(name)s: %(tickets)s' % {'name': name, + 'tickets': tickets_string} + result.append(line) + + result = '\n'.join(result) + return result + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Assemble provider logos ' + ' in a single image') + parser.add_argument('--changes-path', action='store', + help='Path to the changes file') + args = parser.parse_args() + + contributors_map = parse_changes_file(file_path=args.changes_path) + markdown = convert_to_markdown(contributors_map=contributors_map) + + print(markdown)
