Introduction
Pre-commit is a framework for managing and maintaining multi-language pre-commit hooks. Developers write a hooks to be triggered so that some preliminary/useful job gets done before updates arrived to your git repo. The idea is quite old, but pre-commit lets install and integrate hooks into existed git repos with minimal efforts.
Writing hooks with sparrow
Sparrow is a universal automation tool and I found it quite easy to use sparrow to write hooks for pre-commit framework. Let me show how. Say I need to run prove tests for Perl6 code.
The code of hook is trivial and look like:
prove -vr -e 'perl6 -Ilib' t/
Let’s wrap this script into sparrow plugin, here are few simple steps:
1. Write a story:
$ cat story.bash set -x set -e path=$(config path) echo path is: $path cd $path prove -vr -e 'perl6 -Ilib' t/
A quick remark here. We pass a Perl6 project directory location explicitly by --path
parameter as absolute file path. This requirement is due to sparrow does not preserve a current working directory when executing plugins.
2. Leave story check file empty, as we don’t need an extra checks here:
$ touch story.check
3. And create plugin meta file:
$ cat sparrow.json { "name" : "perl6-prove", "description" : "pre-commit hook - runs prove for Perl6 project", "version" : "0.0.1", "category" : "utilities", "url" : "https://github.com/melezhik/perl6-prove" }
4. Now we can upload our freshly backed plugin to SparrowHub:
$ sparrow plg upload
Using sparrow plugin in pre-commit hooks
First of all we need to install sparrow plugins at our system and see that our hook works on a test Perl6 project.
Install the plugin:
$ sparrow plg install perl6-prove
Set up git repository and project files:
$ git init $ ... # Create files and directories, git add, and so on ..
Create a simple Perl6 test:
$ cat t/00.t use v6; use Test; plan 1; ok 1, 'I am ok';
Then we need to set up pre-commit hooks yaml.
Our pre-commit hook yaml will be:
$ cat .pre-commit-config.yaml - repo: local hooks: - id: perl6-prove name: perl6-prove entry: bash -c "sparrow plg run perl6-prove --param path=$PWD" language: system always_run: true files: ''
Here we use so called “local” repository and language as”system” bear in mind that sparrow comes as external system command.
Now let’s commit our changes to trigger hook execution:
$ git commit -a -mtest-commit perl6-prove..............................................................Passed [master 98cf098] test-commit 1 file changed, 6 insertions(+) create mode 100644 t/00.t
You can also trigger the hook directly not committing anything:
$ pre-commit run perl6-prove --verbose [WARNING] Unstaged files detected. [INFO] Stashing unstaged files to /home/vagrant/.pre-commit/patch1489306073. [perl6-prove] perl6-prove................................................Passed hookid: perl6-prove [p] perl6-prove at 2017-03-12 08:07:53 path is: /home/vagrant/projects/pre-commit-test t/00.t .. 1..1 ok 1 - I am ok ok All tests successful. Files=1, Tests=1, 1 wallclock secs ( 0.02 usr 0.00 sys + 0.16 cusr 0.03 csys = 0.21 CPU) Result: PASS ok scenario succeeded STATUS SUCCEED
In the end of this post I am going to take some summary.
Implementing pre-commit hooks via Sparrow plugins
Roughly speaking pre-commit framework supports two types of plugins – external ones, which to be installed into the system manually and ones located in github repositories and installed by pre-commit itself.
I see a possible benefits sparrow can bring you when developing hook’s scripts as sparrow ( external ) plugins:
– Sparrow plugins are external ones and highly decoupled from hooks/project structure.
– Indeed they are versioned and packaged pieces of software. One can maintain and release new versions of plugins in a way predictable and transparent for end user.
– You can always install/remove/upgrade/downgrade versions of sparrow plugin independently on pre-commit framework itself.
– Sparrow provides reasonable alternative to manage hook’s scripts dependencies, so that sparrow takes care about dependencies resolution during plugin installation. It’s CPAN/carton for Perl5 and RubyGems/bundler for Ruby. Let me know if you need other package managers support.
Rregards and have fun with your automation!
Leave a Reply