In this article I describe my approach to keeping some of my Perl repositories as clean and as tidy as they can be.

I use Git to track changes in my code and files. Git repositories contain hooks which can be called prior to a commit. By using a pre-commit hook, one can perform specific actions on the committed files (or all files in the repository), and/or inhibit the commit from happening.

My ~/.perltidyrc is as simple as this:

$ cat ~/.perltidyrc 
-ce    # cuddle elses
-l=100 # max 100 columns
-i=4   # 4 spaces/indent</pre>

I employ two kinds of pre-commit hooks for tidying up the code, depending on whether the Perl version on my machine is threaded or not.

For a threaded Perl

For a threaded Perl, I use a custom-built program ~/bin/tidyup.pl to tidy up all .pl and .pm files in the repository, before actually performing a commit.

This relies on the threaded Perl tidier I developed, which is available under BSD license at tidyup.pl.txt. It uses Perl::Tidy, Text::Diff and threads. It can be saved in ~/bin/ (assuming your $PATH contains it) to be used either standalone or as part of the commit hook.

The script launched without any parameter will simply search for all Perl files (.pl, .pm) in the current directory, recursively, and print the tidiness status of each.

When the script is launched with a true parameter, it will instead tidy up all the Perl files which are not tidy.

Choose a victim Perl project controlled by Git, and input the following in its .git/hooks/pre-commit:

$ cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
~/bin/tidyup.pl 1
EOF

Since the Git pre-commit hook launches the script with a true value, the files will always be tidied up before a commit.

If instead you want to abort the commit if the files are not tidy, just edit the .git/hooks/pre-commit file and remove the 1 parameter to the script.

The script uses threads to perform its operations rather quickly.

For a non-threaded Perl

On both my desktop and netbook machines I build Perl using perlbrew. The resulting Perl is not built with threads, so I use another construct to keep the files tidy: a bash script. This approach can be much slower than the above script, but still works.

The differences in execution time are minimal for small projects, but grow larger with the number of files being tidied. In this case, perltidy is invoked for each .pl and .pm file in the repository. For each of these files perltidy is launched, which means that a new Perl interpreter is loaded in memory and modules loaded, then the file is tidied and the program exits.

The bash script in .git/hooks/pre-commit is simply:

#!/bin/bash
find . -type f -name '*.pl' -or -name '*.pm' | \
    xargs -I{} -P4 sh -c 'perltidy -b {}'

Nothing fancy, but it does do the job ;)