From 164f30bf4a5a99a82791da842d17d75d3d274d6f Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 04:16:36 -0500 Subject: [PATCH 1/6] refactor: code style --- .nuke/Build.Container.cs | 4 ++++ source/Commands/NewThemeCommand.cs | 20 +++++++++----------- source/Commands/ServeCommand.cs | 21 +++++++++++++++++++-- source/Program.cs | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/.nuke/Build.Container.cs b/.nuke/Build.Container.cs index 238b341..c52ab84 100644 --- a/.nuke/Build.Container.cs +++ b/.nuke/Build.Container.cs @@ -42,9 +42,13 @@ sealed partial class Build : NukeBuild .SetProcessLogger((outputType, output) => { if (outputType == OutputType.Std) + { Log.Information(output); + } else + { Log.Debug(output); + } }) ); }); diff --git a/source/Commands/NewThemeCommand.cs b/source/Commands/NewThemeCommand.cs index c138dc1..d6b2bc6 100644 --- a/source/Commands/NewThemeCommand.cs +++ b/source/Commands/NewThemeCommand.cs @@ -34,17 +34,15 @@ public sealed partial class NewThemeCommand(NewThemeOptions options, ILogger log CreateFolders(theme.Folders); - foreach (var themeFolder in theme.Folders) - - try - { - new YAMLParser().Export(theme, themePath); - } - catch (Exception ex) - { - logger.Error("Failed to export site settings: {ex}", ex); - return 1; - } + try + { + new YAMLParser().Export(theme, themePath); + } + catch (Exception ex) + { + logger.Error("Failed to export site settings: {ex}", ex); + return 1; + } logger.Information("Done"); return 0; diff --git a/source/Commands/ServeCommand.cs b/source/Commands/ServeCommand.cs index 17fa492..984df3c 100644 --- a/source/Commands/ServeCommand.cs +++ b/source/Commands/ServeCommand.cs @@ -61,7 +61,7 @@ public sealed class ServeCommand : BaseGeneratorCommand, IDisposable /// The logger instance. Injectable for testing /// /// - public ServeCommand(ServeOptions options, ILogger logger, IFileWatcher fileWatcher, IFileSystem fs) + public ServeCommand(ServeOptions options, ILogger logger, IFileWatcher fileWatcher, IFileSystem fs) : base(options, logger, fs) { this.options = options ?? throw new ArgumentNullException(nameof(options)); @@ -73,13 +73,30 @@ public sealed class ServeCommand : BaseGeneratorCommand, IDisposable fileWatcher.Start(SourceAbsolutePath, OnSourceFileChanged); } + /// + /// Starts the server asynchronously. + /// + public void StartServer() + { + StartServer(baseURLDefault, portDefault); + } + + /// + /// Starts the server asynchronously. + /// + /// + public void StartServer(string baseURL) + { + StartServer(baseURL, portDefault); + } + /// /// Starts the server asynchronously. /// /// The base URL for the server. /// The port number for the server. /// A Task representing the asynchronous operation. - public void StartServer(string baseURL = baseURLDefault, int port = portDefault) + public void StartServer(string baseURL, int port) { logger.Information("Starting server..."); diff --git a/source/Program.cs b/source/Program.cs index b8a7da5..4a5e3b4 100644 --- a/source/Program.cs +++ b/source/Program.cs @@ -19,7 +19,7 @@ public class Program(ILogger logger) /// /// Basic logo of the program, for fun /// - public const string helloWorld = @" + private static readonly string helloWorld = @" ░█▀▀░░░░░█▀▀░░░░░█▀▀ ░▀▀█░█░█░█░░░█▀█░▀▀█ ░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀"; -- GitLab From c0cebb399a537402c98a401c7ceda29a8b25ea48 Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 04:22:26 -0500 Subject: [PATCH 2/6] perf: StringBuilder on report --- source/Helpers/StopwatchReporter.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/source/Helpers/StopwatchReporter.cs b/source/Helpers/StopwatchReporter.cs index 8ec271b..62d8941 100644 --- a/source/Helpers/StopwatchReporter.cs +++ b/source/Helpers/StopwatchReporter.cs @@ -1,6 +1,7 @@ using Serilog; using System.Diagnostics; using System.Globalization; +using System.Text; namespace SuCoS.Helpers; @@ -80,25 +81,27 @@ public class StopwatchReporter var totalDurationAllSteps = stopwatches.Values.Sum(sw => sw.ElapsedMilliseconds); - var report = $@"Site '{siteTitle}' created! -═════════════════════════════════════════════"; + var report = new StringBuilder($@"Site '{siteTitle}' created! +═════════════════════════════════════════════"); for (var i = 0; i < reportData.Count; i++) { if (i == 1 || i == reportData.Count) { - report += @" -─────────────────────────────────────────────"; + report.Append(@" +─────────────────────────────────────────────"); } - report += $"\n{reportData[i].Step,-20} {reportData[i].Status,-15} {reportData[i].DurationString,-10}"; + report.Append(CultureInfo.InvariantCulture, + $"\n{reportData[i].Step,-20} {reportData[i].Status,-15} {reportData[i].DurationString,-10}"); } - report += $@" + report.Append(CultureInfo.InvariantCulture, + $@" ───────────────────────────────────────────── Total {totalDurationAllSteps} ms -═════════════════════════════════════════════"; +═════════════════════════════════════════════"); // Log the report - logger.Information(report, siteTitle); + logger.Information(report.ToString(), siteTitle); } } -- GitLab From f383fa77f9156f0b1681e91412c5114aabccc8e5 Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 04:25:45 -0500 Subject: [PATCH 3/6] perf: returning Task on async --- .nuke/Build.GitLab.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.nuke/Build.GitLab.cs b/.nuke/Build.GitLab.cs index a2e5623..7551972 100644 --- a/.nuke/Build.GitLab.cs +++ b/.nuke/Build.GitLab.cs @@ -10,6 +10,7 @@ using System.IO; using System.IO.Compression; using System.Net.Http; using System.Net.Http.Json; +using System.Threading.Tasks; namespace SuCoS.Nuke; @@ -92,7 +93,7 @@ sealed partial class Build : NukeBuild throw; } - GitLabCreateReleaseLink(package, packageLink); + await GitLabCreateReleaseLink(package, packageLink); }); /// @@ -164,7 +165,7 @@ sealed partial class Build : NukeBuild public Target GitLabPushContainer => td => td .DependsOn(CreateContainer) .OnlyWhenStatic(() => runtimeIdentifier != "win-x64") - .Executes(() => + .Executes(async () => { var tags = ContainerTags(); @@ -184,7 +185,7 @@ sealed partial class Build : NukeBuild // Create a link to the GitLab release var tagLink = GitLabAPIUrl($"?orderBy=NAME&sort=asc&search[]={tag}"); - GitLabCreateReleaseLink($"docker-{tag}", tagLink); + await GitLabCreateReleaseLink($"docker-{tag}", tagLink); } }); /// @@ -217,7 +218,7 @@ sealed partial class Build : NukeBuild return apiUrl; } - async void GitLabCreateReleaseLink(string itemName, string itemLink) + async Task GitLabCreateReleaseLink(string itemName, string itemLink) { try { -- GitLab From 2d8f656c61505c3e7a338f6802e810561c68f535 Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 04:32:08 -0500 Subject: [PATCH 4/6] refator: minor issues --- source/Commands/ServeCommand.cs | 2 +- source/Helpers/SiteHelper.cs | 9 +-------- test/Helpers/StopwatchReporterTests.cs | 3 +-- test/ServerHandlers/StaticFileRequestHandlerTests.cs | 2 +- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/source/Commands/ServeCommand.cs b/source/Commands/ServeCommand.cs index 984df3c..7c9c0ab 100644 --- a/source/Commands/ServeCommand.cs +++ b/source/Commands/ServeCommand.cs @@ -182,7 +182,7 @@ public sealed class ServeCommand : BaseGeneratorCommand, IDisposable // Reinitialize the site site = SiteHelper.Init(configFile, options, Parser, logger, stopwatch, fs); - StartServer(baseURLDefault, portDefault); + StartServer(); }).ConfigureAwait(false); lastRestartTask = lastRestartTask.ContinueWith(t => t.Exception != null diff --git a/source/Helpers/SiteHelper.cs b/source/Helpers/SiteHelper.cs index 39e8873..6a16724 100644 --- a/source/Helpers/SiteHelper.cs +++ b/source/Helpers/SiteHelper.cs @@ -29,14 +29,7 @@ public static class SiteHelper ArgumentNullException.ThrowIfNull(fs); SiteSettings siteSettings; - try - { - siteSettings = ParseSettings(configFile, options, parser, fs); - } - catch - { - throw; - } + siteSettings = ParseSettings(configFile, options, parser, fs); var site = new Site(options, siteSettings, parser, logger, null); diff --git a/test/Helpers/StopwatchReporterTests.cs b/test/Helpers/StopwatchReporterTests.cs index fcfc0b5..86ab9e7 100644 --- a/test/Helpers/StopwatchReporterTests.cs +++ b/test/Helpers/StopwatchReporterTests.cs @@ -12,14 +12,12 @@ namespace Tests.Helpers; public class StopwatchReporterTests { private readonly ILogger logger; - private readonly StopwatchReporter stopwatchReporter; private readonly InMemorySink inMemorySink; public StopwatchReporterTests() { inMemorySink = new InMemorySink(); logger = new LoggerConfiguration().WriteTo.Sink(inMemorySink).CreateLogger(); - stopwatchReporter = new StopwatchReporter(logger); } [Fact] @@ -50,6 +48,7 @@ public class StopwatchReporterTests var siteTitle = "TestSite"; var duration = 123; + var stopwatchReporter = new StopwatchReporter(logger); stopwatchReporter.Start(stepName); Thread.Sleep(duration); // Let's wait a bit to simulate some processing. stopwatchReporter.Stop(stepName, 1); diff --git a/test/ServerHandlers/StaticFileRequestHandlerTests.cs b/test/ServerHandlers/StaticFileRequestHandlerTests.cs index c196a92..88a58a3 100644 --- a/test/ServerHandlers/StaticFileRequestHandlerTests.cs +++ b/test/ServerHandlers/StaticFileRequestHandlerTests.cs @@ -8,7 +8,7 @@ public class StaticFileRequestHandlerTests : TestSetup, IDisposable { private readonly string tempFilePath; - public StaticFileRequestHandlerTests() : base() + public StaticFileRequestHandlerTests() { // Creating a temporary file for testing purposes tempFilePath = Path.GetTempFileName(); -- GitLab From 35d94d55a16193db49400806c021b9b6449aa847 Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 04:42:40 -0500 Subject: [PATCH 5/6] refactor: minor issues --- .../CommandLineOptions/GenerateOptions.cs | 20 +++++---- .../CommandLineOptions/IGenerateOptions.cs | 10 ----- source/Models/Site.cs | 5 ++- source/Parsers/YAMLParser.cs | 43 ++----------------- test/Commands/NewSiteCommandTests.cs | 2 - .../RegisteredPageRequestHandlerTests.cs | 2 - 6 files changed, 20 insertions(+), 62 deletions(-) diff --git a/source/Models/CommandLineOptions/GenerateOptions.cs b/source/Models/CommandLineOptions/GenerateOptions.cs index d7c2263..752e946 100644 --- a/source/Models/CommandLineOptions/GenerateOptions.cs +++ b/source/Models/CommandLineOptions/GenerateOptions.cs @@ -14,14 +14,6 @@ public class GenerateOptions : IGenerateOptions /// public string Source => string.IsNullOrEmpty(SourceOption) ? SourceArgument : SourceOption; - /// - [Value(0)] - public string SourceArgument { private get; init; } = "./"; - - /// - [Option('s', "source", Required = false, HelpText = "Source directory path")] - public string SourceOption { private get; init; } = string.Empty; - /// [Option('d', "draft", Required = false, HelpText = "Include draft content")] public bool Draft { get; init; } @@ -33,4 +25,16 @@ public class GenerateOptions : IGenerateOptions /// [Option('e', "expired", Required = false, HelpText = "Include content with ExpiredDate dates from the past")] public bool Expired { get; init; } + + /// + /// The path of the source files + /// + [Value(0)] + public string SourceArgument { private get; init; } = "./"; + + /// + /// The path of the source files, as --source commandline option + /// + [Option('s', "source", Required = false, HelpText = "Source directory path")] + public string SourceOption { private get; init; } = string.Empty; } diff --git a/source/Models/CommandLineOptions/IGenerateOptions.cs b/source/Models/CommandLineOptions/IGenerateOptions.cs index ddac589..6aa93e0 100644 --- a/source/Models/CommandLineOptions/IGenerateOptions.cs +++ b/source/Models/CommandLineOptions/IGenerateOptions.cs @@ -15,16 +15,6 @@ public interface IGenerateOptions /// string Source { get; } - /// - /// The path of the source files - /// - string SourceArgument { init; } - - /// - /// The path of the source files, as --source commandline option - /// - string SourceOption { init; } - /// /// Include draft content /// diff --git a/source/Models/Site.cs b/source/Models/Site.cs index 27c3263..16338f3 100644 --- a/source/Models/Site.cs +++ b/source/Models/Site.cs @@ -295,7 +295,10 @@ public class Site : ISite : markdownFiles.Where(file => file != selectedFile).ToArray(); page = ParseSourceFile(selectedFile!, parent, bundleType); - if (page is null) return; + if (page is null) + { + return; + } if (level == 0) { diff --git a/source/Parsers/YAMLParser.cs b/source/Parsers/YAMLParser.cs index 6b186f7..f2f212c 100644 --- a/source/Parsers/YAMLParser.cs +++ b/source/Parsers/YAMLParser.cs @@ -1,7 +1,5 @@ using System.Text; using FolkerKinzel.Strings; -using SuCoS.Helpers; -using SuCoS.Models; using YamlDotNet.Serialization; namespace SuCoS.Parser; @@ -27,41 +25,6 @@ public class YAMLParser : IMetadataParser .Build(); } - // /// - // public IFrontMatter ParseFrontmatterAndMarkdown( - // in string fileFullPath, - // in string fileRelativePath, - // in string fileContent - // ) - // { - // var (yaml, rawContent) = SplitFrontMatter(fileContent); - - // // Now, you can parse the YAML front matter - // var page = ParseYAML(fileFullPath, fileRelativePath, yaml, rawContent); - - // return page; - // } - - // private FrontMatter ParseYAML( - // in string fileFullPath, - // in string fileRelativePath, - // string yaml, - // in string rawContent - // ) - // { - // var frontMatter = - // deserializer.Deserialize( - // new StringReader(yaml) - // ) ?? throw new FormatException("Error parsing front matter"); - // var section = SiteHelper.GetSection(fileRelativePath); - // frontMatter.RawContent = rawContent; - // frontMatter.Section = section; - // frontMatter.SourceRelativePath = fileRelativePath; - // frontMatter.SourceFullPath = fileFullPath; - // frontMatter.Type ??= section; - // return frontMatter; - // } - /// public T Parse(string content) { @@ -78,14 +41,14 @@ public class YAMLParser : IMetadataParser /// public void Export(T data, string path) { - var deserializer = new SerializerBuilder() + var serializer = new SerializerBuilder() .IgnoreFields() .ConfigureDefaultValuesHandling( DefaultValuesHandling.OmitEmptyCollections | DefaultValuesHandling.OmitDefaults | DefaultValuesHandling.OmitNull) .Build(); - var dataString = deserializer.Serialize(data); + var dataString = serializer.Serialize(data); File.WriteAllText(path, dataString); } @@ -96,7 +59,9 @@ public class YAMLParser : IMetadataParser var frontMatterBuilder = new StringBuilder(); string? line; + // find the start of the block while ((line = content.ReadLine()) != null && line != "---") { } + // find the end of the block while ((line = content.ReadLine()) != null && line != "---") { _ = frontMatterBuilder.AppendLine(line); diff --git a/test/Commands/NewSiteCommandTests.cs b/test/Commands/NewSiteCommandTests.cs index a14823a..cbb44dd 100644 --- a/test/Commands/NewSiteCommandTests.cs +++ b/test/Commands/NewSiteCommandTests.cs @@ -74,7 +74,6 @@ public class NewSiteCommandTests { // Arrange var options = new NewSiteOptions { Output = "test", Title = "Test", Description = "Test", BaseURL = "http://test.com", Force = false }; - var site = Substitute.For(); site.SourceFolders.Returns(["folder1", "folder2"]); fileSystem.FileExists(Arg.Any()).Returns(false); @@ -93,7 +92,6 @@ public class NewSiteCommandTests { // Arrange var options = new NewSiteOptions { Output = "test", Title = "Test", Description = "Test", BaseURL = "http://test.com", Force = false }; - var site = Substitute.For(); site.SourceFolders.Returns(["folder1", "folder2"]); fileSystem.FileExists(Arg.Any()).Returns(false); fileSystem.When(x => x.DirectoryCreateDirectory(Arg.Any())) diff --git a/test/ServerHandlers/RegisteredPageRequestHandlerTests.cs b/test/ServerHandlers/RegisteredPageRequestHandlerTests.cs index 33c7653..89925db 100644 --- a/test/ServerHandlers/RegisteredPageRequestHandlerTests.cs +++ b/test/ServerHandlers/RegisteredPageRequestHandlerTests.cs @@ -49,8 +49,6 @@ public class RegisteredPageRequestHandlerTests : TestSetup SourceArgument = siteFullPath }; var parser = new SuCoS.Parser.YAMLParser(); - // FIXME: make it an argument - var fs = new FileSystem(); var siteSettings = SiteHelper.ParseSettings("sucos.yaml", options, parser, fs); site = new Site(options, siteSettings, parser, loggerMock, null); -- GitLab From 4417a5ec0dc63098947d9c4224cd989c83f73d69 Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 25 Apr 2024 05:10:29 -0500 Subject: [PATCH 6/6] fix: missing stopwatchReporter --- test/Helpers/StopwatchReporterTests.cs | 1 + test/ProgramTest.cs | 17 +---------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/test/Helpers/StopwatchReporterTests.cs b/test/Helpers/StopwatchReporterTests.cs index 86ab9e7..b2e67db 100644 --- a/test/Helpers/StopwatchReporterTests.cs +++ b/test/Helpers/StopwatchReporterTests.cs @@ -68,6 +68,7 @@ public class StopwatchReporterTests public void Stop_ThrowsExceptionWhenStopCalledWithoutStart() { var stepName = "TestStep"; + var stopwatchReporter = new StopwatchReporter(logger); // Don't call Start for stepName diff --git a/test/ProgramTest.cs b/test/ProgramTest.cs index ae18ada..e25a052 100644 --- a/test/ProgramTest.cs +++ b/test/ProgramTest.cs @@ -1,4 +1,3 @@ -using NSubstitute; using Serilog.Events; using SuCoS; using Xunit; @@ -14,22 +13,8 @@ public class ProgramTests : TestSetup { // Act var logger = Program.CreateLogger(verbose); - - // Assert - Assert.True(logger.IsEnabled(expected)); - } - - [Fact] - public void OutputLogo_Should_LogHelloWorld() - { - // Arrange - var program = new Program(loggerMock); - - // Act - program.OutputLogo(); - program.OutputWelcome(); // Assert - loggerMock.Received(1).Information(Program.helloWorld); + Assert.True(logger.IsEnabled(expected)); } } -- GitLab