[git-buildpackage] [PATCH] dch: fake timestamp
Guido Günther
agx at sigxcpu.org
Sun Dec 4 13:02:21 CET 2022
Hi Raphael,
On Mon, Oct 24, 2022 at 12:25:01PM +0200, Raphael Lisicki wrote:
>
> Allow to derive timestamp for changelog from commit to obtain reproducible
> changelog files
That's a great idea. Could you update the manpage as well and add a test?
Cheers,
-- Guido
> ---
> 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 you do:
date = commit_date if options.fake_timestamp else None
> 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)
> +
you should be able to drop the condition here
>
> 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)
here
> 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)
and here - improving readability.
Cheer,
-- Guido
> gbp.log.info("Changelog %s (snapshot #%d) prepared up to %s" % (version, snap, commit[:7]))
>
> if editor_cmd:
> --
> 2.25.1
>
> _______________________________________________
> git-buildpackage mailing list
> git-buildpackage at lists.sigxcpu.org
> http://lists.sigxcpu.org/mailman/listinfo/git-buildpackage
>
More information about the git-buildpackage
mailing list