gcc/contrib/gcc-changelog/git_update_version.py
Pierre-Marie de Rodat bb07057a31 gcc-changelog: remove file descriptor leaks
Currently, running gcc-changelog's unit tests may clutter the output
with tons of warnings such as:

    .../contrib/gcc-changelog/git_email.py:40: ResourceWarning: unclosed
    file <_io.TextIOWrapper name='/tmp/tmpt5okd4qp.patch' mode='r'
    encoding='UTF-8'>
      lines = open(self.filename).read().splitlines()
    ResourceWarning: Enable tracemalloc to get the object allocation
    traceback

This commit fixes these leaks, which restores a clean testsuite output.

contrib/

	* gcc-changelog/git_update_version.py: Close file objects after
	use.
	* gcc-changelog/git_email.py: Likewise.
	* gcc-changelog/test_email.py: Likewise.
2020-05-26 17:45:38 +02:00

126 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3, or (at your option) any later
# version.
#
# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. */
import argparse
import datetime
import os
from git import Repo
from git_repository import parse_git_revisions
current_timestamp = datetime.datetime.now().strftime('%Y%m%d\n')
def read_timestamp(path):
with open(path) as f:
return f.read()
def prepend_to_changelog_files(repo, folder, git_commit, add_to_git):
if not git_commit.success:
for error in git_commit.errors:
print(error)
raise AssertionError()
for entry, output in git_commit.to_changelog_entries(use_commit_ts=True):
full_path = os.path.join(folder, entry, 'ChangeLog')
print('writting to %s' % full_path)
if os.path.exists(full_path):
with open(full_path) as f:
content = f.read()
else:
content = ''
with open(full_path, 'w+') as f:
f.write(output)
if content:
f.write('\n\n')
f.write(content)
if add_to_git:
repo.git.add(full_path)
active_refs = ['master', 'releases/gcc-8', 'releases/gcc-9', 'releases/gcc-10']
parser = argparse.ArgumentParser(description='Update DATESTAMP and generate '
'ChangeLog entries')
parser.add_argument('-g', '--git-path', default='.',
help='Path to git repository')
parser.add_argument('-p', '--push', action='store_true',
help='Push updated active branches')
parser.add_argument('-d', '--dry-mode',
help='Generate patch for ChangeLog entries and do it'
' even if DATESTAMP is unchanged; folder argument'
' is expected')
args = parser.parse_args()
repo = Repo(args.git_path)
origin = repo.remotes['origin']
for ref in origin.refs:
assert ref.name.startswith('origin/')
name = ref.name[len('origin/'):]
if name in active_refs:
if name in repo.branches:
branch = repo.branches[name]
else:
branch = repo.create_head(name, ref).set_tracking_branch(ref)
print('=== Working on: %s ===' % branch, flush=True)
origin.pull(rebase=True)
branch.checkout()
print('branch pulled and checked out')
assert not repo.index.diff(None)
commit = branch.commit
commit_count = 1
while commit:
if (commit.author.email == 'gccadmin@gcc.gnu.org'
and commit.message.strip() == 'Daily bump.'):
break
commit = commit.parents[0]
commit_count += 1
print('%d revisions since last Daily bump' % commit_count)
datestamp_path = os.path.join(args.git_path, 'gcc/DATESTAMP')
if (read_timestamp(datestamp_path) != current_timestamp
or args.dry_mode):
commits = parse_git_revisions(args.git_path, '%s..HEAD'
% commit.hexsha)
for git_commit in reversed(commits):
prepend_to_changelog_files(repo, args.git_path, git_commit,
not args.dry_mode)
if args.dry_mode:
diff = repo.git.diff('HEAD')
patch = os.path.join(args.dry_mode,
branch.name.split('/')[-1] + '.patch')
with open(patch, 'w+') as f:
f.write(diff)
print('branch diff written to %s' % patch)
repo.git.checkout(force=True)
else:
# update timestamp
print('DATESTAMP will be changed:')
with open(datestamp_path, 'w+') as f:
f.write(current_timestamp)
repo.git.add(datestamp_path)
repo.index.commit('Daily bump.')
if args.push:
repo.git.push('origin', branch)
print('branch is pushed')
else:
print('DATESTAMP unchanged')
print('branch is done\n', flush=True)