commitplease
Advanced tools
Comparing version 2.6.1 to 2.7.0
#!/usr/bin/env node | ||
// commitplease-original | ||
require('commitplease') | ||
var commitplease = require('commitplease') | ||
var options = commitplease.getOptions() | ||
if (options && options.nohook === true) { | ||
console.log('commitplease: package.json or .npmrc set to skip check') | ||
process.exit(0) | ||
} | ||
commitplease() |
99
index.js
var fs = require('fs') | ||
var ini = require('ini') | ||
var path = require('path') | ||
var root = path.resolve(__dirname, '../..') | ||
var chalk = require('chalk') | ||
var Git = require('git-tools') | ||
var objectAssign = require('object-assign') | ||
var validate = require('./lib/validate') | ||
var sanitize = require('./lib/sanitize') | ||
var options = fs.existsSync(path.join(root, 'package.json')) && | ||
require(path.join(root, 'package.json')).commitplease || {} | ||
;(function () { | ||
var messageFile = path.resolve(process.cwd(), '.git/COMMIT_EDITMSG') | ||
var message = sanitize(fs.readFileSync(messageFile, 'utf8').toString()) | ||
var errors = validate(message, options) | ||
function getOptions () { | ||
var pkg = path.join(process.cwd(), 'package.json') | ||
var npm = path.join(process.cwd(), '.npmrc') | ||
pkg = fs.existsSync(pkg) && require(pkg) || {} | ||
npm = fs.existsSync(npm) && ini.parse(fs.readFileSync(npm, 'utf8')) || {} | ||
pkg = pkg.commitplease || {} | ||
npm = npm.commitplease || {} | ||
return objectAssign(pkg, npm) | ||
} | ||
function runValidate (message, options) { | ||
var errors = validate(sanitize(message), options) | ||
if (errors.length) { | ||
console.error('Invalid commit message, please fix the following issues:\n') | ||
console.error('Invalid commit message, please fix:\n') | ||
console.error(chalk.red('- ' + errors.join('\n- '))) | ||
@@ -20,3 +34,3 @@ console.error() | ||
console.error() | ||
console.error(chalk.green(message)) | ||
console.error(chalk.green(sanitize(message))) | ||
@@ -31,2 +45,67 @@ if (options.style === undefined || options.style === 'jquery') { | ||
} | ||
}()) | ||
} | ||
module.exports = function () { | ||
var argv = process.argv.slice(2) | ||
var help = argv.some(function (value) { | ||
if (value === '-h' || value === '--help') { | ||
return true | ||
} | ||
}) | ||
if (argv.length > 1 || help) { | ||
console.log( | ||
'Usage: commitplease [committish]\n\n' + | ||
'committish a commit range passed to git log\n\n' + | ||
'Examples:\n\n' + | ||
'1. Check all commits on branch master:\n' + | ||
'commitplease master\n\n' + | ||
'2. Check all commits on branch feature but not on master:\n' + | ||
'commitplease master..feature\n\n' + | ||
'3. Check the latest 1 commit (n works too):\n' + | ||
'commitplease -1\n\n' + | ||
'4. Check all commits between 84991d and 2021ce\n' + | ||
'commitplease 84991d..2021ce\n\n' + | ||
'5. Check all commits starting with 84991d\n' + | ||
'commitplease 84991d..\n\n' + | ||
'Docs on git commit ranges: https://bit.ly/commit-range' | ||
) | ||
process.exit(0) | ||
} | ||
var options = getOptions() | ||
var message = path.join('.git', 'COMMIT_EDITMSG') | ||
if (argv[0] === message) { | ||
runValidate(fs.readFileSync(message, 'utf8').toString(), options) | ||
process.exit(0) | ||
} | ||
var committish = 'HEAD' | ||
if (argv.length !== 0) { | ||
committish = argv[0] | ||
} | ||
var repo = new Git(process.cwd()) | ||
var secret = '--++== CoMMiTPLeaSe ==++--' | ||
var format = '--format=%B' + secret | ||
repo.exec('log', format, committish, function (error, messages) { | ||
if (error) { | ||
console.error(error) | ||
process.exit(1) | ||
} | ||
messages = messages.trim().split(secret) | ||
messages.pop() | ||
for (var i = 0; i < messages.length; ++i) { | ||
runValidate(messages[i], options) | ||
} | ||
}) | ||
} | ||
module.exports.getOptions = getOptions |
@@ -0,10 +1,25 @@ | ||
var fs = require('fs') | ||
var path = require('path') | ||
var chalk = require('chalk') | ||
var setup = require('./setup') | ||
if (setup.selfmadeHook) { | ||
console.log('Found an existing commitplease hook, removing to update it') | ||
setup.destroy() | ||
} else if (setup.hookExists) { | ||
console.log(chalk.red('Detected an existing git commit-msg hook')) | ||
console.log('') | ||
var options = require('./index.js').getOptions() | ||
if (options && options.nohook) { | ||
console.log('commitplease: package.json or .npmrc set to skip hook') | ||
process.exit(0) | ||
} | ||
var git = path.resolve(process.cwd(), '..', '..', '.git') | ||
var hooks = path.join(git, 'hooks') | ||
if (!fs.existsSync(git) || !fs.existsSync(hooks)) { | ||
fs.mkdirSync(git) | ||
fs.mkdirSync(hooks) | ||
} | ||
var dstHook = path.join(hooks, 'commit-msg') | ||
var srcHook = path.relative(hooks, 'commit-msg-hook.js') | ||
if (fs.existsSync(dstHook)) { | ||
console.log(chalk.red('A commit-msg hook already exists')) | ||
console.log(chalk.red('Remove it and install this package again to install commitplease properly')) | ||
@@ -14,3 +29,15 @@ process.exit(0) | ||
setup.create() | ||
console.log('Installed ' + setup.hook) | ||
try { | ||
fs.writeFileSync(dstHook, fs.readFileSync(srcHook)) | ||
fs.chmodSync(dstHook, '755') | ||
} catch (e) { | ||
if (/EPERM/.test(e.message)) { | ||
console.error( | ||
chalk.red( | ||
'Failed to write commit-msg hook. ' + | ||
'Make sure you have the necessary permissions.' | ||
) | ||
) | ||
} | ||
throw e | ||
} |
@@ -12,4 +12,5 @@ var defaults = require('./defaults.js') | ||
var semver = require('semver') | ||
var merge = require('mout/object/merge') | ||
var objectAssign = require('object-assign') | ||
module.exports = function (message, options) { | ||
@@ -29,5 +30,5 @@ if (message === undefined) { | ||
options.style === 'jquery') { | ||
options = merge(defaults.jquery, options) | ||
options = objectAssign({}, defaults.jquery, options) | ||
} else if (options.style === 'angular') { | ||
options = merge(defaults.angular, options) | ||
options = objectAssign({}, defaults.angular, options) | ||
} else { | ||
@@ -34,0 +35,0 @@ return [ |
{ | ||
"name": "commitplease", | ||
"version": "2.6.1", | ||
"version": "2.7.0", | ||
"description": "Validates strings as commit messages", | ||
"main": "index.js", | ||
"bin": { | ||
"commitplease": "./commit-msg-hook.js" | ||
"commitplease": "commitplease.js" | ||
}, | ||
@@ -33,3 +33,2 @@ "scripts": { | ||
"babel-register": "^6.9.0", | ||
"mout": "^0.12.0", | ||
"nodemon": "^1.9.1", | ||
@@ -41,5 +40,7 @@ "nodeunit": "^0.9.1", | ||
"chalk": "^1.1.1", | ||
"mout": "^0.12.0", | ||
"git-tools": "^0.2.1", | ||
"ini": "^1.3.4", | ||
"object-assign": "^4.1.0", | ||
"semver": "^5.1.0" | ||
} | ||
} |
@@ -12,10 +12,19 @@ # Commitplease | ||
You can also start with one of these and customize the validation rules. | ||
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. | ||
@@ -25,4 +34,2 @@ | ||
Commit as usual. This module is triggered by a git commit-msg hook and automatically validates your messages as you commit them. Invalid messages will be rejected, with details on what's wrong and a copy of the input. | ||
The following ways to begin a commit message are special and always valid: | ||
@@ -37,4 +44,22 @@ | ||
Common commit messages follow one of the style guides ([jQuery Commit Guidelines][1] by default) | ||
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 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 | ||
@@ -60,3 +85,3 @@ | ||
* `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 attempt to install its own `commit-msg` hook. Setting `"nohook": true` 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) | ||
* `"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. | ||
@@ -75,3 +100,3 @@ The following options are experimental and are subject to change: | ||
Here is how to use and configure validation for [jQuery Commit Guidelines][1]: | ||
Here is how to configure validation for [jQuery Commit Guidelines][1]: | ||
@@ -94,3 +119,3 @@ ```json | ||
Here is how to use and configure validation for [AngularJS Commit Guidelines][2] | ||
Here is how to configure validation for [AngularJS Commit Guidelines][2] | ||
@@ -209,2 +234,3 @@ ```json | ||
[2]: https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit | ||
[3]: https://github.com/typicode/husky | ||
[3]: https://github.com/typicode/husky | ||
[4]: https://git-scm.com/book/en/v2/Git-Tools-Revision-Selection#Commit-Ranges |
15
test.js
@@ -1,2 +0,1 @@ | ||
var merge = require('mout/object/merge') | ||
var validate = require('./lib/validate') | ||
@@ -6,2 +5,4 @@ var sanitize = require('./lib/sanitize') | ||
var objectAssign = require('object-assign') | ||
var jqueryColon = | ||
@@ -35,12 +36,12 @@ 'First line must be <Component>: <subject>\n' + | ||
var jquery1 = merge( | ||
defaults.jquery, {component: false} | ||
var jquery1 = objectAssign( | ||
{}, defaults.jquery, {component: false} | ||
) | ||
var jquery2 = merge( | ||
defaults.jquery, {components: ['Build', 'Legacy']} | ||
var jquery2 = objectAssign( | ||
{}, defaults.jquery, {components: ['Build', 'Legacy']} | ||
) | ||
var jquery3 = merge( | ||
defaults.jquery, { | ||
var jquery3 = objectAssign( | ||
{}, defaults.jquery, { | ||
markerPattern: '^((clos|fix|resolv)(e[sd]|ing))|(refs?)', | ||
@@ -47,0 +48,0 @@ ticketPattern: '^((Closes|Fixes) ([a-zA-Z]{2,}-)[0-9]+)|(Refs? [^#])' |
@@ -1,8 +0,16 @@ | ||
var setup = require('./setup') | ||
var fs = require('fs') | ||
var path = require('path') | ||
if (setup.selfmadeHook) { | ||
console.log('Found a hook installed by commitplease, removing') | ||
setup.destroy() | ||
} else { | ||
console.log("Didn't find a commit-msg hook installed by this module, doing nothing") | ||
var hooks = path.join(process.cwd(), '..', '..', '.git', 'hooks') | ||
var dstHook = path.join(hooks, 'commit-msg') | ||
var srcHook = path.relative(hooks, 'commit-msg-hook.js') | ||
if (fs.existsSync(dstHook) && fs.existsSync(srcHook)) { | ||
var githook = fs.readFileSync(dstHook, 'utf-8') | ||
var comhook = fs.readFileSync(srcHook, 'utf-8') | ||
if (githook.toString() === comhook.toString()) { | ||
console.log('Removing the hook installed by commitplease') | ||
fs.unlinkSync(dstHook) | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
43259
6
1162
229
5
+ Addedgit-tools@^0.2.1
+ Addedini@^1.3.4
+ Addedobject-assign@^4.1.0
+ Addedgit-tools@0.2.1(transitive)
+ Addedini@1.3.8(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedspawnback@1.0.1(transitive)
- Removedmout@^0.12.0
- Removedmout@0.12.0(transitive)