### Flavio Poletti

Irreducible Perler.

# Changes, nags and git hooks

I use Dist::Zilla with a few plugins, including NextRelease and Git::Check. I was always nagged by the fact that committing actually left the Changes file uncommitted… until now.

First of all, I discovered that there was no reason why I should have to be nagged at all. The documentation about Dist::Zilla is pretty clear that both plugins run at the same stage, so it’s only a matter of proper ordering1. Guess what? My dzil file always has the wrong order!

The funny thing is that today I had some kind of epiphany and I understood why this thing was nagging me. It was supposed to do so! It was designed to do so! In this way, I would be nagged to actually populate the Changes file with something meaningful before doing a release, right?

Now, of course this was not the intended behaviour (again, see here) and there are better ways to ensure that Changes is populated in some meaningful way before doing a release (Dist::Zilla::Plugin::CheckChangesHasContent being my new plugin of election for this task), but in the excitement for my epiphany I also figured that presto!, I need a git hook to ensure that I don’t commit Changes without intention (yes, I tend to git commit -a a bit too much).

This is the pre-commit hook that I came out with:

#!/bin/bash

target='Changes'

seen_target=0
skip=1
while read omode nmode ohash nhash changetype filename; do
[ "$filename" == "$target" ] && seen_target=1
if [ $skip -ne 0 ]; then skip=0 # skip the first item only else [$seen_target -eq 0 ] && continue
echo "ERROR - '\$target' MUST be committed alone"
exit 1
fi
done < <(git diff-index --cached HEAD)

exit 0

Now, after the real enlightenment came (i.e. finding DZP::CheckChangesHasContent) this is obviously not needed any more… but I’ll keep it around should the need arise.

While using DZP::CheckChangesHasContent, I figured that the first addition of some change to the file would spoil all my efforts to remember about Changes before the release. My hands were much faster than my brains, again: I was about to propose a patch for the plugin when I simply read the documentation:

It looks for an unindented line starting with the version to be released. It then looks for any text from that line until the next unindented line (or the end of the file), ignoring whitespace. […] If you had nothing but whitespace between [them], the release would be halted.

So, it is sufficient to add a non-indented line immediately after the {{NEXT}} string to make sure the plugin will complain, e.g.:

{{NEXT}}
CHECK YOUR CHANGES AND REMOVE THIS LINE!
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

Now of course I would like that line to be added automatically… this time, before forking the relevant plugin, I’ll try to think if there’s some already available way to do that!

## Update

There can be a workaround to obtain something very similar to the above… It is sufficient to set the format parameter of the NextRelease plugin to something like this:

[NextRelease]
format = Changes for My::Module:%n%n%-9v %{yyyy-MM-dd HH:mm:ssZZZZZ VVVV}d%{ (TRIAL RELEASE)}T

i.e. the same format as the default one, but with some meaningful introduction text (Changes for... in our example, followed by two newlines). In this way, the following Changes file:

{{NEXT}}
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

will generate this for the release package:

Changes for My::Module:

2.0  1990--11-09 07:45:00 Europe/Rome
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

and will be updated into this:

{{NEXT}}

Changes for My::Module:

2.0  1990--11-09 07:45:00 Europe/Rome
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

At this point, it will be sufficient to add new items below the introduction line, like this:

{{NEXT}}

Changes for My::Module:
- This happened here
- This happened there

2.0  1990--11-09 07:45:00 Europe/Rome
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

in order to keep DZP::CheckChangesHasContent complain until the intro line is removed from the file, like this:

{{NEXT}}
- This happened here
- This happened there

2.0  1990--11-09 07:45:00 Europe/Rome
- I did this
- I did that

1.0  1972-11-09 07:45:00 Europe/Rome
- Born

We’re ready for a new release now!

1. For those of you that are too lazy to click on the link and read through the page, you are supposed to put NextRelease before Git::Check.