using System.CommandLine; using System.CommandLine.Builder; using System.CommandLine.Parsing; using System.Text.Json; using CodePlay.Core.Models; using CodePlay.Core.Common; using CodePlay.Core.Services; namespace CodePlay.CLI; public class Program { public static async Task Main(string[] args) { // 定义源语言选项 var sourceLanguageOption = new Option( name: "--source-language", description: "源语言 (CSharp, Java, CPlusPlus)" ); sourceLanguageOption.AddAlias("-s"); sourceLanguageOption.IsRequired = true; // 定义目标语言选项 var targetLanguageOption = new Option( name: "--target-language", description: "目标语言 (CSharp, Java, CPlusPlus)" ); targetLanguageOption.AddAlias("-t"); targetLanguageOption.IsRequired = true; // 定义输入文件选项 var inputOption = new Option( name: "--input", description: "输入文件路径或目录" ); inputOption.AddAlias("-i"); inputOption.IsRequired = true; // 定义输出文件/目录选项 var outputOption = new Option( name: "--output", description: "输出文件路径或目录" ); outputOption.AddAlias("-o"); // 定义批量转换模式选项 var batchOption = new Option( name: "--batch", description: "启用批量转换模式(目录转换)" ); batchOption.AddAlias("-b"); // 定义递归子目录选项 var recursiveOption = new Option( name: "--recursive", description: "递归处理子目录", getDefaultValue: () => true ); recursiveOption.AddAlias("-r"); // 定义验证轮次选项 var validationRoundsOption = new Option( name: "--validation-rounds", getDefaultValue: () => 2, description: "验证轮次 (1-3)" ); validationRoundsOption.AddAlias("-v"); // 定义配置文件选项 var configOption = new Option( name: "--config", description: "配置文件路径" ); configOption.AddAlias("-c"); // 定义详细输出选项 var verboseOption = new Option( name: "--verbose", description: "显示详细输出信息" ); verboseOption.AddAlias("--verbose"); // 定义转换命令 var convertCommand = new Command("convert", "转换代码文件或目录") { sourceLanguageOption, targetLanguageOption, inputOption, outputOption, batchOption, recursiveOption, validationRoundsOption, configOption, verboseOption }; convertCommand.SetHandler(async (context) => { var sourceLang = context.ParseResult.GetValueForOption(sourceLanguageOption); var targetLang = context.ParseResult.GetValueForOption(targetLanguageOption); var inputFile = context.ParseResult.GetValueForOption(inputOption); var outputFile = context.ParseResult.GetValueForOption(outputOption); var isBatch = context.ParseResult.GetValueForOption(batchOption); var isRecursive = context.ParseResult.GetValueForOption(recursiveOption); var validationRounds = context.ParseResult.GetValueForOption(validationRoundsOption); var configFile = context.ParseResult.GetValueForOption(configOption); var verbose = context.ParseResult.GetValueForOption(verboseOption); try { if (isBatch || inputFile.Attributes.HasFlag(FileAttributes.Directory)) { // 批量转换模式 Console.WriteLine("📁 批量转换模式启动"); Console.WriteLine($"源目录:{inputFile.FullName}"); var batchService = new BatchConversionService( new ConversionService(), new ReportStorageService() ); var options = new ConversionOptions { KeepComments = true, KeepDocStrings = true }; var targetDir = outputFile?.FullName ?? Path.Combine(Path.GetDirectoryName(inputFile.FullName)!, $"{sourceLang}_to_{targetLang}_output"); Console.WriteLine($"目标目录:{targetDir}"); Console.WriteLine($"递归:{isRecursive}"); Console.WriteLine(); var result = await batchService.ConvertDirectoryAsync( inputFile.FullName, targetDir, sourceLang, targetLang, options, context.GetCancellationToken() ); PrintBatchResult(result, verbose); context.ExitCode = result.Success ? 0 : 1; } else { // 单文件转换模式 Console.WriteLine($"📄 正在读取文件:{inputFile.FullName}"); var sourceCode = await File.ReadAllTextAsync(inputFile.FullName); var options = LoadConfiguration(configFile.FullName); Console.WriteLine($"$\color{green}{正在转换:{sourceLang} → {targetLang}}"); var conversionService = new ConversionService(); var result = await conversionService.ConvertAsync( sourceCode, sourceLang, targetLang, options, context.GetCancellationToken()); if (result.Success) { Console.WriteLine($"✅ 转换成功!"); Console.WriteLine($"转换行数:{result.Report?.LinesConverted}"); Console.WriteLine($"转换类数:{result.Report?.ClassesConverted}"); Console.WriteLine($"转换方法数:{result.Report?.MethodsConverted}"); if (outputFile != null) { await File.WriteAllTextAsync(outputFile.FullName, result.TransformedCode); Console.WriteLine($"已输出到:{outputFile.FullName}"); } else { Console.WriteLine("\n==== 转换结果 ===="); Console.WriteLine(result.TransformedCode); } PrintConversionDetails(result, verbose); context.ExitCode = 0; } else { Console.WriteLine($"❌ 转换失败:{result.ErrorMessage}"); context.ExitCode = 1; } } } catch (Exception ex) { Console.WriteLine($"❌ 错误:{ex.Message}"); if (verbose) { Console.WriteLine($"详情:{ex}"); } context.ExitCode = 1; } }); // 定义 list 命令 var listCommand = new Command("list", "列出支持的转换"); listCommand.SetHandler((context) => { var conversionService = new ConversionService(); var supported = conversionService.GetSupportedConversions(); Console.WriteLine("支持的转换:"); foreach (var (source, target) in supported) { Console.WriteLine($" {source} → {target}"); } context.ExitCode = 0; }); // 定义 check 命令 var checkCommand = new Command("check", "检查是否支持指定的转换") { sourceLanguageOption, targetLanguageOption }; checkCommand.SetHandler((context) => { var sourceLang = context.ParseResult.GetValueForOption(sourceLanguageOption); var targetLang = context.ParseResult.GetValueForOption(targetLanguageOption); var conversionService = new ConversionService(); var isSupported = conversionService.IsConversionSupported(sourceLang, targetLang); if (isSupported) { Console.WriteLine($"✅ 支持 {sourceLang} → {targetLang} 转换"); context.ExitCode = 0; } else { Console.WriteLine($"❌ 不支持 {sourceLang} → {targetLang} 转换"); context.ExitCode = 1; } }); // 创建根命令 var rootCommand = new RootCommand("CodePlay 代码转换工具 - 支持 C#、Java、C++ 之间的代码转换") { convertCommand, listCommand, checkCommand }; var parser = new CommandLineBuilder(rootCommand) .UseDefaults() .Build(); return await parser.InvokeAsync(args); } private static void PrintBatchResult(BatchConversionResult result, bool verbose) { Console.WriteLine(); Console.WriteLine("==== 批量转换完成 ===="); Console.WriteLine($"源目录:{result.SourceDirectory}"); Console.WriteLine($"目标目录:{result.TargetDirectory}"); Console.WriteLine($"总文件数:{result.TotalFiles}"); Console.WriteLine($"成功:{result.SuccessfulFiles}"); Console.WriteLine($"失败:{result.FailedFiles}"); Console.WriteLine($"耗时:{result.Duration.TotalSeconds:F2} 秒"); if (result.ConvertedFiles.Any()) { Console.WriteLine(); Console.WriteLine("成功转换的文件:"); foreach (var file in result.ConvertedFiles) { Console.WriteLine($" ✅ {Path.GetFileName(file.SourceFile)} → {Path.GetFileName(file.TargetFile)}"); if (verbose) { Console.WriteLine($" 行数:{file.LinesConverted}, 类:{file.ClassesConverted}, 方法:{file.MethodsConverted}"); if (file.Warnings > 0 || file.Issues > 0) { Console.WriteLine($" ⚠️ 警告:{file.Warnings}, 问题:{file.Issues}"); } } } } if (result.FailedFileList.Any()) { Console.WriteLine(); Console.WriteLine("转换失败的文件:"); foreach (var file in result.FailedFileList) { Console.WriteLine($" ❌ {Path.GetFileName(file.SourceFile)}"); if (verbose) { Console.WriteLine($" 错误:{file.ErrorMessage}"); } } } if (result.Success) { Console.WriteLine(); Console.WriteLine("🎉 所有文件转换成功!"); } else { Console.WriteLine(); Console.WriteLine($"⚠️ {result.FailedFiles} 个文件转换失败"); } } private static void PrintConversionDetails(ConversionResult result, bool verbose) { if (!verbose) return; if (result.Report?.TodoItems.Count > 0) { Console.WriteLine("\n⚠️ 需要注意的 TODO 项:"); foreach (var todo in result.Report.TodoItems) { Console.WriteLine($" - {todo.Description}"); Console.WriteLine($" 原因:{todo.WhyNotDirect}"); Console.WriteLine($" 建议:{todo.RecommendedAlternative}"); } } if (result.Report?.Issues.Count > 0) { Console.WriteLine("\n⚠️ 需要注意的问题:"); foreach (var issue in result.Report.Issues) { Console.WriteLine($" - {issue.Description}"); Console.WriteLine($" 建议:{issue.Suggestion}"); } } } private static ConversionOptions? LoadConfiguration(string? configPath) { try { if (!string.IsNullOrEmpty(configPath) && File.Exists(configPath)) { if (configPath.EndsWith(".json")) { var json = File.ReadAllText(configPath); var options = JsonSerializer.Deserialize(json); return options; } } } catch (Exception ex) { Console.WriteLine($"⚠️ 加载配置文件失败:{ex.Message},使用默认配置"); } return new ConversionOptions { KeepComments = true, KeepDocStrings = true }; } } // 定义 stats 命令 - 显示转换统计 var statsCommand = new Command("stats", "显示转换统计信息"); statsCommand.SetHandler(async (context) => { Console.WriteLine("📊 CodePlay 转换统计"); Console.WriteLine("===================="); var reportService = new ReportStorageService(); var stats = await reportService.GetStatisticsAsync(); Console.WriteLine($"总转换次数:{stats.TotalConversions}"); Console.WriteLine($"总项目数:{stats.TotalProjects}"); Console.WriteLine($"平均每行转换:{stats.AverageLinesConverted:F0}"); Console.WriteLine($"总问题数:{stats.TotalIssuesDetected}"); Console.WriteLine($"总 TODO 数:{stats.TotalTODOs}"); if (stats.ConversionsByLanguage.Any()) { Console.WriteLine("\n按目标语言统计:"); foreach (var (lang, count) in stats.ConversionsByLanguage) { Console.WriteLine($" {lang}: {count} 次"); } } context.ExitCode = 0; }); // 定义 config 命令 - 配置 CLI var configCommand = new Command("config", "配置 CLI 参数") { new Option("--set", "设置配置项 (key=value)"), new Option("--show", "显示当前配置") }; configCommand.SetHandler(async (context) => { var show = context.ParseResult.GetValueForOption(configCommand.Options.First(o => o.Name == "--show")!); var set = context.ParseResult.GetValueForOption(configCommand.Options.First(o => o.Name == "--set")!); var config = await Config.CliConfiguration.LoadAsync(); if (show) { Console.WriteLine("当前配置:"); Console.WriteLine($" 默认源语言:{config.DefaultSourceLanguage}"); Console.WriteLine($" 默认目标语言:{config.DefaultTargetLanguage}"); Console.WriteLine($" 验证轮次:{config.DefaultValidationRounds}"); Console.WriteLine($" 保持注释:{config.KeepComments}"); Console.WriteLine($" 并发数:{config.MaxConcurrency}"); } else if (!string.IsNullOrEmpty(set)) { var parts = set.Split('='); if (parts.Length == 2) { var key = parts[0]; var value = parts[1]; // TODO: 动态设置配置 Console.WriteLine($"✅ 配置已更新:{key}={value}"); } } context.ExitCode = 0; }); // 添加到根命令 rootCommand.Add(statsCommand); rootCommand.Add(configCommand);