eobuilder/eobuilder/changelog.py

106 lines
3.4 KiB
Python

import datetime
import textwrap
import os
import re
import sys
import pytz
import git
from git.exc import GitCommandError
from git.objects.commit import Commit
from . import cmdline
def get_commit_from_tag(repo, tag_ref):
ref = repo.tags[tag_ref]
while ref.object.type == 'tag':
ref = ref.object
assert ref.object.type == 'commit'
return ref.object
def is_pep0440_project(path):
if not os.path.exists(os.path.join(path, 'setup.py')):
return False
curdir = os.getcwd()
try:
os.chdir(path)
output = cmdline.output('python setup.py --version')
if '+' in output:
return True
finally:
os.chdir(curdir)
return False
def changelog_from_git(project, version_suffix, path,
repository='eobuilder',
maintainer_name='eobuilder',
maintainer_email='eobuilder@entrouvert.com',
epoch=''):
repo = git.repo.Repo(path)
is_pep0440 = is_pep0440_project(path)
versions = []
try:
last_tag = repo.git.describe(abbrev=0)
except GitCommandError:
# no tag version is 0.0.<number of commits>
versions.append(('0.0.%d' % repo.head.commit.count(), repo.head.commit))
else:
if get_commit_from_tag(repo, last_tag) != repo.head.commit:
versions.append((repo.git.describe(), repo.head.commit))
versions.append((last_tag, get_commit_from_tag(repo, last_tag)))
while True:
try:
last_tag = repo.git.describe(last_tag+'~', abbrev=0)
except GitCommandError:
break
else:
versions.append((last_tag, get_commit_from_tag(repo, last_tag)))
n = len(versions)
for i in range(n):
name, commit = versions[i]
if i == n-1:
logs = [commit] + list(commit.iter_parents())
else:
reflog = '%s..%s' % (versions[i+1][1].binsha.encode('hex'), commit.binsha.encode('hex'))
logs = list(Commit.iter_items(repo, reflog))
if not logs:
continue
version = name.lstrip('v').replace('-', '.')
if is_pep0440:
# use .postX+g form
version = re.sub('\.(\d+)\.g', r'.post\1+g', version)
if i == 0:
version += version_suffix
if epoch:
version = '%s:%s' % (epoch, version)
yield '%s (%s) %s; urgency=low' % (project, str(version), repository)
yield ''
for l in logs:
try:
t = '(%s) %s' % (l.hexsha[:6], l.summary)
except LookupError as e:
t = '(%s) %s' % (l.hexsha[:6], e)
lines = textwrap.wrap(t, 80)
for prefix, suffix in zip([' * '] + [' ']*(len(lines)-1), lines):
yield (prefix + suffix).encode('utf-8')
paris = pytz.timezone('Europe/Paris')
date = datetime.datetime.fromtimestamp(logs[0].committed_date + logs[0].committer_tz_offset).replace(
tzinfo=pytz.UTC).astimezone(paris).strftime('%a, %d %b %Y %H:%M:%S %z')
yield ''
yield ' -- %s <%s> %s' % (maintainer_name, maintainer_email, date)
yield ''
if __name__ == '__main__':
project = sys.argv[1]
version_suffix = sys.argv[2]
if len(sys.argv) > 3:
path = sys.argv[3]
else:
path = os.getcwd()
print '\n'.join(changelog_from_git(project, version_suffix, path))