diff --git a/.build.Nuke/Build.Compile.cs b/.build.Nuke/Build.Compile.cs
index b07b145ffac266baf1465a99f7096b28f3bf439e..e784aba811db1ce7120b12cda85a8dd1d1f6bd8d 100644
--- a/.build.Nuke/Build.Compile.cs
+++ b/.build.Nuke/Build.Compile.cs
@@ -26,21 +26,21 @@ sealed partial class Build : NukeBuild
coverageDirectory.DeleteDirectory();
});
- Target Restore => _ => _
+ Target Restore => td => td
.DependsOn(Clean)
.Executes(() =>
{
- DotNetRestore(s => s
+ _ = DotNetRestore(s => s
.SetProjectFile(solution));
});
- Target Compile => _ => _
+ Target Compile => td => td
.DependsOn(Restore)
.Executes(() =>
{
Log.Debug("Configuration {Configuration}", configurationSet);
Log.Debug("configuration {configuration}", configuration);
- DotNetBuild(s => s
+ _ = DotNetBuild(s => s
.SetNoLogo(true)
.SetProjectFile(solution)
.SetConfiguration(configurationSet)
diff --git a/.build.Nuke/Build.Container.cs b/.build.Nuke/Build.Container.cs
index f80c5a517bbabceb138abb20e185451c92b1955e..888d83183148df3af2195ce8538d68046ee558f9 100644
--- a/.build.Nuke/Build.Container.cs
+++ b/.build.Nuke/Build.Container.cs
@@ -21,7 +21,7 @@ sealed partial class Build : NukeBuild
[Parameter("GitLab Project Full Address")]
readonly string containerDefaultRID = "linux-x64";
- public Target CreateContainer => _ => _
+ public Target CreateContainer => td => td
.DependsOn(Publish)
.DependsOn(CheckNewCommits)
.OnlyWhenStatic(() => runtimeIdentifier != "win-x64")
@@ -34,35 +34,35 @@ sealed partial class Build : NukeBuild
tags.AddRange(tagsOriginal);
}
- // Build the Container image
- DockerTasks.DockerBuild(_ => _
- .SetPath(PublishDirectory)
- .SetFile($"./Dockerfile")
- .SetTag(tags.Select(tag => $"{ContainerRegistryImage}:{tag}").ToArray())
- .SetBuildArg(new[] { $"BASE_IMAGE={BaseImage}", $"COPY_PATH={PublishDirectory}" })
- .SetProcessLogger((outputType, output) =>
- {
- // A bug this log type value
- if (outputType != OutputType.Std)
- Log.Information(output);
- else
- Log.Error(output);
- })
- );
+ // Build the Container image
+ _ = DockerTasks.DockerBuild(dbs => dbs
+ .SetPath(PublishDirectory)
+ .SetFile($"./Dockerfile")
+ .SetTag(tags.Select(tag => $"{ContainerRegistryImage}:{tag}").ToArray())
+ .SetBuildArg([$"BASE_IMAGE={BaseImage}", $"COPY_PATH={PublishDirectory}"])
+ .SetProcessLogger((outputType, output) =>
+ {
+ // A bug this log type value
+ if (outputType != OutputType.Std)
+ Log.Information(output);
+ else
+ Log.Error(output);
+ })
+ );
- // Log in to the Docker registry
- DockerTasks.DockerLogin(_ => _
- .SetServer("registry.gitlab.com")
- .SetUsername("gitlab-ci-token")
- .SetPassword(GitLab.JobToken)
- );
+ // Log in to the Docker registry
+ _ = DockerTasks.DockerLogin(_ => _
+ .SetServer("registry.gitlab.com")
+ .SetUsername("gitlab-ci-token")
+ .SetPassword(GitLab.JobToken)
+ );
// Push the container images
foreach (var tag in tags)
{
- DockerTasks.DockerPush(_ => _
- .SetName($"{ContainerRegistryImage}:{tag}")
- );
+ _ = DockerTasks.DockerPush(_ => _
+ .SetName($"{ContainerRegistryImage}:{tag}")
+ );
// Create a link to the GitLab release
var tagLink = GitLabAPIUrl($"?orderBy=NAME&sort=asc&search[]={tag}");
diff --git a/.build.Nuke/Build.GitLab.cs b/.build.Nuke/Build.GitLab.cs
index f9b587950ea34b661e50b9e6ea85ff22c3aa0ade..833d9e99b8b383f0a3d1fc3ee2b51021f8880537 100644
--- a/.build.Nuke/Build.GitLab.cs
+++ b/.build.Nuke/Build.GitLab.cs
@@ -42,7 +42,7 @@ sealed partial class Build : NukeBuild
/// One for each runtime identifier.
///
///
- public Target CreatePackage => _ => _
+ public Target CreatePackage => td => td
.DependsOn(Publish)
.DependsOn(CheckNewCommits)
.Requires(() => gitlabPrivateToken)
@@ -80,9 +80,9 @@ sealed partial class Build : NukeBuild
using var httpClient = HttpClientGitLabToken();
var response = await httpClient.PutAsync(
packageLink,
- new StreamContent(fileStream));
+ new StreamContent(fileStream)).ConfigureAwait(false);
- response.EnsureSuccessStatusCode();
+ _ = response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
@@ -97,7 +97,7 @@ sealed partial class Build : NukeBuild
/// Creates a release in the GitLab repository.
///
///
- public Target GitLabCreateRelease => _ => _
+ public Target GitLabCreateRelease => td => td
.DependsOn(GitLabCreateTag)
.OnlyWhenStatic(() => HasNewCommits)
.Requires(() => gitlabPrivateToken)
@@ -113,9 +113,9 @@ sealed partial class Build : NukeBuild
tag_name = TagName,
name = $"{TagName} {Date}",
description = $"Created {Date}"
- });
+ }).ConfigureAwait(false);
- response.EnsureSuccessStatusCode();
+ _ = response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
@@ -128,7 +128,7 @@ sealed partial class Build : NukeBuild
/// Creates a tag in the GitLab repository.
///
///
- Target GitLabCreateTag => _ => _
+ Target GitLabCreateTag => td => td
.DependsOn(CheckNewCommits)
.After(Compile)
.OnlyWhenStatic(() => HasNewCommits)
@@ -145,9 +145,9 @@ sealed partial class Build : NukeBuild
tag_name = TagName,
@ref = GitLab?.CommitRefName ?? GitTasks.GitCurrentCommit(),
message = $"Automatic tag creation: {isScheduled} at {Date}"
- });
+ }).ConfigureAwait(false);
- response.EnsureSuccessStatusCode();
+ _ = response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
@@ -197,9 +197,9 @@ sealed partial class Build : NukeBuild
{
name = itemName,
url = itemLink
- });
+ }).ConfigureAwait(false);
- response.EnsureSuccessStatusCode();
+ _ = response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
diff --git a/.build.Nuke/Build.Publish.cs b/.build.Nuke/Build.Publish.cs
index fa2684dd008ad53d08d9f257463bb6e5fd290990..042775ff8d15c98248a0c187e180a2d684cd72df 100644
--- a/.build.Nuke/Build.Publish.cs
+++ b/.build.Nuke/Build.Publish.cs
@@ -11,39 +11,39 @@ namespace SuCoS;
///
sealed partial class Build : NukeBuild
{
- [Parameter("Runtime identifier for the build (e.g., win-x64, linux-x64, osx-x64) (default: linux-x64)")]
- readonly string runtimeIdentifier = "linux-x64";
+ [Parameter("Runtime identifier for the build (e.g., win-x64, linux-x64, osx-x64) (default: linux-x64)")]
+ readonly string runtimeIdentifier = "linux-x64";
- [Parameter("publish-directory (default: ./publish/{runtimeIdentifier})")]
- readonly AbsolutePath publishDirectory;
- AbsolutePath PublishDirectory => publishDirectory ?? RootDirectory / "publish" / runtimeIdentifier;
+ [Parameter("publish-directory (default: ./publish/{runtimeIdentifier})")]
+ readonly AbsolutePath publishDirectory;
+ AbsolutePath PublishDirectory => publishDirectory ?? RootDirectory / "publish" / runtimeIdentifier;
- [Parameter("publish-self-contained (default: true)")]
- readonly bool publishSelfContained = true;
+ [Parameter("publish-self-contained (default: true)")]
+ readonly bool publishSelfContained = true;
- [Parameter("publish-single-file (default: true)")]
- readonly bool publishSingleFile = true;
+ [Parameter("publish-single-file (default: true)")]
+ readonly bool publishSingleFile = true;
- [Parameter("publish-trimmed (default: false)")]
- readonly bool publishTrimmed = false;
+ [Parameter("publish-trimmed (default: false)")]
+ readonly bool publishTrimmed = false;
- Target Publish => _ => _
- .DependsOn(Restore)
- .Executes(() =>
- {
- DotNetPublish(s => s
- .SetNoLogo(true)
- .SetProject("source/SuCoS.csproj")
- .SetConfiguration(configurationSet)
- .SetOutput(PublishDirectory)
- .SetRuntime(runtimeIdentifier)
- .SetSelfContained(publishSelfContained)
- .SetPublishSingleFile(publishSingleFile)
- .SetPublishTrimmed(publishTrimmed)
- .SetAuthors("Bruno Massa")
- .SetVersion(CurrentVersion)
- .SetAssemblyVersion(CurrentVersion)
- .SetInformationalVersion(CurrentVersion)
- );
- });
+ Target Publish => td => td
+ .DependsOn(Restore)
+ .Executes(() =>
+ {
+ _ = DotNetPublish(s => s
+ .SetNoLogo(true)
+ .SetProject("source/SuCoS.csproj")
+ .SetConfiguration(configurationSet)
+ .SetOutput(PublishDirectory)
+ .SetRuntime(runtimeIdentifier)
+ .SetSelfContained(publishSelfContained)
+ .SetPublishSingleFile(publishSingleFile)
+ .SetPublishTrimmed(publishTrimmed)
+ .SetAuthors("Bruno Massa")
+ .SetVersion(CurrentVersion)
+ .SetAssemblyVersion(CurrentVersion)
+ .SetInformationalVersion(CurrentVersion)
+ );
+ });
}
diff --git a/.build.Nuke/Build.Test.cs b/.build.Nuke/Build.Test.cs
index 54f1d524fc5b289a850ca97a7d86d6bd46145cff..76ec9e937a11896cc5d0fd669c84a637cf718a69 100644
--- a/.build.Nuke/Build.Test.cs
+++ b/.build.Nuke/Build.Test.cs
@@ -26,30 +26,30 @@ sealed partial class Build : NukeBuild
static AbsolutePath coverageReportDirectory => coverageDirectory / "report";
static AbsolutePath coverageReportSummaryDirectory => coverageReportDirectory / "Summary.txt";
- Target Test => _ => _
+ Target Test => td => td
.DependsOn(Compile)
.Executes(() =>
{
- coverageResultDirectory.CreateDirectory();
- Coverlet(s => s
- .SetTarget("dotnet")
- .SetTargetArgs("test --no-build --no-restore")
- .SetAssembly(testAssembly)
- // .SetThreshold(75)
- .SetOutput(coverageResultFile)
- .SetFormat(CoverletOutputFormat.cobertura));
+ _ = coverageResultDirectory.CreateDirectory();
+ _ = Coverlet(s => s
+ .SetTarget("dotnet")
+ .SetTargetArgs("test --no-build --no-restore")
+ .SetAssembly(testAssembly)
+ // .SetThreshold(75)
+ .SetOutput(coverageResultFile)
+ .SetFormat(CoverletOutputFormat.cobertura));
});
- public Target TestReport => _ => _
+ public Target TestReport => td => td
.DependsOn(Test)
.Executes(() =>
{
- coverageReportDirectory.CreateDirectory();
- ReportGenerator(s => s
- .SetTargetDirectory(coverageReportDirectory)
- .SetReportTypes(new ReportTypes[] { ReportTypes.Html, ReportTypes.TextSummary })
- .SetReports(coverageResultFile)
- );
+ _ = coverageReportDirectory.CreateDirectory();
+ _ = ReportGenerator(s => s
+ .SetTargetDirectory(coverageReportDirectory)
+ .SetReportTypes([ReportTypes.Html, ReportTypes.TextSummary])
+ .SetReports(coverageResultFile)
+ );
var summaryText = coverageReportSummaryDirectory.ReadAllLines();
Log.Information(string.Join(Environment.NewLine, summaryText));
});
diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json
index 7def812ce0dc0a3e51e5560b0cd87f877e9eaf09..87122c0e5548fbdef89e2da79b123f09c2bfa9a5 100644
--- a/.nuke/build.schema.json
+++ b/.nuke/build.schema.json
@@ -1,164 +1,164 @@
-{
- "$schema": "http://json-schema.org/draft-04/schema#",
- "$ref": "#/definitions/build",
- "title": "Build Schema",
- "definitions": {
- "build": {
- "type": "object",
- "properties": {
- "configuration": {
- "type": "string",
- "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)"
- },
- "containerDefaultRID": {
- "type": "string",
- "description": "GitLab Project Full Address"
- },
- "containerRegistryImage": {
- "type": "string",
- "description": "GitLab Project CI_REGISTRY_IMAGE"
- },
- "Continue": {
- "type": "boolean",
- "description": "Indicates to continue a previously failed build attempt"
- },
- "gitlabPrivateToken": {
- "type": "string",
- "description": "GitLab private token"
- },
- "Help": {
- "type": "boolean",
- "description": "Shows the help text for this build assembly"
- },
- "Host": {
- "type": "string",
- "description": "Host for execution. Default is 'automatic'",
- "enum": [
- "AppVeyor",
- "AzurePipelines",
- "Bamboo",
- "Bitbucket",
- "Bitrise",
- "GitHubActions",
- "GitLab",
- "Jenkins",
- "Rider",
- "SpaceAutomation",
- "TeamCity",
- "Terminal",
- "TravisCI",
- "VisualStudio",
- "VSCode"
- ]
- },
- "isScheduled": {
- "type": "boolean",
- "description": "If the pipeline was triggered by a schedule (or manually)"
- },
- "NoLogo": {
- "type": "boolean",
- "description": "Disables displaying the NUKE logo"
- },
- "packageName": {
- "type": "string",
- "description": "package-name (default: SuCoS)"
- },
- "Partition": {
- "type": "string",
- "description": "Partition to use on CI"
- },
- "Plan": {
- "type": "boolean",
- "description": "Shows the execution plan (HTML)"
- },
- "Profile": {
- "type": "array",
- "description": "Defines the profiles to load",
- "items": {
- "type": "string"
- }
- },
- "publishDirectory": {
- "type": "string",
- "description": "publish-directory (default: ./publish/{runtimeIdentifier})"
- },
- "publishSelfContained": {
- "type": "boolean",
- "description": "publish-self-contained (default: true)"
- },
- "publishSingleFile": {
- "type": "boolean",
- "description": "publish-single-file (default: true)"
- },
- "publishTrimmed": {
- "type": "boolean",
- "description": "publish-trimmed (default: false)"
- },
- "Root": {
- "type": "string",
- "description": "Root directory during build execution"
- },
- "runtimeIdentifier": {
- "type": "string",
- "description": "Runtime identifier for the build (e.g., win-x64, linux-x64, osx-x64) (default: linux-x64)"
- },
- "Skip": {
- "type": "array",
- "description": "List of targets to be skipped. Empty list skips all dependencies",
- "items": {
- "type": "string",
- "enum": [
- "CheckNewCommits",
- "Clean",
- "Compile",
- "CreateContainer",
- "CreatePackage",
- "GitLabCreateRelease",
- "GitLabCreateTag",
- "Publish",
- "Restore",
- "ShowCurrentVersion",
- "Test",
- "TestReport"
- ]
- }
- },
- "solution": {
- "type": "string",
- "description": "Path to a solution file that is automatically loaded"
- },
- "Target": {
- "type": "array",
- "description": "List of targets to be invoked. Default is '{default_target}'",
- "items": {
- "type": "string",
- "enum": [
- "CheckNewCommits",
- "Clean",
- "Compile",
- "CreateContainer",
- "CreatePackage",
- "GitLabCreateRelease",
- "GitLabCreateTag",
- "Publish",
- "Restore",
- "ShowCurrentVersion",
- "Test",
- "TestReport"
- ]
- }
- },
- "Verbosity": {
- "type": "string",
- "description": "Logging verbosity during build execution. Default is 'Normal'",
- "enum": [
- "Minimal",
- "Normal",
- "Quiet",
- "Verbose"
- ]
- }
- }
- }
- }
-}
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "$ref": "#/definitions/build",
+ "title": "Build Schema",
+ "definitions": {
+ "build": {
+ "type": "object",
+ "properties": {
+ "configuration": {
+ "type": "string",
+ "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)"
+ },
+ "containerDefaultRID": {
+ "type": "string",
+ "description": "GitLab Project Full Address"
+ },
+ "containerRegistryImage": {
+ "type": "string",
+ "description": "GitLab Project CI_REGISTRY_IMAGE"
+ },
+ "Continue": {
+ "type": "boolean",
+ "description": "Indicates to continue a previously failed build attempt"
+ },
+ "gitlabPrivateToken": {
+ "type": "string",
+ "description": "GitLab private token"
+ },
+ "Help": {
+ "type": "boolean",
+ "description": "Shows the help text for this build assembly"
+ },
+ "Host": {
+ "type": "string",
+ "description": "Host for execution. Default is 'automatic'",
+ "enum": [
+ "AppVeyor",
+ "AzurePipelines",
+ "Bamboo",
+ "Bitbucket",
+ "Bitrise",
+ "GitHubActions",
+ "GitLab",
+ "Jenkins",
+ "Rider",
+ "SpaceAutomation",
+ "TeamCity",
+ "Terminal",
+ "TravisCI",
+ "VisualStudio",
+ "VSCode"
+ ]
+ },
+ "isScheduled": {
+ "type": "boolean",
+ "description": "If the pipeline was triggered by a schedule (or manually)"
+ },
+ "NoLogo": {
+ "type": "boolean",
+ "description": "Disables displaying the NUKE logo"
+ },
+ "packageName": {
+ "type": "string",
+ "description": "package-name (default: SuCoS)"
+ },
+ "Partition": {
+ "type": "string",
+ "description": "Partition to use on CI"
+ },
+ "Plan": {
+ "type": "boolean",
+ "description": "Shows the execution plan (HTML)"
+ },
+ "Profile": {
+ "type": "array",
+ "description": "Defines the profiles to load",
+ "items": {
+ "type": "string"
+ }
+ },
+ "publishDirectory": {
+ "type": "string",
+ "description": "publish-directory (default: ./publish/{runtimeIdentifier})"
+ },
+ "publishSelfContained": {
+ "type": "boolean",
+ "description": "publish-self-contained (default: true)"
+ },
+ "publishSingleFile": {
+ "type": "boolean",
+ "description": "publish-single-file (default: true)"
+ },
+ "publishTrimmed": {
+ "type": "boolean",
+ "description": "publish-trimmed (default: false)"
+ },
+ "Root": {
+ "type": "string",
+ "description": "Root directory during build execution"
+ },
+ "runtimeIdentifier": {
+ "type": "string",
+ "description": "Runtime identifier for the build (e.g., win-x64, linux-x64, osx-x64) (default: linux-x64)"
+ },
+ "Skip": {
+ "type": "array",
+ "description": "List of targets to be skipped. Empty list skips all dependencies",
+ "items": {
+ "type": "string",
+ "enum": [
+ "CheckNewCommits",
+ "Clean",
+ "Compile",
+ "CreateContainer",
+ "CreatePackage",
+ "GitLabCreateRelease",
+ "GitLabCreateTag",
+ "Publish",
+ "Restore",
+ "ShowCurrentVersion",
+ "Test",
+ "TestReport"
+ ]
+ }
+ },
+ "solution": {
+ "type": "string",
+ "description": "Path to a solution file that is automatically loaded"
+ },
+ "Target": {
+ "type": "array",
+ "description": "List of targets to be invoked. Default is '{default_target}'",
+ "items": {
+ "type": "string",
+ "enum": [
+ "CheckNewCommits",
+ "Clean",
+ "Compile",
+ "CreateContainer",
+ "CreatePackage",
+ "GitLabCreateRelease",
+ "GitLabCreateTag",
+ "Publish",
+ "Restore",
+ "ShowCurrentVersion",
+ "Test",
+ "TestReport"
+ ]
+ }
+ },
+ "Verbosity": {
+ "type": "string",
+ "description": "Logging verbosity during build execution. Default is 'Normal'",
+ "enum": [
+ "Minimal",
+ "Normal",
+ "Quiet",
+ "Verbose"
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/source/BaseGeneratorCommand.cs b/source/BaseGeneratorCommand.cs
index 3b216ca6114fc75140b1957e26057cf3db345bec..20579c798f613ba86af0e68a0b081f69cd46e9cb 100644
--- a/source/BaseGeneratorCommand.cs
+++ b/source/BaseGeneratorCommand.cs
@@ -21,22 +21,22 @@ public abstract class BaseGeneratorCommand
///
/// The site configuration.
///
- protected Site site;
+ protected Site site { get; set; }
///
/// The front matter parser instance. The default is YAML.
///
- protected readonly IFrontMatterParser frontMatterParser = new YAMLParser();
+ protected IFrontMatterParser frontMatterParser { get; } = new YAMLParser();
///
/// The stopwatch reporter.
///
- protected readonly StopwatchReporter stopwatch;
+ protected StopwatchReporter stopwatch { get; }
///
/// The logger (Serilog).
///
- protected readonly ILogger logger;
+ protected ILogger logger { get; }
///
/// Initializes a new instance of the class.
@@ -45,10 +45,7 @@ public abstract class BaseGeneratorCommand
/// The logger instance. Injectable for testing
protected BaseGeneratorCommand(IGenerateOptions options, ILogger logger)
{
- if (options is null)
- {
- throw new ArgumentNullException(nameof(options));
- }
+ ArgumentNullException.ThrowIfNull(options);
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
stopwatch = new(logger);
@@ -68,14 +65,8 @@ public abstract class BaseGeneratorCommand
///
protected static ValueTask WhereParamsFilter(FluidValue input, FilterArguments arguments, TemplateContext context)
{
- if (input is null)
- {
- throw new ArgumentNullException(nameof(input));
- }
- if (arguments is null)
- {
- throw new ArgumentNullException(nameof(arguments));
- }
+ ArgumentNullException.ThrowIfNull(input);
+ ArgumentNullException.ThrowIfNull(arguments);
List result = new();
var list = (input as ArrayValue)!.Values;
diff --git a/source/BuildCommand.cs b/source/BuildCommand.cs
index 46f9bdcea84de99d57e5cd5af541b43ded7686ad..c4bda47b22eb8f4aa8a9f76a3e97a1283954619e 100644
--- a/source/BuildCommand.cs
+++ b/source/BuildCommand.cs
@@ -54,10 +54,7 @@ public class BuildCommand : BaseGeneratorCommand
var outputAbsolutePath = Path.Combine(options.Output, path);
var outputDirectory = Path.GetDirectoryName(outputAbsolutePath);
- if (!Directory.Exists(outputDirectory))
- {
- _ = Directory.CreateDirectory(outputDirectory!);
- }
+ _ = Directory.CreateDirectory(outputDirectory!);
// Save the processed output to the final file
var result = page.CompleteContent;
@@ -73,6 +70,9 @@ public class BuildCommand : BaseGeneratorCommand
{
var outputAbsolutePath = Path.Combine(options.Output, resource.Permalink!.TrimStart('/'));
+ var outputDirectory = Path.GetDirectoryName(outputAbsolutePath);
+ _ = Directory.CreateDirectory(outputDirectory!);
+
// Copy the file to the output folder
File.Copy(resource.SourceFullPath, outputAbsolutePath, overwrite: true);
}
diff --git a/source/Helpers/FileUtils.cs b/source/Helpers/FileUtils.cs
index 5125bb8e8cd36883ab8b9d8d876fb2ddac668245..0afcb810407ef154fdbd3545804d7aa8ab9888fa 100644
--- a/source/Helpers/FileUtils.cs
+++ b/source/Helpers/FileUtils.cs
@@ -17,14 +17,8 @@ public static class FileUtils
/// The content of the template file.
public static string GetTemplate(string themePath, Page page, SiteCacheManager cacheManager, bool isBaseTemplate = false)
{
- if (page is null)
- {
- throw new ArgumentNullException(nameof(page));
- }
- if (cacheManager is null)
- {
- throw new ArgumentNullException(nameof(cacheManager));
- }
+ ArgumentNullException.ThrowIfNull(page);
+ ArgumentNullException.ThrowIfNull(cacheManager);
var index = (page.Section, page.Kind, page.Type);
@@ -53,10 +47,7 @@ public static class FileUtils
/// The content of the template file, or an empty string if not found.
private static string GetTemplate(List templatePaths)
{
- if (templatePaths is null)
- {
- throw new ArgumentNullException(nameof(templatePaths));
- }
+ ArgumentNullException.ThrowIfNull(templatePaths);
// Iterate through the template paths and return the content of the first existing file
foreach (var templatePath in templatePaths.Where(File.Exists))
@@ -76,10 +67,7 @@ public static class FileUtils
/// The list of template paths in the lookup order.
private static List GetTemplateLookupOrder(string themePath, Page page, bool isBaseTemplate)
{
- if (page is null)
- {
- throw new ArgumentNullException(nameof(page));
- }
+ ArgumentNullException.ThrowIfNull(page);
// Generate the lookup order for template files based on the theme path, page section, type, and kind
var sections = page.Section is not null ? new[] { page.Section, string.Empty } : new[] { string.Empty };
diff --git a/source/Helpers/SiteCacheManager.cs b/source/Helpers/SiteCacheManager.cs
index 5391bbffe712f3994682cf2a9ea7a19bda74f421..7365db8d0b1bceea36a125a2d65a6173129d8163 100644
--- a/source/Helpers/SiteCacheManager.cs
+++ b/source/Helpers/SiteCacheManager.cs
@@ -11,17 +11,17 @@ public class SiteCacheManager
///
/// Cache for content templates.
///
- public readonly Dictionary<(string?, Kind?, string?), string> contentTemplateCache = new();
+ public Dictionary<(string?, Kind?, string?), string> contentTemplateCache { get; } = new();
///
/// Cache for base templates.
///
- public readonly Dictionary<(string?, Kind?, string?), string> baseTemplateCache = new();
+ public Dictionary<(string?, Kind?, string?), string> baseTemplateCache { get; } = new();
///
/// Cache for tag page.
///
- public readonly ConcurrentDictionary> automaticContentCache = new();
+ public ConcurrentDictionary> automaticContentCache { get; } = new();
///
/// Resets the template cache to force a reload of all templates.
diff --git a/source/Helpers/SiteHelper.cs b/source/Helpers/SiteHelper.cs
index ebc73468a37290c1071b02f190d1de74e09a98e8..64d2d104b50c76f94005d9cd8d230b54900ddfa8 100644
--- a/source/Helpers/SiteHelper.cs
+++ b/source/Helpers/SiteHelper.cs
@@ -27,10 +27,7 @@ public static class SiteHelper
///
public static Site Init(string configFile, IGenerateOptions options, IFrontMatterParser frontMatterParser, FilterDelegate whereParamsFilter, ILogger logger, StopwatchReporter stopwatch)
{
- if (stopwatch is null)
- {
- throw new ArgumentNullException(nameof(stopwatch));
- }
+ ArgumentNullException.ThrowIfNull(stopwatch);
SiteSettings siteSettings;
try
@@ -54,7 +51,7 @@ public static class SiteHelper
site.ParseAndScanSourceFiles(site.SourceContentPath);
- stopwatch.Stop("Parse", site.filesParsedToReport);
+ stopwatch.Stop("Parse", site.FilesParsedToReport);
site.TemplateOptions.FileProvider = new PhysicalFileProvider(Path.GetFullPath(site.SourceThemePath));
@@ -97,14 +94,8 @@ public static class SiteHelper
/// The site settings.
private static SiteSettings ParseSettings(string configFile, IGenerateOptions options, IFrontMatterParser frontMatterParser)
{
- if (options is null)
- {
- throw new ArgumentNullException(nameof(options));
- }
- if (frontMatterParser is null)
- {
- throw new ArgumentNullException(nameof(frontMatterParser));
- }
+ ArgumentNullException.ThrowIfNull(options);
+ ArgumentNullException.ThrowIfNull(frontMatterParser);
try
{
diff --git a/source/Helpers/SourceFileWatcher.cs b/source/Helpers/SourceFileWatcher.cs
index b857e4c5fee05e65994fe1344c51d6ff43b1f8dc..4da2e2da1ffe347746264be2243b1e2668e40344 100644
--- a/source/Helpers/SourceFileWatcher.cs
+++ b/source/Helpers/SourceFileWatcher.cs
@@ -3,7 +3,7 @@ namespace SuCoS.Helpers;
///
/// The FileSystemWatcher object that monitors the source directory for file changes.
///
-public class SourceFileWatcher : IFileWatcher
+public sealed class SourceFileWatcher : IFileWatcher, IDisposable
{
///
/// The FileSystemWatcher object that monitors the source directory for file changes.
@@ -16,10 +16,7 @@ public class SourceFileWatcher : IFileWatcher
///
public void Start(string SourceAbsolutePath, Action
///
- List? Aliases { get; }
+ Collection? Aliases { get; }
///
/// Page weight. Used for sorting by default.
@@ -92,12 +93,12 @@ public interface IFrontMatter : IParams, IFile
///
/// A list of tags, if any.
///
- List? Tags { get; }
+ Collection? Tags { get; }
///
/// List of resource definitions.
///
- List? ResourceDefinitions { get; }
+ Collection? ResourceDefinitions { get; }
///
/// Raw content from the Markdown file, bellow the front matter.
diff --git a/source/Models/IPage.cs b/source/Models/IPage.cs
index d979b7f5b581ca601908279ac7cfb76558bcd61f..83b7e0e22d3db379be2a5d930c06bcf1ec73e45f 100644
--- a/source/Models/IPage.cs
+++ b/source/Models/IPage.cs
@@ -1,6 +1,7 @@
using Markdig;
using SuCoS.Helpers;
using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
namespace SuCoS.Models;
@@ -27,7 +28,7 @@ public interface IPage : IFrontMatter, IOutput
///
/// Secondary URL patterns to be used to create the url.
///
- public List? AliasesProcessed { get; set; }
+ public Collection? AliasesProcessed { get; }
///
/// Other content that mention this content.
@@ -49,7 +50,7 @@ public interface IPage : IFrontMatter, IOutput
///
/// Page resources. All files that accompany a page.
///
- public List? Resources { get; set; }
+ public Collection? Resources { get; }
///
/// Plain markdown content, without HTML.
@@ -81,7 +82,7 @@ public interface IPage : IFrontMatter, IOutput
///
public int WordCount => Plain.Split(nonWords, StringSplitOptions.RemoveEmptyEntries).Length;
- private static readonly char[] nonWords = { ' ', ',', ';', '.', '!', '"', '(', ')', '?', '\n', '\r' };
+ private static readonly char[] nonWords = [' ', ',', ';', '.', '!', '"', '(', ')', '?', '\n', '\r'];
///
/// The markdown content converted to HTML
diff --git a/source/Models/Page.cs b/source/Models/Page.cs
index 5f88cb54a162b42e87e4e027ef60c92b82a43714..d64dd5c3bc6c12a89120f79cbef2c5b993a0fe23 100644
--- a/source/Models/Page.cs
+++ b/source/Models/Page.cs
@@ -3,6 +3,7 @@ using Markdig;
using Microsoft.Extensions.FileSystemGlobbing;
using SuCoS.Helpers;
using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
namespace SuCoS.Models;
@@ -28,7 +29,7 @@ public class Page : IPage
public bool? Draft => frontMatter.Draft;
///
- public List? Aliases => frontMatter.Aliases;
+ public Collection? Aliases => frontMatter.Aliases;
///
public string? Section => frontMatter.Section;
@@ -49,10 +50,10 @@ public class Page : IPage
public int Weight => frontMatter.Weight;
///
- public List? Tags => frontMatter.Tags;
+ public Collection? Tags => frontMatter.Tags;
///
- public List? ResourceDefinitions => frontMatter.ResourceDefinitions;
+ public Collection? ResourceDefinitions => frontMatter.ResourceDefinitions;
///
public string RawContent => frontMatter.RawContent;
@@ -103,7 +104,7 @@ public class Page : IPage
///
/// Secondary URL patterns to be used to create the url.
///
- public List? AliasesProcessed { get; set; }
+ public Collection? AliasesProcessed { get; set; }
///
public string? Permalink { get; set; }
@@ -121,7 +122,7 @@ public class Page : IPage
public BundleType BundleType { get; set; } = BundleType.none;
///
- public List? Resources { get; set; }
+ public Collection? Resources { get; set; }
///
/// Plain markdown content, without HTML.
@@ -153,7 +154,7 @@ public class Page : IPage
///
public int WordCount => Plain.Split(nonWords, StringSplitOptions.RemoveEmptyEntries).Length;
- private static readonly char[] nonWords = { ' ', ',', ';', '.', '!', '"', '(', ')', '?', '\n', '\r' };
+ private static readonly char[] nonWords = [' ', ',', ';', '.', '!', '"', '(', ')', '?', '\n', '\r'];
///
/// The markdown content converted to HTML
@@ -191,7 +192,7 @@ public class Page : IPage
return pagesCached;
}
- pagesCached ??= new();
+ pagesCached = new();
foreach (var permalink in PagesReferences)
{
var page = Site.OutputReferences[permalink] as IPage;
@@ -365,14 +366,14 @@ endif
{
foreach (var tagName in Tags)
{
- Site.CreateSystemPage(Path.Combine("tags", tagName), tagName, "tags", this);
+ _ = Site.CreateSystemPage(Path.Combine("tags", tagName), tagName, "tags", this);
}
}
ScanForResources();
}
- private int counterInternal = 0;
+ private int counterInternal;
private bool counterInternalLock;
private int counter
{
@@ -418,7 +419,7 @@ endif
foreach (var resourceDefinition in ResourceDefinitions)
{
resourceDefinition.GlobMatcher ??= new();
- resourceDefinition.GlobMatcher.AddInclude(resourceDefinition.Src);
+ _ = resourceDefinition.GlobMatcher.AddInclude(resourceDefinition.Src);
var file = new InMemoryDirectoryInfo("./", new[] { filenameOriginal });
if (resourceDefinition.GlobMatcher.Execute(file).HasMatches)
{
diff --git a/source/Models/Site.cs b/source/Models/Site.cs
index 3df334f2f735fed258eab2fec8a40bfc5b5b2f8f..4b56ce34943440194a34f0a4431d05289e72e550 100644
--- a/source/Models/Site.cs
+++ b/source/Models/Site.cs
@@ -141,7 +141,9 @@ public class Site : ISite
///
/// Number of files parsed, used in the report.
///
- public int filesParsedToReport;
+ public int FilesParsedToReport => filesParsedToReport;
+
+ private int filesParsedToReport;
private const string indexLeafFileConst = "index.md";
@@ -218,7 +220,7 @@ public class Site : ISite
_ = Parallel.ForEach(markdownFiles, filePath =>
{
- ParseSourceFile(filePath, parent);
+ _ = ParseSourceFile(filePath, parent);
});
var subdirectories = Directory.GetDirectories(directory);
@@ -310,7 +312,7 @@ public class Site : ISite
// Remove the selected file from markdownFiles
markdownFiles = bundleType == BundleType.leaf
- ? new string[] { }
+ ? Array.Empty()
: markdownFiles.Where(file => file != selectedFile).ToArray();
page = ParseSourceFile(selectedFile!, parent, bundleType);
@@ -318,11 +320,11 @@ public class Site : ISite
if (level == 0)
{
- OutputReferences.TryRemove(page!.Permalink!, out _);
+ _ = OutputReferences.TryRemove(page!.Permalink!, out _);
page.Permalink = "/";
page.Kind = Kind.index;
- OutputReferences.GetOrAdd(page.Permalink, page);
+ _ = OutputReferences.GetOrAdd(page.Permalink, page);
Home = page;
}
else
@@ -341,7 +343,7 @@ public class Site : ISite
}
}
- private IPage? ParseSourceFile(in string filePath, in IPage? parent, BundleType bundleType = BundleType.none)
+ private Page? ParseSourceFile(in string filePath, in IPage? parent, BundleType bundleType = BundleType.none)
{
Page? page = null;
try
@@ -377,10 +379,7 @@ public class Site : ISite
///
public void PostProcessPage(in IPage page, IPage? parent = null, bool overwrite = false)
{
- if (page is null)
- {
- throw new ArgumentNullException(nameof(page));
- }
+ ArgumentNullException.ThrowIfNull(page);
page.Parent = parent;
page.Permalink = page.CreatePermalink();
@@ -391,7 +390,7 @@ public class Site : ISite
page.PostProcess();
// Replace the old page with the newly created one
- if (oldOutput is IPage oldpage && oldpage?.PagesReferences is not null)
+ if (oldOutput is IPage oldpage && oldpage.PagesReferences is not null)
{
foreach (var pageOld in oldpage.PagesReferences)
{
@@ -402,7 +401,7 @@ public class Site : ISite
// Register the page for all urls
foreach (var pageOutput in page.AllOutputURLs)
{
- OutputReferences.TryAdd(pageOutput.Key, pageOutput.Value);
+ _ = OutputReferences.TryAdd(pageOutput.Key, pageOutput.Value);
}
}
}
@@ -420,10 +419,8 @@ public class Site : ISite
///
public bool IsValidPage(in IFrontMatter frontMatter, IGenerateOptions? options)
{
- if (frontMatter is null)
- {
- throw new ArgumentNullException(nameof(frontMatter));
- }
+ ArgumentNullException.ThrowIfNull(frontMatter);
+
return IsValidDate(frontMatter, options)
&& (frontMatter.Draft is null || frontMatter.Draft == false || (options?.Draft ?? false));
}
@@ -431,10 +428,8 @@ public class Site : ISite
///
public bool IsValidDate(in IFrontMatter frontMatter, IGenerateOptions? options)
{
- if (frontMatter is null)
- {
- throw new ArgumentNullException(nameof(frontMatter));
- }
+ ArgumentNullException.ThrowIfNull(frontMatter);
+
return (!IsDateExpired(frontMatter) || (options?.Expired ?? false))
&& (IsDatePublishable(frontMatter) || (options?.Future ?? false));
}
@@ -444,10 +439,8 @@ public class Site : ISite
///
public bool IsDateExpired(in IFrontMatter frontMatter)
{
- if (frontMatter is null)
- {
- throw new ArgumentNullException(nameof(frontMatter));
- }
+ ArgumentNullException.ThrowIfNull(frontMatter);
+
return frontMatter.ExpiryDate is not null && frontMatter.ExpiryDate <= clock.Now;
}
@@ -456,10 +449,8 @@ public class Site : ISite
///
public bool IsDatePublishable(in IFrontMatter frontMatter)
{
- if (frontMatter is null)
- {
- throw new ArgumentNullException(nameof(frontMatter));
- }
+ ArgumentNullException.ThrowIfNull(frontMatter);
+
return frontMatter.GetPublishDate is null || frontMatter.GetPublishDate <= clock.Now;
}
}
\ No newline at end of file
diff --git a/source/Parser/YAMLParser.cs b/source/Parser/YAMLParser.cs
index 36ca94dd8024cb0f0f5af565cc10a8dfdfc3dcaa..f9b85d2f5930dfcd428a7359cd2245e6c71e2457 100644
--- a/source/Parser/YAMLParser.cs
+++ b/source/Parser/YAMLParser.cs
@@ -27,10 +27,7 @@ public class YAMLParser : IFrontMatterParser
///
public IFrontMatter ParseFrontmatterAndMarkdownFromFile(in string fileFullPath, in string? sourceContentPath = null)
{
- if (fileFullPath is null)
- {
- throw new ArgumentNullException(nameof(fileFullPath));
- }
+ ArgumentNullException.ThrowIfNull(fileFullPath);
string? fileContent;
string? fileRelativePath;
@@ -50,10 +47,7 @@ public class YAMLParser : IFrontMatterParser
///
public IFrontMatter ParseFrontmatterAndMarkdown(in string fileFullPath, in string fileRelativePath, in string fileContent)
{
- if (fileRelativePath is null)
- {
- throw new ArgumentNullException(nameof(fileRelativePath));
- }
+ ArgumentNullException.ThrowIfNull(fileRelativePath);
using var content = new StringReader(fileContent);
var frontMatterBuilder = new StringBuilder();
@@ -62,7 +56,7 @@ public class YAMLParser : IFrontMatterParser
while ((line = content.ReadLine()) != null && line != "---") { }
while ((line = content.ReadLine()) != null && line != "---")
{
- frontMatterBuilder.AppendLine(line);
+ _ = frontMatterBuilder.AppendLine(line);
}
// Join the read lines to form the front matter
@@ -75,7 +69,7 @@ public class YAMLParser : IFrontMatterParser
return page;
}
- private IFrontMatter ParseYAML(in string fileFullPath, in string fileRelativePath, string yaml, in string rawContent)
+ private FrontMatter ParseYAML(in string fileFullPath, in string fileRelativePath, string yaml, in string rawContent)
{
var frontMatter = yamlDeserializerRigid.Deserialize(new StringReader(yaml)) ?? throw new FormatException("Error parsing front matter");
var section = SiteHelper.GetSection(fileRelativePath);
@@ -112,14 +106,8 @@ public class YAMLParser : IFrontMatterParser
/// yamlObject already parsed if available
public void ParseParams(IParams settings, Type type, string yaml, object? yamlObject = null)
{
- if (settings is null)
- {
- throw new ArgumentNullException(nameof(settings));
- }
- if (type is null)
- {
- throw new ArgumentNullException(nameof(type));
- }
+ ArgumentNullException.ThrowIfNull(settings);
+ ArgumentNullException.ThrowIfNull(type);
yamlObject ??= yamlDeserializer.Deserialize(new StringReader(yaml));
if (yamlObject is not Dictionary