format-commit 0.1.8 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/lib/commit.js +48 -15
- package/lib/default-config.json +10 -4
- package/lib/index.js +5 -4
- package/lib/options.json +6 -2
- package/lib/setup.js +25 -10
- package/lib/utils.js +31 -24
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -22,10 +22,12 @@ If you want to change format-commit configuration without manually editing the j
|
|
|
22
22
|
|
|
23
23
|
| Property | Description |
|
|
24
24
|
| :------- | :---------- |
|
|
25
|
-
| **format** |
|
|
26
|
-
| **types** | The different types of commit allowed. Not defined during assisted configuration, default values used:
|
|
25
|
+
| **format** | Format option for your commit titles. <br> 1 - (type) Name / 2 - (type) name <br> 3 - type: Name / 4 - type: name <br> 5 - type(scope) Name / 6 - type(scope) name <br> 7 - type(scope): Name / 8 - type(scope): name |
|
|
26
|
+
| **types** | The different types of commit allowed. Not defined during assisted configuration, default values used: feat / fix / core / test / config / doc |
|
|
27
|
+
| **scopes** | Your application's scopes to categorize your commits (only for related formats 5 to 8). Not defined during assisted configuration |
|
|
27
28
|
| **minLength** | Minimum size allowed for your commit titles |
|
|
28
29
|
| **maxLength** | Maximum size allowed for your commit titles |
|
|
29
30
|
| **changeVersion** | "always": All commits must obligatorily involve a change of version (no preliminary request). <br> "only on release branch": All commits on your release/main branch must obligatorily involve a change of version (no preliminary request). <br> "never": Commits do not necessarily lead to a version change whatever the branch, the wizard will always ask. |
|
|
30
31
|
| **releaseBranch** | Release/main Git branch of your project. Use if changeVersion is defined on "only on release branch". |
|
|
31
32
|
| **showAllVersionTypes** | Show all possible types of version changes in the wizard, or show only the main ones (major / minor / patch / \<custom\>) |
|
|
33
|
+
| **stageAllChanges** | Auto-stage all changes before each commit |
|
package/lib/commit.js
CHANGED
|
@@ -2,31 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
const prompts = require('prompts');
|
|
4
4
|
const utils = require('./utils');
|
|
5
|
+
const options = require('./options.json');
|
|
5
6
|
|
|
6
7
|
|
|
7
|
-
module.exports = async (
|
|
8
|
-
if (!
|
|
8
|
+
module.exports = async (config, testMode) => {
|
|
9
|
+
if (!config) {
|
|
9
10
|
return;
|
|
10
11
|
}
|
|
11
12
|
utils.log('new commit');
|
|
12
13
|
|
|
14
|
+
if (testMode) {
|
|
15
|
+
utils.log('test mode enabled - commit will not be performed', 'warning');
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Get current git branch for version change option "only on release branch"
|
|
15
20
|
*/
|
|
16
|
-
const currentBranch =
|
|
21
|
+
const currentBranch = utils.getCurrentBranch();
|
|
17
22
|
const askForVersion = utils.askForVersion(config, currentBranch);
|
|
18
23
|
|
|
24
|
+
const noType = !config.types || (config.types && config.types.length === 0);
|
|
25
|
+
if (noType) {
|
|
26
|
+
utils.log('no types defined - please update config', 'error');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const noScope = !config.scopes || (config.scopes && config.scopes.length === 0);
|
|
31
|
+
if (config.format >= 5 && noScope) {
|
|
32
|
+
utils.log('no scopes defined - update config or format option', 'error');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
let cancelled = false;
|
|
20
37
|
const commit = await prompts([
|
|
21
38
|
{
|
|
22
39
|
type: 'select',
|
|
23
40
|
name: 'type',
|
|
24
41
|
message: 'Type of changes',
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
42
|
+
choices: config.types,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: config.format >= 5 ? 'select' : null,
|
|
46
|
+
name: 'scope',
|
|
47
|
+
message: 'Scope',
|
|
48
|
+
choices: config.scopes,
|
|
30
49
|
},
|
|
31
50
|
{
|
|
32
51
|
type: 'text',
|
|
@@ -81,7 +100,7 @@ module.exports = async (options, config) => {
|
|
|
81
100
|
* Handle prompt cancellation and stop commit execution
|
|
82
101
|
*/
|
|
83
102
|
if (cancelled) {
|
|
84
|
-
utils.log('commit cancelled');
|
|
103
|
+
utils.log('commit cancelled', 'error');
|
|
85
104
|
return;
|
|
86
105
|
}
|
|
87
106
|
|
|
@@ -89,8 +108,22 @@ module.exports = async (options, config) => {
|
|
|
89
108
|
* Format changes message and commit it
|
|
90
109
|
*/
|
|
91
110
|
utils.log('commit changes...');
|
|
92
|
-
|
|
93
|
-
|
|
111
|
+
if (config.stageAllChanges) {
|
|
112
|
+
utils.handleCmdExec('git add -A');
|
|
113
|
+
}
|
|
114
|
+
const commitTitle = utils.formatCommitTitle(
|
|
115
|
+
commit.type,
|
|
116
|
+
commit.title,
|
|
117
|
+
config.format,
|
|
118
|
+
commit.scope
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
if (testMode) {
|
|
122
|
+
utils.log(commitTitle, 'warning');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const commitRes = utils.handleCmdExec(`git commit -m "${commitTitle}" -m "${commit.description}"`);
|
|
94
127
|
if (!commitRes) {
|
|
95
128
|
return;
|
|
96
129
|
}
|
|
@@ -110,7 +143,7 @@ module.exports = async (options, config) => {
|
|
|
110
143
|
},
|
|
111
144
|
]);
|
|
112
145
|
utils.log('update version...');
|
|
113
|
-
newVersion =
|
|
146
|
+
newVersion = utils.handleCmdExec(`npm version ${commit.version} --preid=${preRelease.tag}`);
|
|
114
147
|
|
|
115
148
|
} else if (commit.version) {
|
|
116
149
|
/**
|
|
@@ -118,7 +151,7 @@ module.exports = async (options, config) => {
|
|
|
118
151
|
*/
|
|
119
152
|
utils.log('update version...');
|
|
120
153
|
const version = commit.customVersion ? commit.customVersion : commit.version;
|
|
121
|
-
newVersion =
|
|
154
|
+
newVersion = utils.handleCmdExec(`npm version ${version} --allow-same-version`);
|
|
122
155
|
}
|
|
123
156
|
|
|
124
157
|
if (newVersion) {
|
|
@@ -130,9 +163,9 @@ module.exports = async (options, config) => {
|
|
|
130
163
|
*/
|
|
131
164
|
if (commit.pushAfterCommit) {
|
|
132
165
|
utils.log('push changes...');
|
|
133
|
-
const gitPush =
|
|
166
|
+
const gitPush = utils.handleCmdExec(`git push -u origin ${currentBranch}`);
|
|
134
167
|
console.log(gitPush);
|
|
135
168
|
}
|
|
136
|
-
const gitStatus =
|
|
169
|
+
const gitStatus = utils.handleCmdExec('git status');
|
|
137
170
|
console.log(gitStatus);
|
|
138
171
|
};
|
package/lib/default-config.json
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 1,
|
|
3
3
|
"minLength": 8,
|
|
4
|
-
"maxLength":
|
|
4
|
+
"maxLength": 80,
|
|
5
5
|
"changeVersion": "never",
|
|
6
6
|
"releaseBranch": "master",
|
|
7
7
|
"showAllVersionTypes": false,
|
|
8
|
+
"stageAllChanges": false,
|
|
8
9
|
"types": [
|
|
9
|
-
{ "value": "fix", "description": "
|
|
10
|
-
{ "value": "feat", "description": "New feature(s)"},
|
|
10
|
+
{ "value": "fix", "description": "Issue(s) fixing" },
|
|
11
|
+
{ "value": "feat", "description": "New feature(s)" },
|
|
11
12
|
{ "value": "core", "description": "Change(s) on the application core" },
|
|
12
|
-
{ "value": "test" , "description": "Change(s) related to tests"}
|
|
13
|
+
{ "value": "test" , "description": "Change(s) related to tests" },
|
|
14
|
+
{ "value": "config" , "description": "Project configuration" },
|
|
15
|
+
{ "value": "doc" , "description": "Documentation / comment(s)" }
|
|
16
|
+
],
|
|
17
|
+
"scopes": [
|
|
18
|
+
{ "value": "example", "description": "Your scope's description" }
|
|
13
19
|
]
|
|
14
20
|
}
|
package/lib/index.js
CHANGED
|
@@ -9,11 +9,12 @@ const commit = require('./commit');
|
|
|
9
9
|
const options = require('./options.json');
|
|
10
10
|
|
|
11
11
|
program.option('-c, --config', 'generate a configuration file on your project for format-commit');
|
|
12
|
+
program.option('-t, --test', 'start script without finalize commit (for tests)');
|
|
12
13
|
program.parse(process.argv);
|
|
13
14
|
|
|
14
15
|
(async () => {
|
|
15
16
|
if (program.config) {
|
|
16
|
-
await setup();
|
|
17
|
+
await setup(false);
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
@@ -23,12 +24,12 @@ program.parse(process.argv);
|
|
|
23
24
|
fs.readFile(`./${options.configFile}.json`, async (err, data) => {
|
|
24
25
|
if (err) {
|
|
25
26
|
utils.log('no configuration found', 'warning');
|
|
26
|
-
const setupResult = await setup(
|
|
27
|
+
const setupResult = await setup(true);
|
|
27
28
|
if (setupResult && setupResult.commitAfter) {
|
|
28
|
-
commit(
|
|
29
|
+
commit(setupResult.config, program.test);
|
|
29
30
|
}
|
|
30
31
|
} else {
|
|
31
|
-
commit(
|
|
32
|
+
commit(JSON.parse(data), program.test);
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
35
|
})();
|
package/lib/options.json
CHANGED
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
{ "value": 1, "title": "(type) Name" },
|
|
5
5
|
{ "value": 2, "title": "(type) name" },
|
|
6
6
|
{ "value": 3, "title": "type: Name" },
|
|
7
|
-
{ "value": 4, "title": "type: name" }
|
|
7
|
+
{ "value": 4, "title": "type: name" },
|
|
8
|
+
{ "value": 5, "title": "type(scope) Name" },
|
|
9
|
+
{ "value": 6, "title": "type(scope) name" },
|
|
10
|
+
{ "value": 7, "title": "type(scope): Name" },
|
|
11
|
+
{ "value": 8, "title": "type(scope): name" }
|
|
8
12
|
],
|
|
9
13
|
"versionChangeMode": [
|
|
10
14
|
{ "value": "always" },
|
|
11
15
|
{ "value": "releaseBranch", "title": "only on release branch" },
|
|
12
|
-
{ "value": "never" }
|
|
16
|
+
{ "value": "never", "title": "never (always ask)" }
|
|
13
17
|
],
|
|
14
18
|
"versionTypes": [
|
|
15
19
|
{ "value": "major" },
|
package/lib/setup.js
CHANGED
|
@@ -4,18 +4,16 @@ const prompts = require('prompts');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const utils = require('./utils');
|
|
6
6
|
const defaultConfig = require('./default-config.json');
|
|
7
|
+
const options = require('./options.json');
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
module.exports = async (
|
|
10
|
-
if (!options) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
10
|
+
module.exports = async (askForCommitAfter) => {
|
|
13
11
|
utils.log('create config file');
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* Get current git branch to pre-fill release branch option
|
|
17
15
|
*/
|
|
18
|
-
const currentBranch =
|
|
16
|
+
const currentBranch = utils.getCurrentBranch();
|
|
19
17
|
|
|
20
18
|
let cancelled = false;
|
|
21
19
|
const configChoices = await prompts([
|
|
@@ -39,6 +37,12 @@ module.exports = async (options) => {
|
|
|
39
37
|
validate: val => utils.validCommitTitleSetupLength(val),
|
|
40
38
|
initial: defaultConfig.maxLength,
|
|
41
39
|
},
|
|
40
|
+
{
|
|
41
|
+
type: 'confirm',
|
|
42
|
+
name: 'stageAllChanges',
|
|
43
|
+
message: 'Stage all changes before each commit?',
|
|
44
|
+
initial: defaultConfig.stageAllChanges,
|
|
45
|
+
},
|
|
42
46
|
{
|
|
43
47
|
type: 'select',
|
|
44
48
|
name: 'changeVersion',
|
|
@@ -58,7 +62,7 @@ module.exports = async (options) => {
|
|
|
58
62
|
initial: defaultConfig.showAllVersionTypes,
|
|
59
63
|
},
|
|
60
64
|
{
|
|
61
|
-
type: 'confirm',
|
|
65
|
+
type: askForCommitAfter ? 'confirm' : null,
|
|
62
66
|
name: 'commitAfter',
|
|
63
67
|
message: 'Commit your changes now? (or exit the configuration without committing)',
|
|
64
68
|
initial: false,
|
|
@@ -74,7 +78,7 @@ module.exports = async (options) => {
|
|
|
74
78
|
* Handle prompt cancellation and stop setup execution
|
|
75
79
|
*/
|
|
76
80
|
if (cancelled) {
|
|
77
|
-
utils.log('setup cancelled');
|
|
81
|
+
utils.log('setup cancelled', 'error');
|
|
78
82
|
return;
|
|
79
83
|
}
|
|
80
84
|
|
|
@@ -84,16 +88,27 @@ module.exports = async (options) => {
|
|
|
84
88
|
const config = {
|
|
85
89
|
format: configChoices.format,
|
|
86
90
|
types: defaultConfig.types,
|
|
91
|
+
scopes: configChoices.format >= 5
|
|
92
|
+
? defaultConfig.scopes
|
|
93
|
+
: undefined,
|
|
87
94
|
minLength: configChoices.minLength,
|
|
88
|
-
|
|
95
|
+
maxLength: configChoices.maxLength,
|
|
89
96
|
changeVersion: configChoices.changeVersion,
|
|
90
97
|
releaseBranch: configChoices.releaseBranch,
|
|
91
98
|
showAllVersionTypes: configChoices.showAllVersionTypes,
|
|
99
|
+
stageAllChanges: configChoices.stageAllChanges,
|
|
92
100
|
};
|
|
93
101
|
const parsedConfig = JSON.stringify(config, null, 2);
|
|
94
102
|
|
|
95
|
-
utils.log(`
|
|
96
|
-
|
|
103
|
+
utils.log(`save ${options.configFile}.json file...`);
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
fs.writeFileSync(`./${options.configFile}.json`, parsedConfig);
|
|
107
|
+
utils.log('config file successfully created', 'success');
|
|
108
|
+
} catch (err) {
|
|
109
|
+
utils.log(`unable to save config file: ${err}`, 'error');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
97
112
|
|
|
98
113
|
return {
|
|
99
114
|
config,
|
package/lib/utils.js
CHANGED
|
@@ -38,33 +38,40 @@ const validCommitTitleSetupLength = (len) => {
|
|
|
38
38
|
|
|
39
39
|
const validVersion = (version) => {
|
|
40
40
|
const regex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
41
|
-
if(!regex.test(version)) {
|
|
41
|
+
if (!regex.test(version)) {
|
|
42
42
|
return 'Version does not respect semantic versioning';
|
|
43
43
|
}
|
|
44
44
|
return true;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
const formatCommitTitle = (type, title, format) => {
|
|
47
|
+
const formatCommitTitle = (type, title, format, scope = '*') => {
|
|
48
48
|
switch (format) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
49
|
+
case 1:
|
|
50
|
+
default:
|
|
51
|
+
return `(${type}) ${title[0].toUpperCase()}${title.substr(1).toLowerCase()}`;
|
|
52
|
+
case 2:
|
|
53
|
+
return `(${type}) ${title.toLowerCase()}`;
|
|
54
|
+
case 3:
|
|
55
|
+
return `${type}: ${title[0].toUpperCase()}${title.substr(1).toLowerCase()}`;
|
|
56
|
+
case 4:
|
|
57
|
+
return `${type}: ${title.toLowerCase()}`;
|
|
58
|
+
case 5:
|
|
59
|
+
return `${type}(${scope}) ${title[0].toUpperCase()}${title.substr(1).toLowerCase()}`;
|
|
60
|
+
case 6:
|
|
61
|
+
return `${type}(${scope}) ${title.toLowerCase()}`;
|
|
62
|
+
case 7:
|
|
63
|
+
return `${type}(${scope}): ${title[0].toUpperCase()}${title.substr(1).toLowerCase()}`;
|
|
64
|
+
case 8:
|
|
65
|
+
return `${type}(${scope}): ${title.toLowerCase()}`;
|
|
58
66
|
}
|
|
59
67
|
};
|
|
60
68
|
|
|
61
|
-
const handleCmdExec =
|
|
69
|
+
const handleCmdExec = (command) => {
|
|
62
70
|
try {
|
|
63
|
-
const output =
|
|
71
|
+
const output = execSync(command);
|
|
64
72
|
return output.toString();
|
|
65
|
-
} catch(err) {
|
|
73
|
+
} catch (err) {
|
|
66
74
|
log(`Error\n${err.message ? err.message : err}`, 'error');
|
|
67
|
-
return;
|
|
68
75
|
}
|
|
69
76
|
};
|
|
70
77
|
|
|
@@ -72,15 +79,15 @@ const log = (message, type) => {
|
|
|
72
79
|
const date = gray(`[${new Date().toISOString()}]`);
|
|
73
80
|
let msg = `${bold('format-commit')}: ${message}`;
|
|
74
81
|
switch (type) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
case 'error':
|
|
83
|
+
msg = red(msg);
|
|
84
|
+
break;
|
|
85
|
+
case 'success':
|
|
86
|
+
msg = green(msg);
|
|
87
|
+
break;
|
|
88
|
+
case 'warning':
|
|
89
|
+
msg = yellow(msg);
|
|
90
|
+
break;
|
|
84
91
|
}
|
|
85
92
|
console.log(`${date} ${type === 'error' ? red(msg) : (type === 'success' ? green(msg) : msg)}`);
|
|
86
93
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "format-commit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Format and standardize your
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Format and standardize your Git commits",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"type": "commonjs",
|
|
7
7
|
"scripts": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"bin": {
|
|
18
18
|
"format-commit": "./lib/index.js"
|
|
19
19
|
},
|
|
20
|
-
"author": "
|
|
20
|
+
"author": "Thomas BARKATS",
|
|
21
21
|
"keywords": [
|
|
22
22
|
"git",
|
|
23
23
|
"commit",
|
|
@@ -29,12 +29,12 @@
|
|
|
29
29
|
],
|
|
30
30
|
"license": "ISC",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"commander": "^
|
|
33
|
-
"kleur": "^4.1.
|
|
34
|
-
"prompts": "^2.4.
|
|
32
|
+
"commander": "^9.2.0",
|
|
33
|
+
"kleur": "^4.1.4",
|
|
34
|
+
"prompts": "^2.4.2"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"eslint": "^
|
|
37
|
+
"eslint": "^8.14.0"
|
|
38
38
|
},
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|