2fcc22b501
Program.test.cs -- 将顶层语句改为 ManualTest.RunAsync() 方法,消除入口点冲突 BatchConversionService.cs:96 -- options 可空参数添加 ?? new ConversionOptions() 空值回退 Co-authored-by: monkeycode-ai <monkeycode-ai@chaitin.com>
196 lines
7.7 KiB
C#
196 lines
7.7 KiB
C#
using CodePlay.Core.Models;
|
|
using CodePlay.Core.Common;
|
|
|
|
namespace CodePlay.Core.Services;
|
|
|
|
public interface IBatchConversionService
|
|
{
|
|
Task<BatchConversionResult> ConvertDirectoryAsync(string sourceDirectory, string targetDirectory,
|
|
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
|
|
CancellationToken cancellationToken = default);
|
|
|
|
Task<BatchConversionResult> ConvertFilesAsync(IEnumerable<string> sourceFiles, string targetDirectory,
|
|
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
|
|
CancellationToken cancellationToken = default);
|
|
}
|
|
|
|
public class BatchConversionService : IBatchConversionService
|
|
{
|
|
private readonly ConversionService _conversionService;
|
|
private readonly IReportStorageService _reportStorageService;
|
|
|
|
public BatchConversionService(ConversionService conversionService, IReportStorageService reportStorageService)
|
|
{
|
|
_conversionService = conversionService;
|
|
_reportStorageService = reportStorageService;
|
|
}
|
|
|
|
public async Task<BatchConversionResult> ConvertDirectoryAsync(string sourceDirectory, string targetDirectory,
|
|
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var result = new BatchConversionResult
|
|
{
|
|
SourceDirectory = sourceDirectory,
|
|
TargetDirectory = targetDirectory,
|
|
SourceLanguage = sourceLanguage,
|
|
TargetLanguage = targetLanguage,
|
|
StartedAt = DateTime.UtcNow
|
|
};
|
|
|
|
if (!Directory.Exists(sourceDirectory))
|
|
{
|
|
result.Success = false;
|
|
result.ErrorMessage = $"Source directory not found: {sourceDirectory}";
|
|
return result;
|
|
}
|
|
|
|
var fileExtension = GetFileExtension(sourceLanguage);
|
|
var sourceFiles = Directory.GetFiles(sourceDirectory, $"*{fileExtension}", SearchOption.AllDirectories);
|
|
|
|
return await ConvertFilesAsync(sourceFiles, targetDirectory, sourceLanguage, targetLanguage, options, cancellationToken);
|
|
}
|
|
|
|
public async Task<BatchConversionResult> ConvertFilesAsync(IEnumerable<string> sourceFiles, string targetDirectory,
|
|
LanguageType sourceLanguage, LanguageType targetLanguage, ConversionOptions? options = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var result = new BatchConversionResult
|
|
{
|
|
TargetDirectory = targetDirectory,
|
|
SourceLanguage = sourceLanguage,
|
|
TargetLanguage = targetLanguage,
|
|
StartedAt = DateTime.UtcNow,
|
|
TotalFiles = sourceFiles.Count()
|
|
};
|
|
|
|
if (!Directory.Exists(targetDirectory))
|
|
{
|
|
Directory.CreateDirectory(targetDirectory);
|
|
}
|
|
|
|
var targetExtension = GetFileExtension(targetLanguage);
|
|
|
|
foreach (var sourceFile in sourceFiles)
|
|
{
|
|
if (cancellationToken.IsCancellationRequested)
|
|
{
|
|
result.CancelledAt = DateTime.UtcNow;
|
|
break;
|
|
}
|
|
|
|
try
|
|
{
|
|
var relativePath = Path.GetRelativePath(Path.GetDirectoryName(sourceFile)!, sourceFile);
|
|
var targetFileName = Path.ChangeExtension(relativePath, targetExtension);
|
|
var targetFilePath = Path.Combine(targetDirectory, targetFileName);
|
|
|
|
var targetFileDir = Path.GetDirectoryName(targetFilePath)!;
|
|
if (!Directory.Exists(targetFileDir))
|
|
{
|
|
Directory.CreateDirectory(targetFileDir);
|
|
}
|
|
|
|
var sourceCode = await File.ReadAllTextAsync(sourceFile, cancellationToken);
|
|
var conversionResult = await _conversionService.ConvertAsync(
|
|
sourceCode, sourceLanguage.ToName(), targetLanguage.ToName(), options ?? new ConversionOptions());
|
|
|
|
if (conversionResult.Success)
|
|
{
|
|
await File.WriteAllTextAsync(targetFilePath, conversionResult.TransformedCode, cancellationToken);
|
|
|
|
result.SuccessfulFiles++;
|
|
result.ConvertedFiles.Add(new ConvertedFileInfo
|
|
{
|
|
SourceFile = sourceFile,
|
|
TargetFile = targetFilePath,
|
|
LinesConverted = conversionResult.Report?.LinesConverted ?? 0,
|
|
ClassesConverted = conversionResult.Report?.ClassesConverted ?? 0,
|
|
MethodsConverted = conversionResult.Report?.MethodsConverted ?? 0,
|
|
Warnings = conversionResult.Warnings.Count,
|
|
Issues = conversionResult.Report?.Issues.Count ?? 0
|
|
});
|
|
|
|
if (conversionResult.Report != null)
|
|
{
|
|
conversionResult.Report.ProjectId = "batch-" + DateTime.UtcNow.ToString("yyyyMMdd");
|
|
await _reportStorageService.SaveReportAsync(conversionResult.Report);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result.FailedFiles++;
|
|
result.FailedFileList.Add(new FailedFileInfo
|
|
{
|
|
SourceFile = sourceFile,
|
|
ErrorMessage = conversionResult.ErrorMessage ?? "Unknown error"
|
|
});
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.FailedFiles++;
|
|
result.FailedFileList.Add(new FailedFileInfo
|
|
{
|
|
SourceFile = sourceFile,
|
|
ErrorMessage = ex.Message
|
|
});
|
|
}
|
|
}
|
|
|
|
result.CompletedAt = DateTime.UtcNow;
|
|
result.Duration = result.CompletedAt - result.StartedAt;
|
|
result.Success = result.FailedFiles == 0;
|
|
|
|
return result;
|
|
}
|
|
|
|
private string GetFileExtension(LanguageType language)
|
|
{
|
|
return language switch
|
|
{
|
|
LanguageType.CSharp => ".cs",
|
|
LanguageType.Java => ".java",
|
|
LanguageType.CPlusPlus => ".cpp",
|
|
_ => throw new ArgumentException($"Unsupported language: {language}")
|
|
};
|
|
}
|
|
}
|
|
|
|
public class BatchConversionResult
|
|
{
|
|
public bool Success { get; set; }
|
|
public string? ErrorMessage { get; set; }
|
|
public string SourceDirectory { get; set; } = string.Empty;
|
|
public string TargetDirectory { get; set; } = string.Empty;
|
|
public LanguageType SourceLanguage { get; set; }
|
|
public LanguageType TargetLanguage { get; set; }
|
|
public int TotalFiles { get; set; }
|
|
public int SuccessfulFiles { get; set; }
|
|
public int FailedFiles { get; set; }
|
|
public DateTime StartedAt { get; set; }
|
|
public DateTime? CompletedAt { get; set; }
|
|
public DateTime? CancelledAt { get; set; }
|
|
public TimeSpan? Duration { get; set; }
|
|
public List<ConvertedFileInfo> ConvertedFiles { get; set; } = new();
|
|
public List<FailedFileInfo> FailedFileList { get; set; } = new();
|
|
}
|
|
|
|
public class ConvertedFileInfo
|
|
{
|
|
public string SourceFile { get; set; } = string.Empty;
|
|
public string TargetFile { get; set; } = string.Empty;
|
|
public int LinesConverted { get; set; }
|
|
public int ClassesConverted { get; set; }
|
|
public int MethodsConverted { get; set; }
|
|
public int Warnings { get; set; }
|
|
public int Issues { get; set; }
|
|
}
|
|
|
|
public class FailedFileInfo
|
|
{
|
|
public string SourceFile { get; set; } = string.Empty;
|
|
public string? TargetFile { get; set; }
|
|
public string ErrorMessage { get; set; } = string.Empty;
|
|
}
|