1e01aa904Sopenharmony_ci#!/usr/bin/env python 2e01aa904Sopenharmony_ci# SPDX-License-Identifier: LGPL-2.0-or-later 3e01aa904Sopenharmony_ci# 4e01aa904Sopenharmony_ci# -*- mode: python -*- 5e01aa904Sopenharmony_ci# 6e01aa904Sopenharmony_ci# This python program has been copied from 7e01aa904Sopenharmony_ci# https://github.com/GNOME/gnet/blob/master/gen-changelog.py 8e01aa904Sopenharmony_ci# 9e01aa904Sopenharmony_ci# It has been authored by Edward Hervey, of GStreamer fame. I have 10e01aa904Sopenharmony_ci# asked his permission to copy it and re-use it here, as part of the 11e01aa904Sopenharmony_ci# Libabigail project. He granted me the permission to distribute the 12e01aa904Sopenharmony_ci# program under the terms of the GNU Lesser Public License as 13e01aa904Sopenharmony_ci# published by the Free Software Foundaion; either version 2, or (at 14e01aa904Sopenharmony_ci# your option) any later version. 15e01aa904Sopenharmony_ci# 16e01aa904Sopenharmony_ci 17e01aa904Sopenharmony_ciimport sys 18e01aa904Sopenharmony_ciimport subprocess 19e01aa904Sopenharmony_ciimport re 20e01aa904Sopenharmony_ci 21e01aa904Sopenharmony_ci# Makes a GNU-Style ChangeLog from a git repository 22e01aa904Sopenharmony_ci# Handles git-svn repositories also 23e01aa904Sopenharmony_ci 24e01aa904Sopenharmony_ci# Arguments : same as for git log 25e01aa904Sopenharmony_cirelease_refs={} 26e01aa904Sopenharmony_ci 27e01aa904Sopenharmony_cidef process_commit(lines, files): 28e01aa904Sopenharmony_ci # DATE NAME 29e01aa904Sopenharmony_ci # BLANK LINE 30e01aa904Sopenharmony_ci # Subject 31e01aa904Sopenharmony_ci # BLANK LINE 32e01aa904Sopenharmony_ci # ... 33e01aa904Sopenharmony_ci # FILES 34e01aa904Sopenharmony_ci fileincommit = False 35e01aa904Sopenharmony_ci lines = [x.strip() for x in lines if x.strip() and not x.startswith('git-svn-id')] 36e01aa904Sopenharmony_ci files = [x.strip() for x in files if x.strip()] 37e01aa904Sopenharmony_ci for l in lines: 38e01aa904Sopenharmony_ci if l.startswith('* '): 39e01aa904Sopenharmony_ci fileincommit = True 40e01aa904Sopenharmony_ci break 41e01aa904Sopenharmony_ci 42e01aa904Sopenharmony_ci top_line = lines[0] 43e01aa904Sopenharmony_ci subject_line_index = 0 if lines[1].startswith('*') else 1; 44e01aa904Sopenharmony_ci first_cl_body_line_index = 0; 45e01aa904Sopenharmony_ci 46e01aa904Sopenharmony_ci for i in range(1, len(lines)): 47e01aa904Sopenharmony_ci if lines[i].startswith('*'): 48e01aa904Sopenharmony_ci first_cl_body_line_index = i 49e01aa904Sopenharmony_ci break; 50e01aa904Sopenharmony_ci 51e01aa904Sopenharmony_ci # Clean up top line of ChangeLog entry: 52e01aa904Sopenharmony_ci fields = top_line.split(' ') 53e01aa904Sopenharmony_ci 54e01aa904Sopenharmony_ci # 1. remove the time and timezone stuff in "2008-05-13 07:10:28 +0000 name" 55e01aa904Sopenharmony_ci if fields[2].startswith('+') or fields[2].startswith('-'): 56e01aa904Sopenharmony_ci del fields[2] 57e01aa904Sopenharmony_ci if fields[1][2] == ':' and fields[1][5] == ':': 58e01aa904Sopenharmony_ci del fields[1] 59e01aa904Sopenharmony_ci 60e01aa904Sopenharmony_ci # 2. munge at least my @src.gnome.org e-mail address... 61e01aa904Sopenharmony_ci if fields[-1] == '<tpm@src.gnome.org>': 62e01aa904Sopenharmony_ci fields[-1] = '<tim@centricular.net>' 63e01aa904Sopenharmony_ci 64e01aa904Sopenharmony_ci top_line = ' '.join(fields) 65e01aa904Sopenharmony_ci print(top_line.strip()) 66e01aa904Sopenharmony_ci print() 67e01aa904Sopenharmony_ci 68e01aa904Sopenharmony_ci if subject_line_index > 0: 69e01aa904Sopenharmony_ci print('\t%s' % lines[subject_line_index].strip()) 70e01aa904Sopenharmony_ci 71e01aa904Sopenharmony_ci if not fileincommit: 72e01aa904Sopenharmony_ci for f in files: 73e01aa904Sopenharmony_ci print('\t* %s:' % f.strip()) 74e01aa904Sopenharmony_ci print() 75e01aa904Sopenharmony_ci 76e01aa904Sopenharmony_ci if first_cl_body_line_index > 0: 77e01aa904Sopenharmony_ci for l in lines[first_cl_body_line_index:]: 78e01aa904Sopenharmony_ci if l.startswith('Signed-off-by:'): 79e01aa904Sopenharmony_ci continue 80e01aa904Sopenharmony_ci print('\t%s' % l.strip()) 81e01aa904Sopenharmony_ci print() 82e01aa904Sopenharmony_ci 83e01aa904Sopenharmony_cidef output_commits(): 84e01aa904Sopenharmony_ci cmd = ['git', 'log', '--pretty=format:--START-COMMIT--%H%n%ai %an <%ae>%n%n%s%n%b%n--END-COMMIT--', 85e01aa904Sopenharmony_ci '--date=short', '--name-only'] 86e01aa904Sopenharmony_ci 87e01aa904Sopenharmony_ci start_tag = find_start_tag() 88e01aa904Sopenharmony_ci 89e01aa904Sopenharmony_ci if start_tag is None: 90e01aa904Sopenharmony_ci cmd.extend(sys.argv[1:]) 91e01aa904Sopenharmony_ci else: 92e01aa904Sopenharmony_ci cmd.extend(["%s..HEAD" % (start_tag)]) 93e01aa904Sopenharmony_ci 94e01aa904Sopenharmony_ci p = subprocess.Popen(args=cmd, shell=False, 95e01aa904Sopenharmony_ci stdout=subprocess.PIPE, 96e01aa904Sopenharmony_ci text=True) 97e01aa904Sopenharmony_ci buf = [] 98e01aa904Sopenharmony_ci files = [] 99e01aa904Sopenharmony_ci filemode = False 100e01aa904Sopenharmony_ci for lin in p.stdout.readlines(): 101e01aa904Sopenharmony_ci if lin.startswith("--START-COMMIT--"): 102e01aa904Sopenharmony_ci if buf != []: 103e01aa904Sopenharmony_ci process_commit(buf, files) 104e01aa904Sopenharmony_ci hash = lin[16:].strip() 105e01aa904Sopenharmony_ci try: 106e01aa904Sopenharmony_ci rel = release_refs[hash] 107e01aa904Sopenharmony_ci print("=== release %d.%d.%d ===\n" % (int(rel[0]), int(rel[1]), int(rel[2]))) 108e01aa904Sopenharmony_ci except: 109e01aa904Sopenharmony_ci pass 110e01aa904Sopenharmony_ci buf = [] 111e01aa904Sopenharmony_ci files = [] 112e01aa904Sopenharmony_ci filemode = False 113e01aa904Sopenharmony_ci elif lin.startswith("--END-COMMIT--"): 114e01aa904Sopenharmony_ci filemode = True 115e01aa904Sopenharmony_ci elif filemode == True: 116e01aa904Sopenharmony_ci files.append(lin) 117e01aa904Sopenharmony_ci else: 118e01aa904Sopenharmony_ci buf.append(lin) 119e01aa904Sopenharmony_ci if buf != []: 120e01aa904Sopenharmony_ci process_commit(buf, files) 121e01aa904Sopenharmony_ci 122e01aa904Sopenharmony_cidef get_rel_tags(): 123e01aa904Sopenharmony_ci # Populate the release_refs dict with the tags for previous releases 124e01aa904Sopenharmony_ci reltagre = re.compile("^([a-z0-9]{40}) refs\/tags\/GNET-([0-9]+)[-_.]([0-9]+)[-_.]([0-9]+)") 125e01aa904Sopenharmony_ci 126e01aa904Sopenharmony_ci cmd = ['git', 'show-ref', '--tags', '--dereference'] 127e01aa904Sopenharmony_ci p = subprocess.Popen(args=cmd, shell=False, 128e01aa904Sopenharmony_ci stdout=subprocess.PIPE, 129e01aa904Sopenharmony_ci text=True) 130e01aa904Sopenharmony_ci for lin in p.stdout: 131e01aa904Sopenharmony_ci match = reltagre.search(lin) 132e01aa904Sopenharmony_ci if match: 133e01aa904Sopenharmony_ci (sha, maj, min, nano) = match.groups() 134e01aa904Sopenharmony_ci release_refs[sha] = (maj, min, nano) 135e01aa904Sopenharmony_ci 136e01aa904Sopenharmony_cidef find_start_tag(): 137e01aa904Sopenharmony_ci starttagre = re.compile("^([a-z0-9]{40}) refs\/tags\/CHANGELOG_START") 138e01aa904Sopenharmony_ci cmd = ['git', 'show-ref', '--tags'] 139e01aa904Sopenharmony_ci p = subprocess.Popen(args=cmd, shell=False, 140e01aa904Sopenharmony_ci stdout=subprocess.PIPE, 141e01aa904Sopenharmony_ci text=True) 142e01aa904Sopenharmony_ci for lin in p.stdout: 143e01aa904Sopenharmony_ci match = starttagre.search(lin) 144e01aa904Sopenharmony_ci if match: 145e01aa904Sopenharmony_ci return match.group(1) 146e01aa904Sopenharmony_ci return None 147e01aa904Sopenharmony_ci 148e01aa904Sopenharmony_ciif __name__ == "__main__": 149e01aa904Sopenharmony_ci get_rel_tags() 150e01aa904Sopenharmony_ci output_commits() 151