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 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** | The formatting of your commit titles. <br> 1: (type) Name / 2: (type) name <br> 3: type: Name / 4: type: Name |
26
- | **types** | The different types of commit allowed. Not defined during assisted configuration, default values used: <br> feat / fix / core / test |
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 (options, config) => {
8
- if (!options || !config) {
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 = await utils.getCurrentBranch();
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
- * Get commit allowed types from custom config if exist
27
- * or get default types from options file
28
- */
29
- choices: config.types ? config.types : options.commitTypes,
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
- const commitTitle = utils.formatCommitTitle(commit.type, commit.title, config.format);
93
- const commitRes = await utils.handleCmdExec(`git add -A && git commit -m "${commitTitle}" -m "${commit.description}"`);
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 = await utils.handleCmdExec(`npm version ${commit.version} --preid=${preRelease.tag}`);
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 = await utils.handleCmdExec(`npm version ${version} --allow-same-version`);
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 = await utils.handleCmdExec(`git push -u origin ${currentBranch}`);
166
+ const gitPush = utils.handleCmdExec(`git push -u origin ${currentBranch}`);
134
167
  console.log(gitPush);
135
168
  }
136
- const gitStatus = await utils.handleCmdExec('git status');
169
+ const gitStatus = utils.handleCmdExec('git status');
137
170
  console.log(gitStatus);
138
171
  };
@@ -1,14 +1,20 @@
1
1
  {
2
2
  "format": 1,
3
3
  "minLength": 8,
4
- "maxLength": 70,
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": "Bug(s) correction" },
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(options);
27
+ const setupResult = await setup(true);
27
28
  if (setupResult && setupResult.commitAfter) {
28
- commit(options, setupResult.config);
29
+ commit(setupResult.config, program.test);
29
30
  }
30
31
  } else {
31
- commit(options, JSON.parse(data));
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 (options) => {
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 = await utils.getCurrentBranch();
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
- maxLengt: configChoices.maxLength,
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(`write ${options.configFile} file...`);
96
- await fs.writeFileSync(`./${options.configFile}.json`, parsedConfig);
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
- 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()}`;
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 = async (command) => {
69
+ const handleCmdExec = (command) => {
62
70
  try {
63
- const output = await execSync(command);
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
- case 'error':
76
- msg = red(msg);
77
- break;
78
- case 'success':
79
- msg = green(msg);
80
- break;
81
- case 'warning':
82
- msg = yellow(msg);
83
- break;
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.1.8",
4
- "description": "Format and standardize your git commits",
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": "Sendups",
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": "^6.2.1",
33
- "kleur": "^4.1.3",
34
- "prompts": "^2.4.0"
32
+ "commander": "^9.2.0",
33
+ "kleur": "^4.1.4",
34
+ "prompts": "^2.4.2"
35
35
  },
36
36
  "devDependencies": {
37
- "eslint": "^7.16.0"
37
+ "eslint": "^8.14.0"
38
38
  },
39
39
  "repository": {
40
40
  "type": "git",