diff --git a/Source/Bake/Cooking/Editor.cs b/Source/Bake/Cooking/Editor.cs index 7cbba7b7..8eecc459 100644 --- a/Source/Bake/Cooking/Editor.cs +++ b/Source/Bake/Cooking/Editor.cs @@ -20,17 +20,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Bake.Cooking.Ingredients.Gathers; using Bake.Core; using Bake.Extensions; using Bake.Services; using Bake.ValueObjects; -using Bake.ValueObjects.Artifacts; using Bake.ValueObjects.Recipes; using Microsoft.Extensions.Logging; @@ -68,7 +63,43 @@ public async Task ComposeAsync( context.Ingredients.WorkingDirectory, context.Ingredients.Version); - await Task.WhenAll(_gathers.Select(g => g.GatherAsync(context.Ingredients, cancellationToken))); + await ExecuteGatherersAsync(context, cancellationToken); + + var recipes = await ExecuteComposersAsync(context, cancellationToken); + + var book = new Book( + context.Ingredients, + recipes.ToArray()); + + if (_logger.IsEnabled(LogLevel.Trace)) + { + var yaml = await _yaml.SerializeAsync(book, cancellationToken); + _logger.LogTrace("Create the following YAML {Book}", yaml); + } + + return book; + } + + private async Task ExecuteGatherersAsync(Context context, CancellationToken cancellationToken) + { + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + timeout.CancelAfter(TimeSpan.FromMinutes(5)); + + try + { + await Task.WhenAll(_gathers.Select(g => g.GatherAsync(context.Ingredients, timeout.Token))); + } + catch (Exception e) when (e is TaskCanceledException or OperationCanceledException && timeout.IsCancellationRequested) + { + Console.WriteLine("Gathering repository meta data took too long! Aborting :("); + throw; + } + } + + private async Task> ExecuteComposersAsync(Context context, CancellationToken cancellationToken) + { + using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + timeout.CancelAfter(TimeSpan.FromMinutes(5)); var recipes = new List(); var composers = _composerOrdering.Order(_composers); @@ -81,31 +112,21 @@ public async Task ComposeAsync( composerTypeName); var stopWatch = Stopwatch.StartNew(); - var createdRecipes = await composer.ComposeAsync(context, cancellationToken); + var createdRecipes = await composer.ComposeAsync(context, timeout.Token); _logger.LogInformation( "Composer {ComposerType} finished after {TotalSeconds}", composerTypeName, stopWatch.Elapsed.TotalSeconds); var createdArtifacts = createdRecipes - .SelectMany(r => r.Artifacts ?? Artifact.Empty) + .SelectMany(r => r.Artifacts) .ToList(); recipes.AddRange(createdRecipes); context.AddArtifacts(createdArtifacts); } - var book = new Book( - context.Ingredients, - recipes.ToArray()); - - if (_logger.IsEnabled(LogLevel.Trace)) - { - var yaml = await _yaml.SerializeAsync(book, cancellationToken); - _logger.LogTrace("Create the following YAML {Book}", yaml); - } - - return book; + return recipes; } } }