# Commitplease [![Travis](https://img.shields.io/travis/jzaefferer/commitplease.svg?maxAge=2592000)](http://travis-ci.org/jzaefferer/commitplease) [![npm](https://img.shields.io/npm/dm/commitplease.svg?maxAge=2592000)](https://www.npmjs.com/package/commitplease) [![npm](https://img.shields.io/npm/v/commitplease.svg?maxAge=2592000)](https://www.npmjs.com/package/commitplease) [![npm](https://img.shields.io/npm/l/commitplease.svg?maxAge=2592000)](https://www.npmjs.com/package/commitplease) This [node.js](http://nodejs.org/) module makes sure your git commit messages consistently follow one of these style guides: 1. [jQuery Commit Guidelines][1] 2. [AngularJS Commit Guidelines][2] You can also make customized validation rules based on those styles. ## Installation Commitplease can be installed locally or globally (or both): Repo-local install (adds a git hook that runs automatically upon `git commit`): ```js cd path/to/your/repo npm install commitplease --save-dev ``` Global install (adds a system-wide executable to be run manually): ```js npm install -g commitplease ``` A git version of 1.8.5 or newer is recommended. If you use `git commit --verbose`, it is required. Also, currently we do not support custom `core.commentchar`, so let us know if you set one. You could also install a global commitplease executable and put it into a `package.json` script or as a git hook of your choice. Here is an example with a `pre-push` hook: ``` #!/bin/sh npm run commitplease --silent ``` And `chmod +x .git/hooks/pre-push`. Now each time you do a `git push`, the hook will be checking **all** commits on current branch. ## Usage The following ways to begin a commit message are special and always valid: 1. `0.0.1` or any other semantic version 1. `WIP`, `Wip` or `wip` which means "work in progress" 1. `Merge branch [...]` or `Merge into ` 1. `fixup!` or `squash!`, as generated by `git commit --fixup` and `--squash`, but any content afterwards is accepted Other ways to make your commit messages special and bypass style checks are [described below](#skip-style-check). Non-special commit messages must follow one of the style guides ([jQuery Commit Guidelines][1] by default) ### Repo-local install Commit as usual. Git will trigger commitplease to check your commit message for errors. Invalid messages will prevent the commit, with details about what went wrong and a copy of the input. ### Global install Navigate to your repository and run the global commitplease executable. By default, it will check all the commit messages. Other examples include (just anything you can pass to `git log` really): | Use case | command | |----------|---------| | Check all commits on branch `master` | `commitplease master` | | Check all commits on branch `feature` that are not on `master` | `commitplease master..feature` | | Check all commits on current branch that are not on `master` | `commitplease master..HEAD` | | Check the latest 1 commit | `commitplease -1` | | Check all commits between `84991d` and `2021ce` | `commitplease 84991d..2021ce` | | Check all commits starting with `84991d` | `commitplease 84991d..` | [Here you can read][4] more about git commit ranges ## Setup You can configure commitplease from `package.json` of your project. Here are the options common for all style guidelines: ```json { "commitplease": { "limits": { "firstLine": "72", "otherLine": "80" }, "nohook": false, "markerPattern": "^(clos|fix|resolv)(e[sd]|ing)", "actionPattern": "^([Cc]los|[Ff]ix|[Rr]esolv)(e[sd]|ing)\\s+[^\\s\\d]+(\\s|$)", "ticketPattern": "^(Closes|Fixes) (.*#|gh-|[A-Z]{2,}-)[0-9]+", } } ``` * `limits.firstLine` and `limits.otherLine` are the hard limits for the number of symbols on the first line and on other lines of the commit message, respectively. * `"nohook": false` tells commitplease to install its `commit-msg` hook. Setting `"nohook": true` makes commitplease skip installing the hook or skip running the hook if it has already been installed. This can be used when wrapping the commitplease validation API into another module, like a [grunt plugin](https://github.com/rxaviers/grunt-commitplease/) or [husky](#husky). This setting does not affect the global commitplease executable, only repo-local. The following options are experimental and are subject to change: * `markerPattern`: A (intentionally loose) RegExp that indicates that the line might be a ticket reference. Case insensitive. * `actionPattern`: A RegExp that makes a line marked by `markerPattern` valid even if the line does not fit `ticketPattern` * `ticketPattern`: A RegExp that detects ticket references: `Closes gh-1`, `Fixes gh-42`, `WEB-451` and similar. The ticket reference match will fail only if `markerPattern` succeeds and __both__ `ticketPattern` and `actionPattern` fail. When overwriting these patterns in `package.json`, remember to escape special characters. ### jQuery Here is how to configure validation for [jQuery Commit Guidelines][1]: ```json { "commitplease": { "style": "jquery", "component": true, "components": [] } } ``` * `"style": "jquery"` selects [jQuery Commit Guidelines][1] * `"component": true` requires a component followed by a colon, like `Test:` or `Docs:` * `"components": []` is a list of valid components. Example: `"components": ["Test", "Docs"]`. Members of this list are surrounded by `^` and `$` and are treated as a regular expression. When this list is empty, anything followed by a colon is considered to be a valid component name. ### AngularJS Here is how to configure validation for [AngularJS Commit Guidelines][2] ```json { "commitplease": { "style": "angular", "types": [ "feat", "fix", "docs", "style", "refactor", "perf", "test", "chore" ], "scope": "\\S+.*" } } ``` * `"style": "angular"` selects [AngularJS Commit Guidelines][2] * `"types"` is an array of allowed types * `"scope": "\\S+.*"` is a string that is the regexp for scope. By default it means "at least one non-space character" ## Skip style check This paragraph assumes that you would like to skip the style check that happens during `git commit`. One way to do so is to type `git commit --no-verify` that will skip a few git hooks, including the one used by commitplease. If skipping many hooks is not what you want or you find yourself doing it too many times, just set the `nohook` option. You could set that inside `package.json` as described at the beginning of the [setup section](#setup). However, if modifying `package.json` is not possible, just set it in `.npmrc` (it will overwrite `package.json`) like so: ``` [commitplease] nohook = true ``` ## Husky When using commitplease together with [husky][3], the following will let husky manage all the hooks and trigger commitplease: ```json { "scripts": { "commitmsg": "commitplease .git/COMMIT_EDITMSG" }, "commitplease": { "nohook": true } } ``` However, since husky does not use npm in silent mode (and there is [no easy way](https://github.com/typicode/husky/pull/47) to make it [do so](https://github.com/npm/npm/issues/5452)), there will be a lot of additional output when a message fails validation. Moreover, husky will run your `scripts` entry and nothing more, so you have to [specify everything yourself](https://github.com/jzaefferer/commitplease/issues/100) (e.g. the path to the commit message file). Therefore, using commitplease alone is recommended. ## API ```js var validate = require('commitplease/lib/validate'); var errors = validate(commit.message); if (errors.length) { postComment('This commit has ' + errors.length + ' problems!'); } ``` `validate(message[, options])`, returns `Array` * `message` (`String`): the commit message to validate. Must use LF (`\n`) as line breaks. * `options` (`Object`, optional): use this to override the default settings * returns `Array`: empty for valid messages, one or more items as `String` for each problem found ## Examples ```json { "name": "awesomeproject", "description": "described", "devDependencies": { "commitplease": "latest", }, "commitplease": { "style": "jquery", "components": ["Docs", "Tests", "Build", "..."], "markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|(refs?)", "ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|(Refs? [^#])" } } ``` ```json { "name": "awesomeproject", "description": "described", "devDependencies": { "commitplease": "latest", }, "commitplease": { "style": "angular", "markerPattern": "^((clos|fix|resolv)(e[sd]|ing))|(refs?)", "ticketPattern": "^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|(Refs? [^#])" } } ``` ## Uninstall Remove your configurations of commitplease from your package.json, if any. If you are running `npm 2.x`, then: ``` npm uninstall commitplease --save-dev ``` If you are running `npm 3.x`, you will have to remove the hook manually: ``` rm .git/hooks/commit-msg npm uninstall commitplease --save-dev ``` There is [an open issue](https://github.com/npm/npm/issues/13381) to npm about this. ## License Copyright Jörn Zaefferer Released under the terms of the MIT license. --- Support this project by [donating on Gratipay](https://gratipay.com/jzaefferer/). [1]: http://contribute.jquery.org/commits-and-pull-requests/#commit-guidelines [2]: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit [3]: https://github.com/typicode/husky [4]: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges