| 1 | using CascadeIDE.Contracts; |
| 2 | |
| 3 | namespace CascadeIDE.Features.Build.Application; |
| 4 | |
| 5 | /// <summary> |
| 6 | /// Сборка решения с потоковым выводом в канал и сливом в произвольный <see cref="Action{T}"/>. |
| 7 | /// </summary> |
| 8 | [ApplicationOrchestrator] |
| 9 | public static class DotnetSolutionChunkedBuildOrchestrator |
| 10 | { |
| 11 | /// <summary> |
| 12 | /// Запускает <c>dotnet build</c> для <paramref name="solutionPath"/> с записью лога по чанкам. |
| 13 | /// </summary> |
| 14 | /// <returns>При ошибке CLR — код выхода <c>null</c>, сборка считается неуспешной.</returns> |
| 15 | public static async Task<(int? ExitCode, bool? BuildSucceeded)> RunSolutionBuildStreamingAsync( |
| 16 | string solutionPath, |
| 17 | IDotnetCommandRunner runner, |
| 18 | Action<string> appendChunk, |
| 19 | CancellationToken cancellationToken) |
| 20 | { |
| 21 | var workDir = Path.GetDirectoryName(solutionPath) ?? ""; |
| 22 | int? lastExitCode = null; |
| 23 | bool? lastBuildSucceeded = null; |
| 24 | |
| 25 | try |
| 26 | { |
| 27 | var channel = BuildLogIngestion.CreateBuildLogChannel(); |
| 28 | |
| 29 | var drainTask = BuildLogIngestion.DrainToAppendAsync( |
| 30 | channel.Reader, |
| 31 | appendChunk, |
| 32 | maxBatchChars: 8192, |
| 33 | cancellationToken: cancellationToken); |
| 34 | |
| 35 | var runTask = runner.RunWithChunkWriterAsync( |
| 36 | ["build", solutionPath], |
| 37 | workDir, |
| 38 | channel.Writer, |
| 39 | cancellationToken); |
| 40 | |
| 41 | await Task.WhenAll(drainTask, runTask).ConfigureAwait(false); |
| 42 | var (success, exitCode) = await runTask.ConfigureAwait(false); |
| 43 | lastExitCode = exitCode; |
| 44 | lastBuildSucceeded = success; |
| 45 | |
| 46 | appendChunk("\r\n"); |
| 47 | if (!success && exitCode != 0) |
| 48 | appendChunk($"\r\nКод выхода: {exitCode}"); |
| 49 | } |
| 50 | catch (Exception ex) |
| 51 | { |
| 52 | appendChunk("Ошибка: " + ex.Message + "\r\n"); |
| 53 | lastBuildSucceeded = false; |
| 54 | } |
| 55 | |
| 56 | return (lastExitCode, lastBuildSucceeded); |
| 57 | } |
| 58 | } |
| 59 | |