Skip to content

Commit 282c774

Browse files
author
Oskar Karlsson
authored
Merge pull request #22 from tjoskar/feature/blacklist
Feature/blacklist
2 parents ba50634 + 740d5b0 commit 282c774

File tree

13 files changed

+5417
-1095
lines changed

13 files changed

+5417
-1095
lines changed

.eslintrc.js

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ module.exports = {
88
"parserOptions": {
99
"sourceType": "module"
1010
},
11+
"globals": {
12+
"test": true,
13+
"expect": true,
14+
"describe": true
15+
},
1116
"rules": {
1217
"node/no-unsupported-features": ["error"],
1318
"accessor-pairs": "error",
@@ -64,12 +69,9 @@ module.exports = {
6469
"func-call-spacing": "error",
6570
"func-name-matching": "error",
6671
"func-names": "error",
67-
"func-style": [
68-
"error",
69-
"expression"
70-
],
72+
"func-style": "off",
7173
"generator-star-spacing": "error",
72-
"global-require": "error",
74+
"global-require": "off",
7375
"guard-for-in": "error",
7476
"handle-callback-err": "error",
7577
"id-blacklist": "error",
@@ -94,18 +96,18 @@ module.exports = {
9496
"max-params": "error",
9597
"max-statements": "error",
9698
"max-statements-per-line": "error",
97-
"multiline-ternary": "error",
99+
"multiline-ternary": "off",
98100
"new-cap": "error",
99101
"new-parens": "error",
100102
"newline-after-var": "off",
101-
"newline-before-return": "error",
103+
"newline-before-return": "off",
102104
"newline-per-chained-call": "error",
103105
"no-alert": "error",
104106
"no-array-constructor": "error",
105107
"no-bitwise": "error",
106108
"no-caller": "error",
107109
"no-catch-shadow": "error",
108-
"no-confusing-arrow": "error",
110+
"no-confusing-arrow": "off",
109111
"no-console": "off",
110112
"no-continue": "error",
111113
"no-div-regex": "error",
@@ -169,11 +171,11 @@ module.exports = {
169171
"no-sync": "off",
170172
"no-tabs": "error",
171173
"no-template-curly-in-string": "error",
172-
"no-ternary": "error",
174+
"no-ternary": "off",
173175
"no-throw-literal": "error",
174176
"no-trailing-spaces": "error",
175177
"no-undef-init": "error",
176-
"no-undefined": "error",
178+
"no-undefined": "off",
177179
"no-underscore-dangle": "error",
178180
"no-unmodified-loop-condition": "error",
179181
"no-unneeded-ternary": "error",
@@ -191,8 +193,8 @@ module.exports = {
191193
"no-warning-comments": "error",
192194
"no-whitespace-before-property": "error",
193195
"no-with": "error",
194-
"object-curly-newline": "error",
195-
"object-curly-spacing": "error",
196+
"object-curly-newline": "off",
197+
"object-curly-spacing": ["error", "always"],
196198
"object-property-newline": "error",
197199
"object-shorthand": "error",
198200
"one-var": "off",
@@ -213,15 +215,15 @@ module.exports = {
213215
"single"
214216
],
215217
"radix": "error",
216-
"require-jsdoc": "error",
218+
"require-jsdoc": "off",
217219
"rest-spread-spacing": "error",
218-
"semi": "off",
220+
"semi": ["error", "always"],
219221
"semi-spacing": "error",
220222
"sort-imports": "error",
221223
"sort-keys": "off",
222224
"sort-vars": "error",
223225
"space-before-blocks": "error",
224-
"space-before-function-paren": "error",
226+
"space-before-function-paren": ["error", "never"],
225227
"space-in-parens": [
226228
"error",
227229
"never"

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
node_modules
2+
.vscode
3+
mock_hooks/prepare-commit-msg

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ language: node_js
22

33
node_js:
44
- 6
5-
6-
cache: yarn
5+
- node
76

87
notifications:
98
email: false

README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ $ gitmoji-commit-hook --init
2323

2424
![Demo](https://github.com/tjoskar/gitmoji-commit-hook/blob/master/demo.gif?raw=true)
2525

26+
## Config
27+
28+
You can put unwanted emojis in a blacklist section by adding the name in a blacklist array in your `package.json`:
29+
30+
```json
31+
{
32+
"gitmoji": {
33+
"blacklist": [
34+
"card-file-box",
35+
"beers"
36+
]
37+
}
38+
}
39+
```
40+
2641
## Emoji Meanings
2742

2843
A list of available emojis and their associated meanings can be found at [gitmoji.carloscuesta.me](https://gitmoji.carloscuesta.me/)
@@ -35,6 +50,19 @@ to add an emoji from gitmojis list to your commit.
3550
If you're looking for some other cool feature like search in gitmojis list,
3651
please consider [gitmoji-cli](https://github.com/carloscuesta/gitmoji-cli)
3752

53+
## Develop
54+
55+
To run the linter: `npm run lint`
56+
57+
To run the unit test: `npm test`
58+
59+
To dry run the script:
60+
```bash
61+
node invoke.js --init # run the init setup
62+
63+
node invoke.js mock_hooks/COMMIT_EDITMSG # simulate a git commit
64+
```
65+
3866
## License
3967

4068
The code is available under the [MIT](https://github.com/tjoskar/gitmoji-commit-hook/blob/master/LICENSE) license.

bin/index.js

Lines changed: 2 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,6 @@
11
#!/usr/bin/env node
22
'use strict';
33

4-
const fs = require('fs');
5-
const inquirer = require('inquirer');
6-
const axios = require('axios');
7-
const chalk = require('chalk');
8-
const pathExists = require('path-exists');
9-
const fileExists = require('file-exists');
4+
const { gitmojiCommitHook } = require('./lib');
105

11-
const gitmojiData = require('gitmoji-data/data/gitmojis.json');
12-
const GITMOJI_DATA_URL = 'https://raw.githubusercontent.com/gyran/gitmoji-data/master/data/gitmojis.json';
13-
14-
const errorHandler = error => {
15-
console.error(chalk.red(`🚨 ERROR: ${error}`));
16-
process.exit(1);
17-
};
18-
19-
let questions = []
20-
21-
const getGitmojiList = () => {
22-
return axios.get(GITMOJI_DATA_URL)
23-
.then((res) => {
24-
if (res && res.data && res.data.gitmojis) {
25-
return res.data.gitmojis;
26-
}
27-
28-
throw new Error('Could not find gitmojis at url');
29-
})
30-
.catch(() => {
31-
return gitmojiData.gitmojis;
32-
});
33-
};
34-
35-
if (process.argv[2] === '--init') {
36-
const path = `${process.env.PWD}/.git/hooks`;
37-
38-
if (!pathExists.sync('.git')) {
39-
errorHandler('The directory is not a git repository.')
40-
}
41-
42-
if (fileExists.sync(`${path}/prepare-commit-msg`)) {
43-
errorHandler(`A prepare-commit hook already exists, please remove the hook (rm ${path}/prepare-commit-msg)
44-
or install gitmoji-commit-hook manually by adding the following content info ${path}/prepare-commit-msg: \nexec < /dev/tty\ngitmoji-commit-hook $1`);
45-
}
46-
47-
fs.writeFile(`${path}/prepare-commit-msg`, '#!/bin/sh\nexec < /dev/tty\ngitmoji-commit-hook $1', writeError => {
48-
if (writeError) {
49-
errorHandler(writeError);
50-
} else {
51-
fs.chmod(`${path}/prepare-commit-msg`, '755', chmodError => {
52-
if (chmodError) {
53-
errorHandler(chmodError);
54-
} else {
55-
console.log(`${chalk.green('🎉 SUCCESS 🎉')} gitmoji-commit-hook initialized with success.`);
56-
}
57-
});
58-
}
59-
});
60-
} else {
61-
getGitmojiList()
62-
.then((gitmojis) => {
63-
questions.push({
64-
type: 'checkbox',
65-
name: 'emoji',
66-
message: 'Select emoji(s) for your commit',
67-
choices: gitmojis.map(gitmoji => {
68-
return {
69-
name: gitmoji.emoji + ' ' + gitmoji.description,
70-
value: gitmoji.emoji
71-
};
72-
})
73-
});
74-
75-
if(/COMMIT_EDITMSG/g.test(process.argv[2])) {
76-
return inquirer.prompt(questions).then((answers) => {
77-
let commitMsg = fs.readFileSync(process.argv[2]);
78-
commitMsg = `${answers.emoji.join(' ')} ${commitMsg}`;
79-
fs.writeFileSync(process.argv[2], commitMsg);
80-
81-
process.exit(0);
82-
});
83-
}
84-
})
85-
.catch(err => {
86-
errorHandler(err);
87-
});
88-
}
6+
gitmojiCommitHook(`${process.env.PWD}/.git/hooks`, process.argv[2]);

bin/lib.js

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
'use strict';
2+
3+
const fs = require('fs');
4+
const promisify = require('es6-promisify');
5+
const inquirer = require('inquirer');
6+
const axios = require('axios');
7+
const chalk = require('chalk');
8+
const pathExists = require('path-exists');
9+
const fileExists = require('file-exists');
10+
const { map, path, test, join } = require('ramda');
11+
12+
const writeFile = promisify(fs.writeFile);
13+
const readFile = promisify(fs.readFile);
14+
const chmod = promisify(fs.chmod);
15+
16+
const gitmojiUrl = 'https://raw.githubusercontent.com/carloscuesta/gitmoji/master/src/data/gitmojis.json';
17+
const prepareCommitMsgFileName = 'prepare-commit-msg';
18+
19+
const gitmojiCommitHookComand = `#!/bin/sh
20+
exec < /dev/tty
21+
gitmoji-commit-hook $1
22+
`;
23+
24+
const errorMessage = {
25+
notGit: 'The directory is not a git repository.',
26+
commitHookExist: `A prepare-commit hook already exists, please remove the hook (rm .git/hooks/${prepareCommitMsgFileName}) or install gitmoji-commit-hook manually by adding the following content info .git/hooks/\n\n${prepareCommitMsgFileName}:${gitmojiCommitHookComand}`,
27+
gitmojiParse: 'Could not find gitmojis at url'
28+
};
29+
30+
function errorHandler(error) {
31+
console.error(chalk.red(`🚨 ERROR: ${error}`));
32+
process.exit(1);
33+
}
34+
35+
function rejectIf(errorMsg) {
36+
return val => val ? Promise.reject(new Error(errorMsg)) : val;
37+
}
38+
39+
function rejectIfNot(errorMsg) {
40+
return val => val ? val : Promise.reject(new Error(errorMsg));
41+
}
42+
43+
function getGitmojiList() {
44+
return axios.get(gitmojiUrl)
45+
.then(path(['data', 'gitmojis']))
46+
.then(rejectIfNot(errorMessage.gitmojiParse));
47+
}
48+
49+
function assertGitRepository() {
50+
return pathExists('.git')
51+
.then(rejectIfNot(errorMessage.notGit));
52+
}
53+
54+
function assertNoPrepareCommitHook(gitHookPath) {
55+
return () => fileExists(`${gitHookPath}/${prepareCommitMsgFileName}`)
56+
.then(rejectIf(errorMessage.commitHookExist));
57+
}
58+
59+
function initProject(gitHookPath) {
60+
return assertGitRepository()
61+
.then(assertNoPrepareCommitHook(gitHookPath))
62+
.then(() => writeFile(`${gitHookPath}/${prepareCommitMsgFileName}`, gitmojiCommitHookComand))
63+
.then(() => chmod(`${gitHookPath}/${prepareCommitMsgFileName}`, '755'));
64+
}
65+
66+
function prependMessage(getMessage, putMessage) {
67+
return filepath => message => getMessage(filepath)
68+
.then(fileContent => `${message} ${fileContent}`)
69+
.then(fileContent => putMessage(filepath, fileContent));
70+
}
71+
72+
const prependMessageToFile = prependMessage(readFile, writeFile);
73+
74+
function getGitmojiBlacklist() {
75+
return fileExists(`${process.env.PWD}/package.json`)
76+
.then(exist => exist ? require(`${process.env.PWD}/package.json`) : {})
77+
.then(packageJson => packageJson.gitmoji || {})
78+
.then(gitmoji => gitmoji.blacklist || []);
79+
}
80+
81+
function seperateChoices(choices) {
82+
return blacklist => {
83+
if (blacklist.length === 0) {
84+
return choices;
85+
}
86+
return [
87+
...choices.filter(choice => !blacklist.includes(choice.type)),
88+
new inquirer.Separator(),
89+
...choices.filter(choice => blacklist.includes(choice.type)),
90+
new inquirer.Separator()
91+
];
92+
};
93+
}
94+
95+
function seperateBlacklistEmojis(choices) {
96+
return getGitmojiBlacklist()
97+
.then(seperateChoices(choices));
98+
}
99+
100+
function printInitSuccess() {
101+
console.log(`${chalk.green('🎉 SUCCESS 🎉')} gitmoji-commit-hook initialized with success.`);
102+
}
103+
104+
function mapGitmojiItemToOption(gitmoji) {
105+
return {
106+
name: gitmoji.emoji + ' ' + gitmoji.description,
107+
value: gitmoji.emoji,
108+
type: gitmoji.name
109+
};
110+
}
111+
112+
function createInquirerQuestion(emojis) {
113+
return [{
114+
type: 'checkbox',
115+
name: 'emoji',
116+
message: 'Select emoji(s) for your commit',
117+
choices: emojis
118+
}];
119+
}
120+
121+
const isCommitEditMsgFile = test(/COMMIT_EDITMSG/g);
122+
123+
function gitmojiCommitHook(gitHookPath, commitFile) {
124+
if (commitFile === '--init') {
125+
initProject(gitHookPath)
126+
.then(printInitSuccess)
127+
.catch(errorHandler);
128+
} else if (isCommitEditMsgFile(commitFile)) {
129+
getGitmojiList()
130+
.then(map(mapGitmojiItemToOption))
131+
.then(seperateBlacklistEmojis)
132+
.then(createInquirerQuestion)
133+
.then(inquirer.prompt)
134+
.then(answers => answers.emoji)
135+
.then(join(' '))
136+
.then(prependMessageToFile(commitFile))
137+
.catch(errorHandler);
138+
}
139+
}
140+
141+
module.exports = {
142+
rejectIf,
143+
rejectIfNot,
144+
gitmojiCommitHook,
145+
prependMessage,
146+
mapGitmojiItemToOption,
147+
createInquirerQuestion,
148+
seperateChoices
149+
};

invoke.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
const { gitmojiCommitHook } = require('./bin/lib')
3+
4+
gitmojiCommitHook(`${process.env.PWD}/mock_hooks`, process.argv[2])

mock_hooks/COMMIT_EDITMSG

Whitespace-only changes.

0 commit comments

Comments
 (0)