Skip to content

Commit 3ca438c

Browse files
authored
Feat: init commit (#28)
* Chore: add git-commit-count * Chore: add npm-debug.log * Feat: add support for initial commit * Test: update test for initial commit * Fix: update validation for first commit * Docs: update README.md for new feature * Docs: typo * Fix: add type check
1 parent 6cc8d7d commit 3ca438c

File tree

12 files changed

+154
-22
lines changed

12 files changed

+154
-22
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# modules
22
node_modules
3+
npm-debug.log
34

45
# generated
56
dest

.sgcrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"scope": false,
33
"body": true,
44
"emoji": false,
5+
"initial-commit": {
6+
"isEnabled": true,
7+
"emoji": ":tada:",
8+
"message": "Initial commit"
9+
},
510
"types": [
611
{
712
"emoji": ":wrench:",

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ You can even create a global config. Just go to your users home and create a `.s
4646
- [body](#body)
4747
- [scope](#scope)
4848
- [emoji](#emoji)
49+
- [initial-commit](#initial-commit)
4950
- [types](#types)
5051
- [rules](#rules)
5152

@@ -94,6 +95,28 @@ Example:
9495
}
9596
```
9697

98+
### initial-commit
99+
100+
**Type:** `object`
101+
102+
**Default:**
103+
104+
```json
105+
{
106+
"initial-commit": {
107+
"isEnabled": true,
108+
"emoji": ":tada:",
109+
"message": "Initial commit"
110+
}
111+
}
112+
```
113+
114+
**Keys:**
115+
116+
- `isEnabled` - Whether an explicit initial commit should be used for the very first commit
117+
- `emoji` - An emoji which will be appended at the beginning of the commit ([Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet/))
118+
- `message` - The commit message for the very first commit
119+
97120
### types
98121

99122
> Types will define your git commits. If `types` is not set in your own `.sgcrc`, the `types` of the global [.sgcrc](.sgcrc)

lib/cli.js

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
11
#!/usr/bin/env node
22

33
import chalk from 'chalk';
4+
import commitCount from 'git-commit-count';
45
import execa from 'execa';
5-
import yargs from 'yargs';
66
import inquirer from 'inquirer';
7-
import isGit from 'is-git-repository';
87
import isAdded from 'is-git-added';
8+
import isGit from 'is-git-repository';
99
import updateNotifier from 'update-notifier';
10+
import yargs from 'yargs';
1011

11-
import pkg from '../package.json';
1212
import getConfig from './getConfig';
13-
import questions from './questions';
1413
import combineTypeScope from './helpers/combineTypeScope';
14+
import pkg from '../package.json';
15+
import questions, {
16+
initMessage,
17+
initQuestion,
18+
} from './questions';
1519

1620
const config = getConfig();
1721
const questionsList = questions(config);
22+
const question = initQuestion(config);
23+
24+
const gitCommitExeca = message => (
25+
execa('git', ['commit', '-m', message], { stdio: 'inherit' })
26+
.catch(() => {
27+
console.error(chalk.red('\nAn error occured. Try to resolve the previous error and run following commit message again:'));
28+
console.error(chalk.green(`git commit -m "${message}"`));
29+
})
30+
);
31+
1832
const argv = yargs
1933
.usage('Usage: $0')
2034
.alias('v', 'version')
@@ -31,15 +45,19 @@ if (argv.v) {
3145
console.error('fatal: Not a git repository (or any of the parent directories): .git');
3246
} else if (!isAdded()) {
3347
console.error(chalk.red('Please', chalk.bold('git add'), 'some files first before you commit.'));
48+
} else if (commitCount() === 0 &&
49+
typeof config['initial-commit'] === 'object' &&
50+
config['initial-commit'].isEnabled) {
51+
const message = initMessage(config);
52+
53+
inquirer.prompt(question).then(answers => (
54+
answers.initCommit ? gitCommitExeca(message) : undefined
55+
));
3456
} else {
3557
inquirer.prompt(questionsList).then((answers) => {
3658
const typeScope = combineTypeScope(answers.type, answers.scope);
3759
const message = answers.body ? `${answers.editor}` : `${typeScope} ${answers.description}`;
3860

39-
return execa('git', ['commit', '-m', message], { stdio: 'inherit' })
40-
.catch(() => {
41-
console.error(chalk.red('\nAn error occured. Try to resolve the previous error and run following commit message again:'));
42-
console.error(chalk.green(`git commit -m "${message}"`));
43-
});
61+
return gitCommitExeca(message);
4462
});
4563
}

lib/getConfig.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import os from 'os';
2-
import path from 'path';
31
import json from 'json-extra';
42
import merge from 'lodash.merge';
3+
import os from 'os';
4+
import path from 'path';
55

66
const cwd = process.cwd();
77
const homedir = os.homedir();
@@ -35,6 +35,10 @@ const getConfig = (altPath) => {
3535
tempConfig.types = config.types;
3636
}
3737

38+
if (config['initial-commit']) {
39+
tempConfig['initial-commit'] = config['initial-commit'];
40+
}
41+
3842
// next will remove "inherit" from the config
3943
// eslint-disable-next-line
4044
const { inherit, ...copiedConfig } = tempConfig;

lib/questions.js

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import chalk from 'chalk';
2-
import ruleWarningMessages from './rules/ruleWarningMessages';
32
import combineTypeScope from './helpers/combineTypeScope';
3+
import ruleWarningMessages from './rules/ruleWarningMessages';
44

55
const choices = (config) => {
66
const choicesList = [];
@@ -19,6 +19,31 @@ const choices = (config) => {
1919
return choicesList;
2020
};
2121

22+
const initMessage = (config) => {
23+
let message = '';
24+
25+
if (config.emoji &&
26+
typeof config['initial-commit'] === 'object' &&
27+
config['initial-commit'].isEnabled) {
28+
message = `${config['initial-commit'].emoji} ${config['initial-commit'].message}`;
29+
} else {
30+
message = config['initial-commit'].message;
31+
}
32+
33+
return message;
34+
};
35+
36+
const initQuestion = (config) => {
37+
const message = initMessage(config);
38+
39+
return {
40+
type: 'confirm',
41+
name: 'initCommit',
42+
message: `Confirm as first commit message: "${message}"`,
43+
default: true,
44+
};
45+
};
46+
2247
const questions = (config) => {
2348
const choicesList = choices(config);
2449
const questionsList = [
@@ -70,4 +95,8 @@ const questions = (config) => {
7095
};
7196

7297
export default questions;
73-
export { choices };
98+
export {
99+
choices,
100+
initMessage,
101+
initQuestion,
102+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"dependencies": {
6666
"chalk": "^1.1.3",
6767
"execa": "^0.6.1",
68+
"git-commit-count": "^1.1.2",
6869
"inquirer": "^3.0.6",
6970
"is-git-added": "^1.0.1",
7071
"is-git-repository": "^1.0.1",

test/cli.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { homedir } from 'os';
21
import test from 'ava';
3-
import path from 'path';
42
import execa from 'execa';
3+
import { homedir } from 'os';
4+
import path from 'path';
55

66
import pkg from '../package.json';
77

test/fixtures/.sgcrc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"scope": false,
33
"body": true,
44
"emoji": false,
5+
"initial-commit": {
6+
"isEnabled": true,
7+
"emoji": ":tada:",
8+
"message": "Initial commit"
9+
},
510
"types": [
611
{
712
"emoji": ":emo:",

test/getConfig.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import os from 'os';
21
import test from 'ava';
3-
import path from 'path';
42
import fs from 'fs-extra';
53
import json from 'json-extra';
4+
import os from 'os';
5+
import path from 'path';
66

77
import getConfig from '../lib/getConfig';
88

test/questions.js

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import os from 'os';
21
import test from 'ava';
3-
import path from 'path';
42
import fs from 'fs-extra';
3+
import os from 'os';
4+
import path from 'path';
55

6-
import getConfig from '../lib/getConfig';
7-
import questions, { choices } from '../lib/questions';
86
import { withEmoji, withoutEmoji } from './fixtures/questions';
7+
import getConfig from '../lib/getConfig';
8+
import questions, {
9+
choices,
10+
initMessage,
11+
initQuestion,
12+
} from '../lib/questions';
913

1014
const cwd = process.cwd();
1115
const date = new Date();
@@ -108,3 +112,37 @@ test('CONFIRM EDITOR | check if it shows if it has to', (t) => {
108112

109113
t.is(questionsList[3].when(), config.body);
110114
});
115+
116+
test('INIT COMMIT | check message without emoji', (t) => {
117+
const config = getConfig();
118+
const message = initMessage(config);
119+
120+
t.is(message, config['initial-commit'].message);
121+
});
122+
123+
test('INIT COMMIT | check message with emoji', (t) => {
124+
const config = getConfig();
125+
126+
config.emoji = true;
127+
128+
const message = initMessage(config);
129+
130+
t.is(message, `${config['initial-commit'].emoji} ${config['initial-commit'].message}`);
131+
});
132+
133+
test('INIT QUESTION | check message without emoji', (t) => {
134+
const config = getConfig();
135+
const question = initQuestion(config);
136+
137+
t.is(question.message, `Confirm as first commit message: "${config['initial-commit'].message}"`);
138+
});
139+
140+
test('INIT QUESTION | check message with emoji', (t) => {
141+
const config = getConfig();
142+
143+
config.emoji = true;
144+
145+
const question = initQuestion(config);
146+
147+
t.is(question.message, `Confirm as first commit message: "${config['initial-commit'].emoji} ${config['initial-commit'].message}"`);
148+
});

yarn.lock

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,14 @@ getpass@^0.1.1:
18761876
dependencies:
18771877
assert-plus "^1.0.0"
18781878

1879+
git-commit-count@^1.1.2:
1880+
version "1.1.2"
1881+
resolved "https://registry.yarnpkg.com/git-commit-count/-/git-commit-count-1.1.2.tgz#6c1e4a8d7daf5444a9ea501da605d180ee995fb6"
1882+
dependencies:
1883+
execa "^0.6.1"
1884+
is-git-repository "^1.0.1"
1885+
path-is-absolute "^1.0.1"
1886+
18791887
glob-base@^0.3.0:
18801888
version "0.3.0"
18811889
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@@ -3104,7 +3112,7 @@ path-exists@^3.0.0:
31043112
version "3.0.0"
31053113
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
31063114

3107-
path-is-absolute@^1.0.0:
3115+
path-is-absolute@^1.0.0, path-is-absolute@^1.0.1:
31083116
version "1.0.1"
31093117
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
31103118

0 commit comments

Comments
 (0)