byt-commit-hooks
Version:
git commit hooks
78 lines (73 loc) • 3.05 kB
JavaScript
/*
* @Description:
* @Author: 王国火
* @Date: 2025-06-16 14:14:02
* @LastEditTime: 2025-06-24 11:59:58
* @LastEditors: 王国火
*/
const { execSync } = require('child_process');
const path = require('path');
// 获取暂存区的文件列表,排除已删除的文件
const getStagedFiles = (config) => {
try {
// A:Added,表示添加的文件
// C:Copied,表示复制的文件
// D:Deleted,表示删除的文件
// M:Modified,表示修改的文件
// R:Renamed,表示重命名的文件
// 使用 --diff-filter=ACMR 只获取添加、复制、修改、重命名的文件
const scanDir = config.scanDir || 'src';
const output = execSync(`git diff --name-only --cached --diff-filter=ACR ${scanDir}`).toString().trim();
return output ? output.split('\n') : [];
} catch (error) {
console.error('\x1b[31m获取暂存区文件失败:', error.message, '\x1b[0m');
process.exit(1);
return [];
}
};
// 定义文件名规范
const isValidFileName = (filename) => {
// 排除目录和隐藏文件
if (filename.startsWith('.') || filename.includes('/.')) return true;
// 检查 Vue 文件 (支持 PascalCase 和 kebab-case)
if (filename.endsWith('.vue') || filename.endsWith('.jsx')) {
const baseName = path.basename(filename);
// 检查是否为 PascalCase (首字母大写,后续字母可以是字母或数字,单词间无分隔符)
const isPascalCase = /^[A-Z][a-zA-Z0-9]+\.(vue|jsx)$/.test(baseName);
// 检查是否为 kebab-case (全小写字母和数字,单词间用连字符分隔)
const isKebabCase = /^[a-z]+(-[a-z0-9]+)*\.(vue|jsx)$/.test(baseName);
return isPascalCase || isKebabCase;
}
// 检查 JS/TS 文件 (支持 camelCase 和 kebab-case)
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
const baseName = path.basename(filename);
const isCamelCase = /^[a-z][a-zA-Z]+(\.[a-zA-Z0-9]+)?\.(js|ts)$/.test(baseName);
const isKebabCase = /^[a-z]+(-[a-z]+)(\.[a-zA-Z0-9]+)?\.(js|ts)$/.test(baseName);
return isCamelCase || isKebabCase;
}
return true;
};
const lintFileNames = (config = {}) => {
// 检查文件
const stagedFiles = getStagedFiles(config);
let hasError = false;
const successMsg='✅ \x1b[32m扫描文件名通过。\x1b[0m';
if (stagedFiles.length === 0) {
console.log(successMsg);
return;
};
stagedFiles.forEach((file) => {
if (!isValidFileName(file)) {
console.error(`❌ \x1b[31m文件名不符合规范: ${file}\x1b[0m`);
hasError = true;
}
});
if (hasError) {
console.log('\n🚫 \x1b[31m提交被阻止: 发现不符合规范的文件名。\x1b[0m\n请按照以下规则重命名文件:\n - Vue/JSX 组件: PascalCase 或 kebab-case\n - JS/TS 文件: camelCase 或 kebab-case');
process.exit(1); // 退出码 1 会阻止提交
} else {
console.log(successMsg);
// if(last)process.exit(0);
}
}
module.exports = lintFileNames;