smart-git-commit
Version:
AI-powered smart commit message generator for Git diffs.
69 lines (58 loc) • 2.37 kB
JavaScript
export function basicCommit(fileChanges) {
if (fileChanges.length === 0) return "chore: update project files";
const scopes = new Set();
let changeIndicators = {
fix: false,
feat: false,
refactor: false,
docs: false,
test: false,
};
const importantFiles = ["package.json", "README.md", ".env", ".gitignore"];
fileChanges.forEach((file) => {
const parts = file.file.split("/");
// Scope = 2nd level folder, else fallback to file itself
const scope = parts.length >= 2 ? parts[1] : parts[0];
scopes.add(scope);
const changesCombined = [...file.additions, ...file.deletions]
.join(" ")
.toLowerCase();
if (/fix|bug|error|hotfix/.test(changesCombined))
changeIndicators.fix = true;
if (/add|create|feature|implement|introduce/.test(changesCombined))
changeIndicators.feat = true;
if (/refactor|optimize|cleanup|enhance/.test(changesCombined))
changeIndicators.refactor = true;
if (/doc|readme|documentation/.test(changesCombined))
changeIndicators.docs = true;
if (/test|jest|spec|assert/.test(changesCombined))
changeIndicators.test = true;
});
// Prioritize change type
let type = "chore";
if (changeIndicators.fix) type = "fix";
else if (changeIndicators.feat) type = "feat";
else if (changeIndicators.refactor) type = "refactor";
else if (changeIndicators.docs) type = "docs";
else if (changeIndicators.test) type = "test";
const scopeArray = Array.from(scopes);
const scopeStr = scopeArray.join(", ");
const scopeLabel = scopeArray.length > 1 ? "modules" : "module";
// Dynamic Action
let action = "updated";
if (type === "fix") action = "fixed bugs in";
else if (type === "feat") action = "introduced new features in";
else if (type === "refactor") action = "refactored";
else if (type === "docs") action = "updated documentation in";
else if (type === "test") action = "added or modified tests in";
// Special Case: Critical Files
const criticalChanges = fileChanges.filter((f) =>
importantFiles.includes(f.file)
);
if (criticalChanges.length > 0) {
const criticalFiles = criticalChanges.map((f) => f.file).join(", ");
return `chore(config): updated project configuration files (${criticalFiles})`;
}
// Final Commit Message
return `${type}(${scopeStr}): ${action} ${scopeLabel}`;
}