You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
3.7 KiB

#!/usr/bin/env python
'''
This script attempts to extract what options have been added since the
specified revision (usually a tag, but any revision that git recognizes may be
provided). It accepts an optional second revision to use as the cut-off. The
default is your LOCAL "master". Thus, you should ensure that this is up to date
before running this script.
This script works by extracting the set of options before and after every
commit that affected ':src/options.h' and computing the differences. It should,
therefore, be fairly robust (for example, options that moved around won't show
up). However, if an option is removed and subsequently re-added, or if an
option was added and subsequently removed, the resulting records will need to
be reconciled manually.
'''
import argparse
import git
import os
import re
import sys
import time
re_option = re.compile(r'extern (Bounded)?Option<[^>]+>')
# -----------------------------------------------------------------------------
def extract_options(repo, blob_id):
from git.util import hex_to_bin
blob = git.Blob(repo, hex_to_bin(blob_id))
content = blob.data_stream.stream
options = set()
for line in iter(content.readline, b''):
line = line.decode('utf-8').strip()
if re_option.match(line):
line = content.readline().decode('utf-8').strip()
options.add(line.split(';')[0])
return options
# =============================================================================
class Changeset(object):
# -------------------------------------------------------------------------
def __init__(self, repo, sha):
self.sha = sha
self.added_options = set()
self.removed_options = set()
commit = repo.commit(sha)
ad = time.gmtime(commit.authored_date)
self.date = time.strftime('%b %d %Y', ad).replace(' 0', ' ')
info = repo.git.log('-1', '--raw', '--abbrev=40', '--pretty=',
sha, '--', ':src/options.h').split(' ')
if len(info) < 5:
return
old_options = extract_options(repo, info[2])
new_options = extract_options(repo, info[3])
self.added_options = new_options.difference(old_options)
self.removed_options = old_options.difference(new_options)
# -----------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(
description='Generate changelog for new options')
root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
parser.add_argument('--repo', type=str, default=root,
help='Path to uncrustify git repository')
parser.add_argument('since', type=str,
help='Revision (tag) of previous uncrustify version')
parser.add_argument('until', type=str, default='master', nargs='?',
help='Revision (tag) of next uncrustify version')
args = parser.parse_args()
repo = git.Repo(args.repo)
revs = repo.git.log('--pretty=%H', '--reverse',
'{}..{}'.format(args.since, args.until),
'--', ':src/options.h').split('\n')
if revs == ['']:
print('No changes were found')
return 1
changes = []
for r in revs:
c = Changeset(repo, r)
if len(c.added_options) or len(c.removed_options):
changes.append(c)
for c in changes:
print(' ', c.sha)
for o in c.added_options:
print(' Added : {:36} {}'.format(o, c.date))
for o in c.removed_options:
print(' Removed : {:36} {}'.format(o, c.date))
return 0
# %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if __name__ == '__main__':
sys.exit(main())