commit-sense-cli 1.0.1 → 1.1.0
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 +20 -2
- package/dist/analysis/validator.d.ts +5 -0
- package/dist/analysis/validator.js +17 -0
- package/dist/index.js +48 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ CommitSense helps developers write accurate, meaningful, and semantically correc
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
npm install -g commit-sense
|
|
18
|
+
npm install -g commit-sense-cli
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
## Usage
|
|
@@ -29,7 +29,7 @@ git add .
|
|
|
29
29
|
Run CommitSense instead of `git commit`:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
commit-sense
|
|
32
|
+
commit-sense-cli
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
Follow the interactive prompts to confirm or edit the commit message.
|
|
@@ -41,3 +41,21 @@ Follow the interactive prompts to confirm or edit the commit message.
|
|
|
41
41
|
3. Build: `npm run build`
|
|
42
42
|
4. Run locally: `npm run dev` (or `node bin/commitsense.js`)
|
|
43
43
|
|
|
44
|
+
## Optional: Enforce Commit Convention
|
|
45
|
+
|
|
46
|
+
You can use `commit-sense-cli` to validate commit messages with git hooks (e.g., using **Husky**).
|
|
47
|
+
|
|
48
|
+
1. Install Husky:
|
|
49
|
+
```bash
|
|
50
|
+
npm install --save-dev husky
|
|
51
|
+
npx husky init
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
2. Add a `commit-msg` hook:
|
|
55
|
+
```bash
|
|
56
|
+
echo "npx commit-sense-cli validate \$1" > .husky/commit-msg
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Now, if you try to commit with an invalid message (e.g., `git commit -m "bad message"`), it will be rejected.
|
|
60
|
+
|
|
61
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateCommitMessage = validateCommitMessage;
|
|
4
|
+
function validateCommitMessage(message) {
|
|
5
|
+
const errors = [];
|
|
6
|
+
const conventionalCommitRegex = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+\))?: .+$/;
|
|
7
|
+
const firstLine = message.split('\n')[0];
|
|
8
|
+
if (!conventionalCommitRegex.test(firstLine)) {
|
|
9
|
+
errors.push('Commit message must follow format: type(scope): subject');
|
|
10
|
+
errors.push('Example: feat(auth): add login support');
|
|
11
|
+
errors.push('Allowed types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert');
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
isValid: errors.length === 0,
|
|
15
|
+
errors
|
|
16
|
+
};
|
|
17
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,55 @@ const git_1 = require("./utils/git");
|
|
|
9
9
|
const classifier_1 = require("./analysis/classifier");
|
|
10
10
|
const scope_1 = require("./analysis/scope");
|
|
11
11
|
const child_process_1 = require("child_process");
|
|
12
|
+
const validator_1 = require("./analysis/validator");
|
|
13
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
12
14
|
async function main() {
|
|
15
|
+
// 0. Handle Validation Command
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
if (args.length > 0 && (args[0] === 'validate' || args[0] === '--validate')) {
|
|
18
|
+
const msgFile = args[1];
|
|
19
|
+
if (!msgFile) {
|
|
20
|
+
console.error(chalk_1.default.red('Error: Commit message file path required for validation.'));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const msg = await fs_extra_1.default.readFile(msgFile, 'utf-8');
|
|
25
|
+
const result = (0, validator_1.validateCommitMessage)(msg);
|
|
26
|
+
if (!result.isValid) {
|
|
27
|
+
console.error(chalk_1.default.red('Invalid Commit Message:'));
|
|
28
|
+
result.errors.forEach(e => console.error(chalk_1.default.yellow(` - ${e}`)));
|
|
29
|
+
// Provide Suggestions
|
|
30
|
+
try {
|
|
31
|
+
const stagedFiles = await (0, git_1.getStagedFiles)();
|
|
32
|
+
if (stagedFiles.length > 0) {
|
|
33
|
+
const fileChanges = await Promise.all(stagedFiles.map(async (file) => ({
|
|
34
|
+
path: file,
|
|
35
|
+
diff: await (0, git_1.getStagedFileDiff)(file)
|
|
36
|
+
})));
|
|
37
|
+
const classification = await (0, classifier_1.classifyChanges)(fileChanges);
|
|
38
|
+
const suggestedScope = (0, scope_1.detectScope)(stagedFiles);
|
|
39
|
+
console.log(chalk_1.default.cyan('\n----------------------------------------'));
|
|
40
|
+
console.log(chalk_1.default.cyan('🤖 CommitSense Suggestion:'));
|
|
41
|
+
console.log(chalk_1.default.green(`${classification.type}${suggestedScope ? `(${suggestedScope})` : ''}: <description>`));
|
|
42
|
+
console.log(chalk_1.default.gray(`Reason: ${classification.reason}`));
|
|
43
|
+
console.log(chalk_1.default.cyan('----------------------------------------\n'));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
// Ignore analysis errors during validation to avoid noise
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(chalk_1.default.green('Commit message is valid.'));
|
|
53
|
+
process.exit(0);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error(chalk_1.default.red(`Error reading commit message file: ${msgFile}`), error);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
13
61
|
console.log(chalk_1.default.cyan('CommitSense - Smart Commit Wizard'));
|
|
14
62
|
// 1. Get staged files
|
|
15
63
|
const stagedFiles = await (0, git_1.getStagedFiles)();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commit-sense-cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"test": "jest",
|
|
21
21
|
"build": "tsc",
|
|
22
|
-
"dev": "ts-node src/index.ts"
|
|
22
|
+
"dev": "ts-node src/index.ts",
|
|
23
|
+
"prepare": "husky"
|
|
23
24
|
},
|
|
24
25
|
"repository": {
|
|
25
26
|
"type": "git",
|
|
@@ -34,9 +35,11 @@
|
|
|
34
35
|
},
|
|
35
36
|
"homepage": "https://github.com/abhishekpanda0620/commit-sense#readme",
|
|
36
37
|
"dependencies": {
|
|
38
|
+
"@types/fs-extra": "^11.0.4",
|
|
37
39
|
"@types/node": "^25.2.3",
|
|
38
40
|
"chalk": "^5.6.2",
|
|
39
41
|
"commander": "^14.0.3",
|
|
42
|
+
"fs-extra": "^11.3.3",
|
|
40
43
|
"prompts": "^2.4.2",
|
|
41
44
|
"simple-git": "^3.30.0",
|
|
42
45
|
"ts-node": "^10.9.2",
|
|
@@ -45,6 +48,7 @@
|
|
|
45
48
|
"devDependencies": {
|
|
46
49
|
"@types/jest": "^30.0.0",
|
|
47
50
|
"@types/prompts": "^2.4.9",
|
|
51
|
+
"husky": "^9.1.7",
|
|
48
52
|
"jest": "^30.2.0",
|
|
49
53
|
"ts-jest": "^29.4.6"
|
|
50
54
|
}
|