- 将preset.ts移动到config目录,符合架构规范 - 迁移php-tools到java-tools,参考Java架构而非PHP - 清理AI层文档,整合为单一README - 删除core层,专注boot和ai层 - 集成AI层与Boot层,实现100%组件集成 - 清理废弃js文件和临时报告文件 - 更新导入路径,保持代码一致性
185 lines
4.3 KiB
JavaScript
185 lines
4.3 KiB
JavaScript
#!/usr/bin/env node
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
/**
|
||
* 基础生成器类
|
||
* 提供通用的 dry-run、文件操作、日志等功能
|
||
*/
|
||
class BaseGenerator {
|
||
constructor(generatorName = 'Generator') {
|
||
this.generatorName = generatorName;
|
||
|
||
// 从环境变量或参数读取配置
|
||
this.dryRun = process.env.DRY_RUN === 'true' || process.argv.includes('--dry-run');
|
||
this.verbose = process.env.VERBOSE === 'true' || process.argv.includes('--verbose');
|
||
|
||
this.stats = {
|
||
filesCreated: 0,
|
||
filesUpdated: 0,
|
||
filesSkipped: 0,
|
||
errors: 0
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 安全写入文件(支持 dry-run)
|
||
*/
|
||
writeFile(filePath, content, description = '') {
|
||
try {
|
||
if (this.dryRun) {
|
||
console.log(` [DRY-RUN] Would create/update: ${filePath}`);
|
||
if (this.verbose && description) {
|
||
console.log(` Description: ${description}`);
|
||
}
|
||
this.stats.filesCreated++;
|
||
return true;
|
||
}
|
||
|
||
// 确保目录存在
|
||
this.ensureDir(path.dirname(filePath));
|
||
|
||
// 写入文件
|
||
fs.writeFileSync(filePath, content, 'utf8');
|
||
|
||
const action = fs.existsSync(filePath) ? 'Updated' : 'Created';
|
||
console.log(` ✅ ${action}: ${filePath}`);
|
||
|
||
if (action === 'Created') {
|
||
this.stats.filesCreated++;
|
||
} else {
|
||
this.stats.filesUpdated++;
|
||
}
|
||
|
||
return true;
|
||
} catch (error) {
|
||
console.error(` ❌ Failed to write ${filePath}:`, error.message);
|
||
this.stats.errors++;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 确保目录存在
|
||
*/
|
||
ensureDir(dirPath) {
|
||
if (this.dryRun) {
|
||
return;
|
||
}
|
||
|
||
if (!fs.existsSync(dirPath)) {
|
||
fs.mkdirSync(dirPath, { recursive: true });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 读取文件(安全)
|
||
*/
|
||
readFile(filePath) {
|
||
try {
|
||
if (!fs.existsSync(filePath)) {
|
||
return null;
|
||
}
|
||
return fs.readFileSync(filePath, 'utf8');
|
||
} catch (error) {
|
||
console.error(` ❌ Failed to read ${filePath}:`, error.message);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 检查文件是否存在
|
||
*/
|
||
fileExists(filePath) {
|
||
return fs.existsSync(filePath);
|
||
}
|
||
|
||
/**
|
||
* 日志输出
|
||
*/
|
||
log(message, level = 'info') {
|
||
const prefix = {
|
||
'info': ' ℹ️ ',
|
||
'success': ' ✅',
|
||
'warning': ' ⚠️ ',
|
||
'error': ' ❌',
|
||
'debug': ' 🔍'
|
||
};
|
||
|
||
if (level === 'debug' && !this.verbose) {
|
||
return;
|
||
}
|
||
|
||
console.log(`${prefix[level] || ' '}${message}`);
|
||
}
|
||
|
||
/**
|
||
* 输出统计信息
|
||
*/
|
||
printStats(additionalStats = {}) {
|
||
console.log('\n📊 Generation Statistics');
|
||
console.log('==================================================');
|
||
|
||
if (this.dryRun) {
|
||
console.log(' 🔍 DRY-RUN MODE - No files were actually modified');
|
||
}
|
||
|
||
console.log(` 📁 Files Created: ${this.stats.filesCreated}`);
|
||
console.log(` 🔄 Files Updated: ${this.stats.filesUpdated}`);
|
||
console.log(` ⏭️ Files Skipped: ${this.stats.filesSkipped}`);
|
||
console.log(` ❌ Errors: ${this.stats.errors}`);
|
||
|
||
// 输出额外的统计信息
|
||
for (const [key, value] of Object.entries(additionalStats)) {
|
||
console.log(` 📈 ${key}: ${value}`);
|
||
}
|
||
|
||
const total = this.stats.filesCreated + this.stats.filesUpdated;
|
||
const successRate = total > 0
|
||
? ((total / (total + this.stats.errors)) * 100).toFixed(2)
|
||
: '0.00';
|
||
|
||
console.log(` 📊 Success Rate: ${successRate}%`);
|
||
console.log('==================================================');
|
||
}
|
||
|
||
/**
|
||
* kebab-case 转换
|
||
*/
|
||
toKebabCase(str) {
|
||
return String(str)
|
||
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
||
.replace(/_/g, '-')
|
||
.toLowerCase();
|
||
}
|
||
|
||
/**
|
||
* PascalCase 转换
|
||
*/
|
||
toPascalCase(str) {
|
||
return String(str)
|
||
.split(/[-_]/)
|
||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||
.join('');
|
||
}
|
||
|
||
/**
|
||
* camelCase 转换
|
||
*/
|
||
toCamelCase(str) {
|
||
const pascal = this.toPascalCase(str);
|
||
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
||
}
|
||
|
||
/**
|
||
* snake_case 转换
|
||
*/
|
||
toSnakeCase(str) {
|
||
return str.replace(/([A-Z])/g, '_$1').toLowerCase().replace(/^_/, '');
|
||
}
|
||
}
|
||
|
||
module.exports = BaseGenerator;
|
||
|