Skip to content

Instantly share code, notes, and snippets.

@sixertoy
Last active April 12, 2016 15:01
Show Gist options
  • Save sixertoy/feeacbb6cfe8b7a9344d526cabd970b1 to your computer and use it in GitHub Desktop.
Save sixertoy/feeacbb6cfe8b7a9344d526cabd970b1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
/**
*
* Git COMMIT-MSG hook for validating commit message
*
* To be validated commit's message requires:
* - A '#' at message begining
* - Uppercase chars afer '#'
* - Digit chars afer uppercase chars
* EX: #TASK-456: is a valid test message
*
* Regex Online Tester Link
* @see https://regex101.com/r/gH8aW8/1
*
* Installation:
* copy this file under '<project_name>/.git/hooks/'
* renamed it 'commit-msg'
*
*/
(function () {
'use strict';
var fs = require('fs'),
util = require('util'),
// constants
END_LINE = '\n',
MAX_LENGTH = 100,
JIRA_PATTERN = /#(\[A-Z]+-[0-9]+)\s(.*)/g,
// messages
INVALID_HEAD = 'INVALID COMMIT MSG: ',
COMMIT_MESSAGE_FILE = 'COMMIT_EDITMSG',
TOO_LONG = 'is longer than %d characters !',
GIT_LOG_FILE = 'logs/incorrect-commit-msgs',
NOT_MATCH = 'does not match pattern "#<ticket> <message>"!',
// variables
commitMsg, commitMsgFile,
// https://github.com/chalk/ansi-styles/blob/master/index.js
// https://gist.github.com/sixertoy/f26c7177e84bbef9308c96da54325f66
__getColor = function (msg, code) {
return '\u001b[' + code + 'm' + msg + '\u001b[39m';
},
_red = function (msg) {
return __getColor(msg, 31);
},
_white = function (msg) {
return __getColor(msg, 37);
},
_yellow = function (msg) {
return __getColor(msg, 33);
},
/**
*
* Log error in console
*
*/
error = function () {
var msg = _red(INVALID_HEAD);
msg += util.format.apply(null, arguments);
console.error(msg);
return -1;
},
/**
*
* Message Validation Function
* Return -1 if message is not valid
* - will log error in console
* Return 0 if message is valid but has error like
* - wrong ticket # for this git branch
* Return 1 if message is valid
*
*/
_validateMessage = function (message) {
var match, msg,
indexof = message.indexOf('#');
if (indexof !== -1 && indexof !== 0) {
message = ('#' + message);
}
// check message length
if (message.length > MAX_LENGTH) {
msg = _yellow(TOO_LONG);
msg += END_LINE;
msg += _white('> ' + MAX_LENGTH);
return error(msg);
}
// check message pattern
match = JIRA_PATTERN.exec(message);
if (!match) {
msg = _yellow(NOT_MATCH);
msg += END_LINE;
msg += _white('> ' + message);
return error(msg);
}
return 1;
},
/**
*
* Return first line of commit message
*
*/
_getfirstLineFromBuffer = function (buffer) {
var firstLine = buffer.toString()
.split(END_LINE)
.shift();
return firstLine;
},
/**
*
* Write error message in log file
*
*/
_writeLogFileError = function (commitMsgFile, commitMsg, cb) {
try {
// GIT file where to write error
var incorrectLogFile = commitMsgFile.replace(COMMIT_MESSAGE_FILE, GIT_LOG_FILE);
// write file
fs.appendFile(incorrectLogFile, commitMsg + '\n', cb);
} catch (e) {
throw new Error(e.message);
}
};
// GIT file containing current commit message
commitMsgFile = process.argv[2];
// read commit file to validate message
fs.readFile(commitMsgFile, function (err, buffer) {
// -1 is not valid
// 0 contains errors
// 1 is valid
var isMessageValid = -1;
// get file content
commitMsg = _getfirstLineFromBuffer(buffer);
isMessageValid = _validateMessage(commitMsg);
// if message is valid
// exit process without errors
if (isMessageValid > 0) {
process.exit(0);
}
// if message is not valid
// will write error message in GIT log file
// exit process with errors
if (isMessageValid < 0) {
_writeLogFileError(commitMsgFile, commitMsg, function () {
process.exit(1);
});
}
});
// publish for testing
// exports.validateMessage = _validateMessage;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment