[git-buildpackage] [PATCH] dch: fake timestamp
Raphael Lisicki
raphael.lisicki at siemens.com
Mon Oct 24 12:25:41 CEST 2022
Allow to derive timestamp for changelog from commit to obtain reproducible
changelog files
---
gbp/deb/changelog.py | 14 ++++++++++++--
gbp/scripts/dch.py | 26 ++++++++++++++++----------
2 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/gbp/deb/changelog.py b/gbp/deb/changelog.py
index fdee1a9d..0f2fe575 100644
--- a/gbp/deb/changelog.py
+++ b/gbp/deb/changelog.py
@@ -19,6 +19,8 @@
import email
import os
import subprocess
+from datetime import datetime
+from dateutil.parser import isoparse
from gbp.command_wrappers import Command
@@ -234,7 +236,7 @@ class ChangeLog(object):
@staticmethod
def spawn_dch(msg=[], author=None, email=None, newversion=False, version=None,
- release=False, distribution=None, dch_options=None):
+ release=False, distribution=None, dch_options=None, faketime=None):
"""
Spawn dch
@@ -285,7 +287,15 @@ class ChangeLog(object):
args.append('[[[insert-git-dch-commit-message-here]]]')
else:
args.append('')
- dch = Command('debchange', args, extra_env=env, capture_stderr=True)
+ dch = ""
+ if faketime:
+ (timestamp, timezone) = faketime.split(" ")
+ datestring = datetime.fromtimestamp(int(timestamp)).isoformat() + timezone
+ isodate = isoparse(datestring)
+ args = ["-f", isodate.isoformat(sep=" "), "debchange"] + args
+ dch = Command('faketime', args, extra_env=env, capture_stderr=True)
+ else:
+ dch = Command('debchange', args, extra_env=env, capture_stderr=True)
dch.run_error = Command._f("Dch failed: {stderr_or_reason}")
dch([], quiet=True)
if msg:
diff --git a/gbp/scripts/dch.py b/gbp/scripts/dch.py
index ff4fb95c..19f59c97 100644
--- a/gbp/scripts/dch.py
+++ b/gbp/scripts/dch.py
@@ -78,7 +78,7 @@ def get_author_email(repo, use_git_config):
return author, email
-def fixup_section(repo, use_git_author, options, dch_options):
+def fixup_section(repo, use_git_author, options, dch_options, timestamp=None):
"""
Fixup the changelog header and trailer's committer and email address
@@ -108,7 +108,7 @@ def fixup_section(repo, use_git_author, options, dch_options):
break
else:
opts.append(mainttrailer_opts[0])
- ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options + opts)
+ ChangeLog.spawn_dch(msg='', author=author, email=email, dch_options=dch_options + opts, faketime=timestamp)
def snapshot_version(version):
@@ -174,17 +174,17 @@ def mangle_changelog(changelog, cp, snapshot=''):
raise GbpError("Error mangling changelog %s" % e)
-def do_release(changelog, repo, cp, use_git_author, dch_options):
+def do_release(changelog, repo, cp, use_git_author, dch_options, timestamp=None):
"""Remove the snapshot header and set the distribution"""
author, email = get_author_email(repo, use_git_author)
(release, snapshot) = snapshot_version(cp['Version'])
if snapshot:
cp['MangledVersion'] = release
mangle_changelog(changelog, cp)
- cp.spawn_dch(release=True, author=author, email=email, dch_options=dch_options)
+ cp.spawn_dch(release=True, author=author, email=email, dch_options=dch_options, faketime=timestamp)
-def do_snapshot(changelog, repo, next_snapshot):
+def do_snapshot(changelog, repo, next_snapshot, timestamp=None):
"""
Add new snapshot banner to most recent changelog section.
The next snapshot number is calculated by eval()'ing next_snapshot.
@@ -207,11 +207,12 @@ def parse_commit(repo, commitid, opts, last_commit=False):
commit_info = repo.get_commit_info(commitid)
author = commit_info['author'].name
email = commit_info['author'].email
+ date = commit_info['author'].date
format_entry = user_customizations.get('format_changelog_entry')
if not format_entry:
format_entry = dch.format_changelog_entry
entry = format_entry(commit_info, opts, last_commit=last_commit)
- return entry, (author, email)
+ return entry, (author, email, date)
def guess_documented_commit(cp, repo, tagformat):
@@ -376,6 +377,8 @@ def build_parser(name):
help="mark as release")
version_group.add_option("-S", "--snapshot", action="store_true", dest="snapshot", default=False,
help="mark as snapshot build")
+ version_group.add_option("--fake-timestamp", action="store_true", dest="fake_timestamp", default=False,
+ help="set debian changelog timestamp to same value as last commit, allows to reproduce snapshots")
version_group.add_option("-D", "--distribution", dest="distribution", help="Set distribution")
version_group.add_option("--force-distribution", action="store_true", dest="force_distribution", default=False,
help="Force the provided distribution to be used, "
@@ -543,15 +546,17 @@ def main(argv):
version_change['version'] = v
i = 0
+ date = None
for c in commits:
i += 1
parsed = parse_commit(repo, c, options,
last_commit=(i == len(commits)))
- commit_msg, (commit_author, commit_email) = parsed
+ commit_msg, (commit_author, commit_email, commit_date) = parsed
if not commit_msg:
# Some commits can be ignored
continue
+ date = commit_date
if add_section:
# Add a section containing just this message (we can't
# add an empty section with dch)
@@ -578,13 +583,14 @@ def main(argv):
dch_options=dch_options)
fixup_section(repo, use_git_author=options.use_git_author, options=options,
- dch_options=dch_options)
+ dch_options=dch_options, timestamp=date if options.fake_timestamp else None)
+
if options.release:
do_release(changelog, repo, cp, use_git_author=options.use_git_author,
- dch_options=dch_options)
+ dch_options=dch_options, timestamp=date if options.fake_timestamp else None)
elif options.snapshot:
- (snap, commit, version) = do_snapshot(changelog, repo, options.snapshot_number)
+ (snap, commit, version) = do_snapshot(changelog, repo, options.snapshot_number, date if options.fake_timestamp else None)
gbp.log.info("Changelog %s (snapshot #%d) prepared up to %s" % (version, snap, commit[:7]))
if editor_cmd:
--
2.25.1
More information about the git-buildpackage
mailing list