Skip to content

Instantly share code, notes, and snippets.

@realattila
Last active October 7, 2023 10:31
Show Gist options
  • Select an option

  • Save realattila/aa1c0608557ff71649dfc82866d29ed4 to your computer and use it in GitHub Desktop.

Select an option

Save realattila/aa1c0608557ff71649dfc82866d29ed4 to your computer and use it in GitHub Desktop.
Git Commit Message Validation Tool for Ensuring Template Adherence, Designed for Husky Git Hooks
/**
WARNING: AFTER READING THIS SECTION REMOVE THIS COMMENT SECTION FROM commit-template-checker.js file
after adding this script to your project, your commit message should contain on of this format, if not, you can not commit.
const correctCommitMsgFormat = [
"πŸ‘Œ IMPROVE: {Your message}",
"πŸš€ RELEASE: {Your message}",
"πŸ—‘ REMOVE: {Your message}",
"πŸ› FIX: {Your message}",
"πŸ”Ό UPGRADE: {Your message}",
"πŸ“¦ ADD: {Your message}",
];
Instructions
install nodejs -> https://nodejs.org/en
install husky -> https://typicode.github.io/husky/getting-started.html
create file call (commit-template-checker.js) in .husky folder (.husky/commit-template-checker.js) and copy all contents of this file inside commit-template-checker.js
run this command in root project
npx husky add .husky/commit-template-checker "cat .husky/commit-template-checker.js | node --input-type=commonjs"
for me .husky installed in my root folder project you can change instructions dou to the .husky folder location
If you find any problem, please contact me. my contact information exist in my github profile -> https://github.com/realattila
*/
/**
* This JavaScript function checks if a Git commit message follows a specific format and provides
* success or failure messages accordingly.
* @param buffer - The `buffer` parameter is a buffer object that contains the content of a file. In
* this code, it is used to read the content of the `.git/COMMIT_EDITMSG` file.
* @returns The code is returning the first line of the commit message from the `.git/COMMIT_EDITMSG`
* file.
*/
let supportsColor = { stdout: true };
const fs = require("fs");
try {
supportsColor = require("supports-color");
} catch (error) {
// DO NOTHING
// on MODULE_NOT_FOUND when installed by pnpm
}
const colorSupported = supportsColor.stdout;
const YELLOW = colorSupported ? "\x1b[1;33m" : "";
const GRAY = colorSupported ? "\x1b[0;37m" : "";
const RED = colorSupported ? "\x1b[0;31m" : "";
const GREEN = colorSupported ? "\x1b[0;32m" : "";
const BLUE = colorSupported ? "\x1b[1;34m" : "";
/** End Of Style, removes all attributes (formatting and colors) */
const EOS = colorSupported ? "\x1b[0m" : "";
const BOLD = colorSupported ? "\x1b[1m" : "";
// Read commit content (its multiple lines and first line include commit message)
const commitMsgContent = fs.readFileSync(".git/COMMIT_EDITMSG", "utf-8");
const msg = getFirstLine(commitMsgContent).replace(/\s{2,}/g, " ");
const branchName = require("child_process")
.execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" })
.split("\n")[0];
const correctCommitMsgFormat = [
"πŸ‘Œ IMPROVE: {Your message}",
"πŸš€ RELEASE: {Your message}",
"πŸ—‘ REMOVE: {Your message}",
"πŸ› FIX: {Your message}",
"πŸ”Ό UPGRADE: {Your message}",
"πŸ“¦ ADD: {Your message}",
];
const exampleMsg = ["πŸ“¦ ADD: Add husky to project", "πŸš€ RELEASE: Release 1.2", "πŸ› FIX: Fix reported bug in main page"];
const successMsgs = [
`${GREEN}*********** Congratulations! You've reached the next level of awesome! ***********${EOS}`,
`${GREEN}*********** Success is your superpower! Embrace it. ***********${EOS}`,
`${GREEN}*********** Your awesomeness knows no bounds! ***********${EOS}`,
`${GREEN}*********** You're so awesome that even unicorns are jealous! ***********${EOS}`,
`${GREEN}*********** You just leveled up in life! ***********${EOS}`,
`${GREEN}*********** High-fives to your amazing self! ***********${EOS}`,
`${GREEN}*********** Today's success is tomorrow's legend. ***********${EOS}`,
`${GREEN}*********** You've just unlocked the achievement of greatness! ***********${EOS}`,
`${GREEN}*********** Keep rocking the world, superstar! ***********${EOS}`,
`${GREEN}*********** Your success meter just went off the charts! ***********${EOS}`,
];
const failMsgs = [
`${RED}************* Oops! Something went haywire. *************${EOS}`,
`${RED}************* Epic fail! But don't lose hope. Retry! *************${EOS}`,
`${RED}************* Error 404: Success not found. Try again! *************${EOS}`,
`${RED}************* Failure is the path to success. Keep walking! *************${EOS}`,
`${RED}************* It's not a bug; it's a feature... of failure. *************${EOS}`,
`${RED}************* This is why we can't have nice commits. :( *************${EOS}`,
`${RED}************* The commit train derailed. Get back on track! *************${EOS}`,
`${RED}************* Git commit gone wrong. Consult the commit Jedi! *************${EOS}`,
`${RED}************* "I find your lack of proper commit disturbing." - Darth Vader *************${EOS}`,
`${RED}************* "A moment of failure can lead to a lifetime of wisdom." *************${EOS}`,
];
const commitTags = ["πŸ‘Œ IMPROVE:", "πŸš€ RELEASE:", "πŸ—‘ REMOVE:", "πŸ› FIX:", "πŸ”Ό UPGRADE:", "πŸ“¦ ADD:"];
const pattern = new RegExp(`^(${commitTags.join("|")})`);
const result = pattern.test(msg);
const commitResultMsg = result ? "SUCCESS" : "FAILED";
if (result) {
console.log(successMsgs[Math.floor(Math.random() * successMsgs.length)]);
console.log(`${BOLD}Commit result:${EOS} ${GREEN}${commitResultMsg}${EOS}`);
console.log(`${BOLD}Current branch:${EOS} ${branchName}`);
console.log(`${BOLD}Commit message:${EOS} ${BLUE}${msg}${EOS}\n`);
process.exit(0);
} else {
// choose on of random error message
console.log(failMsgs[Math.floor(Math.random() * failMsgs.length)]);
console.log(`${BOLD}Commit result:${EOS} ${RED}${commitResultMsg}${EOS}`);
console.log(`${BOLD}Current branch:${EOS} ${branchName}`);
console.log(`${BOLD}Commit message:${EOS} ${RED}${msg}${EOS}`);
console.log(`${BOLD}Correct format:${EOS}`);
correctCommitMsgFormat.forEach((format, i) => {
console.log(` ${i + 1}) ${GREEN}${format}${EOS}`);
});
console.log(`${BOLD}Example:${EOS}`);
exampleMsg.forEach((example, i) => {
console.log(` ${i + 1}) ${BLUE}${example}${EOS}`);
});
console.log();
process.exit(1);
}
/**
* It takes a buffer and returns the first line of the buffer as a string
* @param buffer - The buffer to read from.
* @returns The first line of the buffer.
*/
function getFirstLine(buffer) {
return buffer.toString().split("\n").shift();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment