|
| 1 | +import os |
| 2 | +import sys |
| 3 | +from subprocess import check_output |
| 4 | + |
| 5 | +from jinja2 import Environment, FileSystemLoader |
| 6 | + |
| 7 | +env = Environment(loader=FileSystemLoader('templates')) |
| 8 | + |
| 9 | + |
| 10 | +class GitLog: |
| 11 | + MARKER = '--PYCHOLOG MARKER--' |
| 12 | + FORMAT = ( |
| 13 | + '%H%n' # commit hash |
| 14 | + '%an%n' # author name |
| 15 | + '%ae%n' # author email |
| 16 | + '%ad%n' # author date |
| 17 | + '%cn%n' # committer name |
| 18 | + '%ce%n' # committer email |
| 19 | + '%cd%n' # committer date |
| 20 | + '%D%n' # tag |
| 21 | + '%s%n' # subject |
| 22 | + '%b%n' + MARKER # body |
| 23 | + ) |
| 24 | + |
| 25 | + COMMAND = ['git', 'log', '--tags', '--date=raw', '--format=' + FORMAT] |
| 26 | + |
| 27 | + def __init__(self, repository): |
| 28 | + self.repository = repository |
| 29 | + self.raw_log = self.get() |
| 30 | + self.commits = self.parse_commits() |
| 31 | + |
| 32 | + def get(self): |
| 33 | + # remove enclosing b-quotes (b'' or b"") |
| 34 | + return str(check_output(self.COMMAND, cwd=self.repository))[2:-1].replace("\\'", "'") |
| 35 | + |
| 36 | + def parse_commits(self): |
| 37 | + lines = self.raw_log.split('\\n') |
| 38 | + size = len(lines) - 1 # don't count last blank line |
| 39 | + commits = [] |
| 40 | + pos = 0 |
| 41 | + while pos < size: |
| 42 | + commit = Commit( |
| 43 | + commit_hash=lines[pos], |
| 44 | + author_name=lines[pos+1], |
| 45 | + author_email=lines[pos+2], |
| 46 | + author_date=lines[pos+3], |
| 47 | + committer_name=lines[pos+4], |
| 48 | + committer_email=lines[pos+5], |
| 49 | + committer_date=lines[pos+6], |
| 50 | + tag=lines[pos+7], |
| 51 | + subject=lines[pos+8], |
| 52 | + body=[lines[pos+9]] |
| 53 | + ) |
| 54 | + commits.append(commit) |
| 55 | + nbl_index = 10 |
| 56 | + while lines[pos+nbl_index] != self.MARKER: |
| 57 | + commit.body.append(lines[pos+nbl_index]) |
| 58 | + nbl_index += 1 |
| 59 | + pos += nbl_index + 1 |
| 60 | + return commits |
| 61 | + |
| 62 | + |
| 63 | +class Commit: |
| 64 | + def __init__(self, commit_hash, |
| 65 | + author_name=None, author_email=None, author_date=None, |
| 66 | + committer_name=None, committer_email=None, committer_date=None, |
| 67 | + tag=None, subject=None, body=None): |
| 68 | + self.commit_hash = commit_hash |
| 69 | + self.author_name = author_name |
| 70 | + self.author_email = author_email |
| 71 | + self.author_date = author_date |
| 72 | + self.committer_name = committer_name |
| 73 | + self.committer_email = committer_email |
| 74 | + self.committer_date = committer_date |
| 75 | + self.tag = tag |
| 76 | + self.subject = subject |
| 77 | + self.body = body or [] |
| 78 | + |
| 79 | + |
| 80 | +if __name__ == '__main__': |
| 81 | + commits = GitLog('example2').commits |
| 82 | + template = env.get_template('changelog.md') |
| 83 | + rendered = template.render(commits=commits) |
| 84 | + with open('output.md', 'w') as stream: |
| 85 | + stream.write(rendered) |
| 86 | + for commit in commits: |
| 87 | + print(commit.subject) |
| 88 | + sys.exit(0) |
0 commit comments