chore: remove all cn comments (#277)
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { Command } from 'commander';
|
||||
import { CliOptions } from '../types/config';
|
||||
|
||||
/**
|
||||
* 创建命令行程序
|
||||
*/
|
||||
export const createProgram = (): Command => {
|
||||
const program = new Command();
|
||||
|
||||
program
|
||||
.name('ai-translate')
|
||||
.description('将代码仓库中的中文注释翻译为英文')
|
||||
.version('1.0.0');
|
||||
|
||||
program
|
||||
.requiredOption('-r, --root <directory>', '需要处理的根目录')
|
||||
.option('-e, --exts <extensions>', '文件扩展名,用逗号分隔 (例: ts,js,go)', '')
|
||||
.option('--access-key-id <key>', '火山引擎 Access Key ID')
|
||||
.option('--secret-access-key <key>', '火山引擎 Secret Access Key')
|
||||
.option('--region <region>', '火山引擎服务区域', 'cn-beijing')
|
||||
.option('--source-language <lang>', '源语言代码', 'zh')
|
||||
.option('--target-language <lang>', '目标语言代码', 'en')
|
||||
.option('--dry-run', '仅分析不实际修改文件')
|
||||
.option('-v, --verbose', '详细输出模式')
|
||||
.option('-o, --output <file>', '报告输出文件路径')
|
||||
.option('-c, --config <file>', '配置文件路径')
|
||||
.option('--concurrency <number>', '并发翻译数量', '3')
|
||||
.option('--max-retries <number>', '最大重试次数', '3')
|
||||
.option('--timeout <number>', 'API超时时间(毫秒)', '30000');
|
||||
|
||||
return program;
|
||||
};
|
||||
|
||||
/**
|
||||
* 解析命令行选项
|
||||
*/
|
||||
export const parseOptions = (program: Command): CliOptions => {
|
||||
const options = program.opts();
|
||||
|
||||
return {
|
||||
root: options.root,
|
||||
exts: options.exts,
|
||||
accessKeyId: options.accessKeyId,
|
||||
secretAccessKey: options.secretAccessKey,
|
||||
region: options.region,
|
||||
sourceLanguage: options.sourceLanguage,
|
||||
targetLanguage: options.targetLanguage,
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
output: options.output,
|
||||
config: options.config
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示帮助信息
|
||||
*/
|
||||
export const showHelp = (): void => {
|
||||
console.log(`
|
||||
🤖 AI翻译工具 - 中文注释转英文(基于火山引擎翻译)
|
||||
|
||||
使用方法:
|
||||
ai-translate --root <目录> [选项]
|
||||
|
||||
示例:
|
||||
# 基本使用
|
||||
ai-translate --root ./src --access-key-id <YOUR_KEY_ID> --secret-access-key <YOUR_SECRET>
|
||||
|
||||
# 指定文件类型和翻译语言
|
||||
ai-translate --root ./src --exts ts,js,go --source-language zh --target-language en
|
||||
|
||||
# 仅预览,不修改文件
|
||||
ai-translate --root ./src --dry-run
|
||||
|
||||
# 指定区域和并发数
|
||||
ai-translate --root ./src --region ap-southeast-1 --concurrency 5
|
||||
|
||||
# 生成详细报告
|
||||
ai-translate --root ./src --verbose --output report.json
|
||||
|
||||
环境变量:
|
||||
VOLC_ACCESS_KEY_ID 火山引擎 Access Key ID(必需)
|
||||
VOLC_SECRET_ACCESS_KEY 火山引擎 Secret Access Key(必需)
|
||||
|
||||
配置文件示例 (config.json):
|
||||
{
|
||||
"translation": {
|
||||
"accessKeyId": "your-access-key-id",
|
||||
"secretAccessKey": "your-secret-access-key",
|
||||
"region": "cn-beijing",
|
||||
"sourceLanguage": "zh",
|
||||
"targetLanguage": "en",
|
||||
"maxRetries": 3,
|
||||
"concurrency": 3
|
||||
},
|
||||
"processing": {
|
||||
"defaultExtensions": ["ts", "js", "go", "md"]
|
||||
}
|
||||
}
|
||||
`);
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示版本信息
|
||||
*/
|
||||
export const showVersion = (): void => {
|
||||
console.log('ai-translate version 1.0.0');
|
||||
};
|
||||
@@ -0,0 +1,182 @@
|
||||
import { AppConfig, CliOptions, TranslationConfig, ProcessingConfig } from '../types/config';
|
||||
import { deepMerge } from '../utils/fp';
|
||||
|
||||
/**
|
||||
* 默认配置
|
||||
*/
|
||||
const DEFAULT_CONFIG: AppConfig = {
|
||||
translation: {
|
||||
accessKeyId: process.env.VOLC_ACCESS_KEY_ID || '',
|
||||
secretAccessKey: process.env.VOLC_SECRET_ACCESS_KEY || '',
|
||||
region: 'cn-beijing',
|
||||
sourceLanguage: 'zh',
|
||||
targetLanguage: 'en',
|
||||
maxRetries: 3,
|
||||
timeout: 30000,
|
||||
concurrency: 3
|
||||
},
|
||||
processing: {
|
||||
defaultExtensions: [
|
||||
'ts', 'tsx', 'js', 'jsx', 'go', 'md', 'txt', 'json',
|
||||
'yaml', 'yml', 'toml', 'ini', 'conf', 'config',
|
||||
'sh', 'bash', 'zsh', 'fish', 'py', 'css', 'scss', 'sass', 'less',
|
||||
'html', 'htm', 'xml', 'php', 'rb', 'rs', 'java', 'c', 'h',
|
||||
'cpp', 'cxx', 'cc', 'hpp', 'cs'
|
||||
],
|
||||
outputFormat: 'console'
|
||||
},
|
||||
git: {
|
||||
ignorePatterns: ['node_modules/**', '.git/**', 'dist/**', 'build/**'],
|
||||
includeUntracked: false
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 从文件加载配置
|
||||
*/
|
||||
export const loadConfigFromFile = async (configPath: string): Promise<Partial<AppConfig>> => {
|
||||
try {
|
||||
const fs = await import('fs/promises');
|
||||
const configContent = await fs.readFile(configPath, 'utf-8');
|
||||
return JSON.parse(configContent);
|
||||
} catch (error) {
|
||||
console.warn(`配置文件加载失败: ${configPath}`, error);
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 从命令行选项创建配置
|
||||
*/
|
||||
export const createConfigFromOptions = (options: CliOptions): Partial<AppConfig> => {
|
||||
const config: Partial<AppConfig> = {};
|
||||
|
||||
// 翻译配置
|
||||
if (options.accessKeyId || options.secretAccessKey || options.region || options.sourceLanguage || options.targetLanguage) {
|
||||
config.translation = {} as Partial<TranslationConfig>;
|
||||
if (options.accessKeyId) {
|
||||
config.translation!.accessKeyId = options.accessKeyId;
|
||||
}
|
||||
if (options.secretAccessKey) {
|
||||
config.translation!.secretAccessKey = options.secretAccessKey;
|
||||
}
|
||||
if (options.region) {
|
||||
config.translation!.region = options.region;
|
||||
}
|
||||
if (options.sourceLanguage) {
|
||||
config.translation!.sourceLanguage = options.sourceLanguage;
|
||||
}
|
||||
if (options.targetLanguage) {
|
||||
config.translation!.targetLanguage = options.targetLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理配置
|
||||
if (options.output) {
|
||||
config.processing = {} as Partial<ProcessingConfig>;
|
||||
// 根据输出文件扩展名推断格式
|
||||
const ext = options.output.toLowerCase().split('.').pop();
|
||||
if (ext === 'json') {
|
||||
config.processing!.outputFormat = 'json';
|
||||
} else if (ext === 'md') {
|
||||
config.processing!.outputFormat = 'markdown';
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
/**
|
||||
* 合并配置
|
||||
*/
|
||||
export const mergeConfigs = (...configs: Partial<AppConfig>[]): AppConfig => {
|
||||
return configs.reduce(
|
||||
(merged, config) => deepMerge(merged, config),
|
||||
{ ...DEFAULT_CONFIG }
|
||||
) as AppConfig;
|
||||
};
|
||||
|
||||
/**
|
||||
* 加载完整配置
|
||||
*/
|
||||
export const loadConfig = async (options: CliOptions): Promise<AppConfig> => {
|
||||
const configs: Partial<AppConfig>[] = [DEFAULT_CONFIG];
|
||||
|
||||
// 加载配置文件
|
||||
if (options.config) {
|
||||
const fileConfig = await loadConfigFromFile(options.config);
|
||||
configs.push(fileConfig);
|
||||
}
|
||||
|
||||
// 加载命令行选项配置
|
||||
const optionsConfig = createConfigFromOptions(options);
|
||||
configs.push(optionsConfig);
|
||||
|
||||
return mergeConfigs(...configs);
|
||||
};
|
||||
|
||||
/**
|
||||
* 验证配置
|
||||
*/
|
||||
export const validateConfig = (config: AppConfig): { valid: boolean; errors: string[] } => {
|
||||
const errors: string[] = [];
|
||||
|
||||
// 验证火山引擎 Access Key ID
|
||||
if (!config.translation.accessKeyId) {
|
||||
errors.push('火山引擎 Access Key ID 未设置,请通过环境变量VOLC_ACCESS_KEY_ID或--access-key-id参数提供');
|
||||
}
|
||||
|
||||
// 验证火山引擎 Secret Access Key
|
||||
if (!config.translation.secretAccessKey) {
|
||||
errors.push('火山引擎 Secret Access Key 未设置,请通过环境变量VOLC_SECRET_ACCESS_KEY或--secret-access-key参数提供');
|
||||
}
|
||||
|
||||
// 验证区域
|
||||
const validRegions = ['cn-beijing', 'ap-southeast-1', 'us-east-1'];
|
||||
if (!validRegions.includes(config.translation.region)) {
|
||||
console.warn(`未知的区域: ${config.translation.region},建议使用: ${validRegions.join(', ')}`);
|
||||
}
|
||||
|
||||
// 验证语言代码
|
||||
const validLanguages = ['zh', 'en', 'ja', 'ko', 'fr', 'de', 'es', 'pt', 'ru'];
|
||||
if (!validLanguages.includes(config.translation.sourceLanguage)) {
|
||||
console.warn(`未知的源语言: ${config.translation.sourceLanguage},建议使用: ${validLanguages.join(', ')}`);
|
||||
}
|
||||
if (!validLanguages.includes(config.translation.targetLanguage)) {
|
||||
console.warn(`未知的目标语言: ${config.translation.targetLanguage},建议使用: ${validLanguages.join(', ')}`);
|
||||
}
|
||||
|
||||
// 验证并发数
|
||||
if (config.translation.concurrency < 1 || config.translation.concurrency > 10) {
|
||||
errors.push('并发数应该在1-10之间');
|
||||
}
|
||||
|
||||
// 验证超时时间
|
||||
if (config.translation.timeout < 1000 || config.translation.timeout > 300000) {
|
||||
errors.push('超时时间应该在1000-300000毫秒之间');
|
||||
}
|
||||
|
||||
return { valid: errors.length === 0, errors };
|
||||
};
|
||||
|
||||
/**
|
||||
* 打印配置信息
|
||||
*/
|
||||
export const printConfigInfo = (config: AppConfig, verbose: boolean = false): void => {
|
||||
console.log('🔧 当前配置:');
|
||||
console.log(` 区域: ${config.translation.region}`);
|
||||
console.log(` 源语言: ${config.translation.sourceLanguage}`);
|
||||
console.log(` 目标语言: ${config.translation.targetLanguage}`);
|
||||
console.log(` 并发数: ${config.translation.concurrency}`);
|
||||
console.log(` 重试次数: ${config.translation.maxRetries}`);
|
||||
console.log(` 输出格式: ${config.processing.outputFormat}`);
|
||||
|
||||
if (verbose) {
|
||||
console.log(` Access Key ID: ${config.translation.accessKeyId ? '已设置' : '未设置'}`);
|
||||
console.log(` Secret Access Key: ${config.translation.secretAccessKey ? '已设置' : '未设置'}`);
|
||||
console.log(` 超时时间: ${config.translation.timeout}ms`);
|
||||
console.log(` 默认扩展名: ${config.processing.defaultExtensions.join(', ')}`);
|
||||
console.log(` 忽略模式: ${config.git.ignorePatterns.join(', ')}`);
|
||||
console.log(` 包含未跟踪文件: ${config.git.includeUntracked ? '是' : '否'}`);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user