UNPKG

6.91 kBMarkdownView Raw
1# grunt-githooks
2
3> A Grunt plugin to help bind Grunt tasks to Git hooks
4
5## Getting Started
6This plugin requires Grunt `~0.4.1`
7
8If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
9
10```shell
11npm install grunt-githooks --save-dev
12```
13
14Once the plugin has been installed, it may be enabled inside your Gruntfile with this line of JavaScript:
15
16```js
17grunt.loadNpmTasks('grunt-githooks');
18```
19
20## The "githooks" task
21
22### Overview
23In your project's Gruntfile, add a section named `githooks` to the data object passed into `grunt.initConfig()`.
24
25```js
26grunt.initConfig({
27 githooks: {
28 options: {
29 // Task-specific options go here.
30 },
31 all: {
32 options: {
33 // Target-specific options go here
34 },
35 // Hook definitions go there
36 }
37 },
38})
39```
40
41#### Defining a few hooks
42
43Hooks are listed as keys of your target configuration.
44**Any key other than `option`** is considered the name of a hook you want to create.
45The simplest way to define a hook is to provide a **space-separated list of the tasks you want the hook to run as the value**.
46
47For example:
48```js
49grunt.initConfig({
50 githooks: {
51 all: {
52 // Will run the jshint and test:unit tasks at every commit
53 'pre-commit': 'jshint test:unit',
54 }
55 }
56});
57```
58
59The plugin warns you if the name matches one of the [hooks announced in the Git documentation](https://www.kernel.org/pub/software/scm/git/docs/githooks.html).
60It will still create the hook, though, in case Git introduces new hooks in the future.
61
62#### Hook specific options
63
64If you need to override a few options for a given hook only, you can *use and Object instead of a String*.
65The `taskNames` property will then correspond to the tasks you want to run.
66Any other key will be merged into the options.
67
68```js
69grunt.initConfig({
70 githooks: {
71 all: {
72 options: {
73 template: 'path/to/a/template'
74 },
75 // Will bind the jshint and test:unit tasks
76 // with the template specified above
77 'pre-commit': 'jshint test:unit',
78
79 // Will bind the bower:install task
80 // with a specific template
81 'post-merge': {
82 taskNames: 'bower:install',
83 template: 'path/to/another/template'
84 }
85 }
86 }
87})
88```
89
90#### Working with existing hooks
91
92If you happen to have existing hooks in your hook folder, the plugin *appends the code launching Grunt* at the end of your hooks.
93You can also insert marker comments in your hooks to specify exactly where you want them inserted.
94Your existing hook would look something like this:
95
96```js
97// Some code run before Grunt starts
98
99// GRUNT-GITHOOKS START // GRUNT-GITHOOKS END
100
101// Some code run after Grunt starts
102```
103
104The markers get automatically inserted when the plugin appends code, so hooks get updated cleanly the next time you run `grunt githooks`.
105
106#### Customising hook output
107
108By default, the plugin generate NodeJS scripts for the hooks.
109Reasonning behind this is that creating Shell scripts won't work well for people using Windows.
110Plus, NodeJS is already installed as Grunt kinda needs it.
111However, you're not tied to it and you can customise the generated script entirely. In case of a Shell script:
112
113```js
114grunt.initConfig({
115 githooks: {
116 all: {
117 options: {
118 // Customize the hashbang to say 'Shell script'
119 hashbang: '#!/bin/sh',
120 // Plugin comes in with a sheel script template already. Handy, innit?
121 template: './node_modules/grunt-githooks/templates/shell.hb',
122 // Customize the markers so comments start with #
123 startMarker: '## LET THE FUN BEGIN',
124 endMarker: '## PARTY IS OVER'
125 }
126 }
127 }
128});
129```
130
131In the template, you've got access to the following variables:
132
133 - *task*: String with the name of the tasks to be run
134 - *args*: String with the list of arguments to provide to the task
135 - *gruntfileDirectory*: Absolute path to the directory containing the Gruntfile
136 - *preventExit*: Flag telling if the hook should avoid exiting after the grunt task
137
138#### Extending the plugin
139
140Pretty annoying when you're using a library that's missing the exact extension point you need to tweak its functionalities?
141`grunt-githooks` is based on a lot of small functions and most of them are exposed so you can override them.
142If you need feel, free to tinker with the internals (at your own risk though ;)). Could be something along:
143
144```js
145var gruntGithooks = require('grunt-githooks/tasks/githooks');
146
147var originalFunction = gruntGithooks.internals.Hook.prototype.getHookContent;
148gruntGithooks.internals.Hook.prototype.getHookContent = function () {
149 console.log('Loading content of an existing hook');
150 originalFunction.apply(this, arguments);
151};
152```
153
154### Options
155
156#### hashbang
157Type: `String`
158Defaults: `'#!/usr/bin/env node'`
159
160The hashbang that will be used at the top of the hook script file. If a hook
161already exist, the hashbang will be used to check if its ok to append/insert
162code in it (to avoid inserting Node code in a Python hook for example).
163
164#### template
165Type: `String`
166
167Path to the Handlebars template used to generate the code that will run Grunt
168in the hook. Default template is the `node.js.hb` file located in the `templates` folder of the plugin.
169It also contains a `shell.hb` file with the template for a shell script hook.
170
171#### startMarker
172Type: `String`
173Default: `'// GRUNT-GITHOOKS START'`
174
175#### endMarker
176Type: `String`
177Default: `'// GRUNT-GITHOOKS END'`
178
179`startMarker` and `endMarker` are markers the plugin use to know where to insert code if a hook already exist.
180If the existing hook doesn't have these markers, the code will simply be appended.
181
182#### preventExit
183Type: `Boolean`
184Default `false`
185
186By default, the inserted code will exit the process after Grunt has run, using a -1 exit code if the task(s) failed.
187If you're inserting the code running Grunt in the middle of an existing hook,
188you might want to disable this so any code after what was inserted by the plugin runs.
189
190#### dest
191Type: `String`
192Default value: `'.git/hooks'`
193
194You probably won't use this one much, but in case you need to put the hooks somewhere else than in the `.git/hooks` folder, this is the option to use.
195
196
197## Contributing
198
199In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
200
201
202## Release History
203
204 - 2013-10-05 v0.2.0 New *args* option to specify arguments to hooked task. Bugfix to allow running grunt when the Gruntfile is not at the root of the project.
205 - 2013-09-02 v0.1.0 Initial functionnalities