Browse Source

Better CLI logging.

pull/860/head
Sebastian 4 years ago
parent
commit
357137d180
  1. 59
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CLILogger.cs
  2. 110
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/StringLogger.cs
  3. 43
      backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/TemplateCommandMiddleware.cs

59
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/CLILogger.cs

@ -1,59 +0,0 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.CLI.Commands.Implementation;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Entities.Apps.Templates
{
internal sealed class CLILogger : ILogger, ILogLine
{
public static readonly CLILogger Instance = new CLILogger();
private CLILogger()
{
}
public void StepFailed(string reason)
{
throw new DomainException($"Template failed with {reason}");
}
public void StepSkipped(string reason)
{
}
public void StepStart(string process)
{
}
public void StepSuccess(string? details = null)
{
}
public void WriteLine()
{
}
public void WriteLine(string message)
{
}
public void WriteLine(string message, params object?[] args)
{
}
public void Dispose()
{
}
public ILogLine WriteSameLine()
{
return this;
}
}
}

110
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/StringLogger.cs

@ -0,0 +1,110 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Globalization;
using Microsoft.Extensions.Logging;
using Squidex.CLI.Commands.Implementation;
using Squidex.Infrastructure;
using ILog = Microsoft.Extensions.Logging.ILogger;
namespace Squidex.Domain.Apps.Entities.Apps.Templates
{
public sealed class StringLogger : CLI.Commands.Implementation.ILogger, ILogLine
{
private const int MaxActionLength = 40;
private readonly ILog log;
private readonly List<string> lines = new List<string>();
private readonly List<string> errors = new List<string>();
private string startedLine = string.Empty;
public StringLogger(ILog log)
{
this.log = log;
}
public void Dispose()
{
var mesage = string.Join('\n', lines);
log.LogInformation("CLI executed with full logs {steps}.", mesage);
if (errors.Count > 0)
{
throw new DomainException($"Template failed with {errors[0]}");
}
}
public void StepStart(string message)
{
if (message.Length > MaxActionLength - 3)
{
var length = MaxActionLength - 3;
message = message[..length];
}
startedLine = $"{message.PadRight(MaxActionLength, '.')}...";
}
public void StepSuccess(string? details = null)
{
if (!string.IsNullOrWhiteSpace(details))
{
AddToLine($"succeeded ({details}).");
}
else
{
AddToLine("succeeded");
}
}
public void StepFailed(string reason)
{
AddToErrors(reason);
AddToLine($"failed: {reason.TrimEnd('.')}.");
}
public void StepSkipped(string reason)
{
AddToLine($"skipped: {reason.TrimEnd('.')}.");
}
public void WriteLine()
{
lines.Add(string.Empty);
}
public void WriteLine(string message)
{
lines.Add(message);
}
public void WriteLine(string message, params object?[] args)
{
lines.Add(string.Format(CultureInfo.InvariantCulture, message, args));
}
private void AddToErrors(string reason)
{
errors.Add(reason);
}
private void AddToLine(string message)
{
startedLine += message;
lines.Add(startedLine);
startedLine = string.Empty;
}
public ILogLine WriteSameLine()
{
return this;
}
}
}

43
backend/src/Squidex.Domain.Apps.Entities/Apps/Templates/TemplateCommandMiddleware.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Microsoft.Extensions.Logging;
using Squidex.CLI.Commands.Implementation; using Squidex.CLI.Commands.Implementation;
using Squidex.CLI.Commands.Implementation.FileSystem; using Squidex.CLI.Commands.Implementation.FileSystem;
using Squidex.CLI.Commands.Implementation.Sync; using Squidex.CLI.Commands.Implementation.Sync;
@ -27,20 +28,14 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
{ {
private readonly TemplatesClient templatesClient; private readonly TemplatesClient templatesClient;
private readonly IUrlGenerator urlGenerator; private readonly IUrlGenerator urlGenerator;
private readonly ISynchronizer[] targets = private readonly ILogger<TemplateCommandMiddleware> log;
{
new AppSynchronizer(CLILogger.Instance), public TemplateCommandMiddleware(TemplatesClient templatesClient, IUrlGenerator urlGenerator,
new AssetFoldersSynchronizer(CLILogger.Instance), ILogger<TemplateCommandMiddleware> log)
new AssetsSynchronizer(CLILogger.Instance),
new RulesSynchronizer(CLILogger.Instance),
new SchemasSynchronizer(CLILogger.Instance),
new WorkflowsSynchronizer(CLILogger.Instance),
};
public TemplateCommandMiddleware(TemplatesClient templatesClient, IUrlGenerator urlGenerator)
{ {
this.templatesClient = templatesClient; this.templatesClient = templatesClient;
this.urlGenerator = urlGenerator; this.urlGenerator = urlGenerator;
this.log = log;
} }
public async Task HandleAsync(CommandContext context, NextDelegate next) public async Task HandleAsync(CommandContext context, NextDelegate next)
@ -64,17 +59,31 @@ namespace Squidex.Domain.Apps.Entities.Apps.Templates
if (string.IsNullOrEmpty(repository)) if (string.IsNullOrEmpty(repository))
{ {
log.LogWarning("Cannot find template {template}.", template);
return; return;
} }
var session = CreateSession(app); using (var cliLog = new StringLogger(log))
{
var session = CreateSession(app);
var syncService = await CreateSyncServiceAsync(repository, session); var syncService = await CreateSyncServiceAsync(repository, session);
var syncOptions = new SyncOptions(); var syncOptions = new SyncOptions();
foreach (var target in targets.OrderBy(x => x.Name)) var targets = new ISynchronizer[]
{ {
await target.ImportAsync(syncService, syncOptions, session); new AppSynchronizer(cliLog),
new AssetFoldersSynchronizer(cliLog),
new AssetsSynchronizer(cliLog),
new RulesSynchronizer(cliLog),
new SchemasSynchronizer(cliLog),
new WorkflowsSynchronizer(cliLog),
};
foreach (var target in targets.OrderBy(x => x.Name))
{
await target.ImportAsync(syncService, syncOptions, session);
}
} }
} }

Loading…
Cancel
Save