From 4b57128421f35181a3d2f2ce87b149988bd42ecb Mon Sep 17 00:00:00 2001 From: Jason Summers <3616919+jasonsummers@users.noreply.github.com> Date: Sun, 28 Dec 2025 15:31:10 +0000 Subject: [PATCH 1/6] Update all packages and target framework to net10.0 --- Directory.Build.props | 10 +++++----- .../Statiq.Web.Examples/Statiq.Web.Examples.csproj | 2 +- src/Statiq.Web.Aws/Statiq.Web.Aws.csproj | 2 +- src/Statiq.Web.Azure/Statiq.Web.Azure.csproj | 2 +- src/Statiq.Web.GitHub/Statiq.Web.GitHub.csproj | 4 ++-- src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj | 6 +++--- src/Statiq.Web.Netlify/Statiq.Web.Netlify.csproj | 2 +- src/Statiq.Web/Statiq.Web.csproj | 2 +- tests/Directory.Build.props | 4 ++-- .../Statiq.Web.Hosting.Tests.csproj | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 029539129..824348111 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -20,7 +20,7 @@ true snupkg true - netcoreapp3.1 + net10.0 true NU1901;NU1902;NU1903;NU1904;CA1724 @@ -31,11 +31,11 @@ - - - + + + - + diff --git a/examples/Statiq.Web.Examples/Statiq.Web.Examples.csproj b/examples/Statiq.Web.Examples/Statiq.Web.Examples.csproj index f1d241f36..5c4e01ec0 100644 --- a/examples/Statiq.Web.Examples/Statiq.Web.Examples.csproj +++ b/examples/Statiq.Web.Examples/Statiq.Web.Examples.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net10.0 $(MSBuildProjectDirectory) diff --git a/src/Statiq.Web.Aws/Statiq.Web.Aws.csproj b/src/Statiq.Web.Aws/Statiq.Web.Aws.csproj index cb7ee20fb..44ae5ab36 100644 --- a/src/Statiq.Web.Aws/Statiq.Web.Aws.csproj +++ b/src/Statiq.Web.Aws/Statiq.Web.Aws.csproj @@ -4,7 +4,7 @@ Statiq Static StaticContent StaticSite Blog BlogEngine AmazonWebServices AWS - + diff --git a/src/Statiq.Web.Azure/Statiq.Web.Azure.csproj b/src/Statiq.Web.Azure/Statiq.Web.Azure.csproj index ac486ab8c..8cbf66caa 100644 --- a/src/Statiq.Web.Azure/Statiq.Web.Azure.csproj +++ b/src/Statiq.Web.Azure/Statiq.Web.Azure.csproj @@ -5,7 +5,7 @@ - + diff --git a/src/Statiq.Web.GitHub/Statiq.Web.GitHub.csproj b/src/Statiq.Web.GitHub/Statiq.Web.GitHub.csproj index 29adbb38c..325c361c5 100644 --- a/src/Statiq.Web.GitHub/Statiq.Web.GitHub.csproj +++ b/src/Statiq.Web.GitHub/Statiq.Web.GitHub.csproj @@ -18,8 +18,8 @@ - - + + \ No newline at end of file diff --git a/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj b/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj index 7b972be9c..4bba78f9c 100644 --- a/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj +++ b/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/src/Statiq.Web.Netlify/Statiq.Web.Netlify.csproj b/src/Statiq.Web.Netlify/Statiq.Web.Netlify.csproj index 92f8b4294..944e83f4e 100644 --- a/src/Statiq.Web.Netlify/Statiq.Web.Netlify.csproj +++ b/src/Statiq.Web.Netlify/Statiq.Web.Netlify.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/Statiq.Web/Statiq.Web.csproj b/src/Statiq.Web/Statiq.Web.csproj index e9930a12b..44361ab35 100644 --- a/src/Statiq.Web/Statiq.Web.csproj +++ b/src/Statiq.Web/Statiq.Web.csproj @@ -11,7 +11,7 @@ - + diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index aa2133ccb..39a0bc147 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -5,7 +5,7 @@ true - - + + \ No newline at end of file diff --git a/tests/Statiq.Web.Hosting.Tests/Statiq.Web.Hosting.Tests.csproj b/tests/Statiq.Web.Hosting.Tests/Statiq.Web.Hosting.Tests.csproj index da55d4e89..5414f39ef 100644 --- a/tests/Statiq.Web.Hosting.Tests/Statiq.Web.Hosting.Tests.csproj +++ b/tests/Statiq.Web.Hosting.Tests/Statiq.Web.Hosting.Tests.csproj @@ -14,8 +14,8 @@ - - + + From b5d2b84c810f3ab1c54631d6841ec9161e7ecefa Mon Sep 17 00:00:00 2001 From: Jason Summers <3616919+jasonsummers@users.noreply.github.com> Date: Sun, 28 Dec 2025 16:43:56 +0000 Subject: [PATCH 2/6] Resolve some new CodeAnalysis errors. Supress others. --- Directory.Build.props | 2 +- src/Statiq.Web.Hosting/Server.cs | 57 +++++++++++-------- .../Statiq.Web.Hosting.csproj | 2 - .../IExecutionContextXrefExtensions.cs | 2 +- src/Statiq.Web/Templates/Templates.cs | 2 + .../DefaultExtensionsMiddlewareTests.cs | 3 +- .../Middleware/DisableCacheMiddlewareTests.cs | 3 +- .../ScriptInjectionMiddlewareTests.cs | 3 +- .../VirtualDirectoryMiddlewareTests.cs | 3 +- .../Statiq.Web.Tests/Statiq.Web.Tests.csproj | 3 - 10 files changed, 44 insertions(+), 36 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 824348111..5e580fb55 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -22,7 +22,7 @@ true net10.0 true - NU1901;NU1902;NU1903;NU1904;CA1724 + NU1901;NU1902;NU1903;NU1904;CA1021;CA1062;CA1724;SA1414; diff --git a/src/Statiq.Web.Hosting/Server.cs b/src/Statiq.Web.Hosting/Server.cs index 3442c4484..6b6350209 100644 --- a/src/Statiq.Web.Hosting/Server.cs +++ b/src/Statiq.Web.Hosting/Server.cs @@ -11,21 +11,23 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Statiq.Common; using Statiq.Web.Hosting.LiveReload; using Statiq.Web.Hosting.Middleware; +using Microsoft.AspNetCore.Hosting.Server; namespace Statiq.Web.Hosting { /// /// An HTTP server that can serve static files from a specified directory on disk. /// - public class Server : IWebHost + public class Server : IHost { private readonly IReadOnlyDictionary _contentTypes; private readonly IReadOnlyDictionary _customHeaders; - private readonly IWebHost _host; + private readonly IHost _host; private readonly LiveReloadServer _liveReloadServer; public bool Extensionless { get; } @@ -40,7 +42,8 @@ public class Server : IWebHost /// public string VirtualDirectory { get; } - public IFeatureCollection ServerFeatures => _host.ServerFeatures; + // IWebHost exposed ServerFeatures directly; IHost does not. Resolve the server and return its features if available. + public IFeatureCollection ServerFeatures => _host.Services.GetService()?.Features; public IServiceProvider Services => _host.Services; @@ -50,7 +53,7 @@ public class Server : IWebHost /// The local path to serve files from. /// The port the server will serve HTTP requests on. public Server(string localPath, int port = 5080) - : this(localPath, port, true, null, true, null) + : this(localPath, port, true, null, true, null, null, null) { } @@ -113,29 +116,33 @@ public Server( string currentDirectory = Directory.GetCurrentDirectory(); - _host = new WebHostBuilder() - .UseContentRoot(currentDirectory) - .UseWebRoot(Path.Combine(currentDirectory, "wwwroot")) - .ConfigureLogging(loggingBuilder => + _host = new HostBuilder() + .ConfigureWebHost(webHostBuilder => { - if (loggerProviders is object) - { - foreach (ILoggerProvider loggerProvider in loggerProviders) + webHostBuilder + .UseContentRoot(currentDirectory) + .UseWebRoot(Path.Combine(currentDirectory, "wwwroot")) + .ConfigureLogging(loggingBuilder => { - if (loggerProvider is object) + if (loggerProviders != null) { - loggingBuilder.AddProvider( - new ChangeLevelLoggerProvider( - loggerProvider, - level => level == LogLevel.Information ? LogLevel.Debug : level)); + foreach (ILoggerProvider loggerProvider in loggerProviders) + { + if (loggerProvider != null) + { + loggingBuilder.AddProvider( + new ChangeLevelLoggerProvider( + loggerProvider, + level => level == LogLevel.Information ? LogLevel.Debug : level)); + } + } } - } - } + }) + .UseKestrel() + .ConfigureKestrel(x => x.ListenAnyIP(port)) + .ConfigureServices(ConfigureServices) + .Configure(ConfigureApp); }) - .UseKestrel() - .ConfigureKestrel(x => x.ListenAnyIP(port)) - .ConfigureServices(ConfigureServices) - .Configure(ConfigureApp) .Build(); } @@ -158,7 +165,7 @@ private void ConfigureServices(IServiceCollection services) options.ForwardedHeaders = ForwardedHeaders.All; // Only loopback proxies are allowed by default, clear that restriction - options.KnownNetworks.Clear(); + options.KnownIPNetworks.Clear(); options.KnownProxies.Clear(); }); } @@ -172,7 +179,7 @@ private void ConfigureApp(IApplicationBuilder app) IWebHostEnvironment host = app.ApplicationServices.GetService(); host.WebRootFileProvider = compositeFileProvider; - if (_liveReloadServer is object) + if (_liveReloadServer != null) { // Inject LiveReload script tags to HTML documents, needs to run first as it overrides output stream app.UseScriptInjection($"{VirtualDirectory ?? string.Empty}/livereload.js?host=localhost&port={Port}"); @@ -237,7 +244,7 @@ private void ConfigureApp(IApplicationBuilder app) public async Task TriggerReloadAsync() { - if (_liveReloadServer is object) + if (_liveReloadServer != null) { await _liveReloadServer.SendReloadMessageAsync(); } diff --git a/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj b/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj index 4bba78f9c..f4a919f59 100644 --- a/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj +++ b/src/Statiq.Web.Hosting/Statiq.Web.Hosting.csproj @@ -11,9 +11,7 @@ - - diff --git a/src/Statiq.Web/IExecutionContextXrefExtensions.cs b/src/Statiq.Web/IExecutionContextXrefExtensions.cs index 33e98c39b..30858e1e1 100644 --- a/src/Statiq.Web/IExecutionContextXrefExtensions.cs +++ b/src/Statiq.Web/IExecutionContextXrefExtensions.cs @@ -135,7 +135,7 @@ public static string GetXrefLink(this IExecutionContext context, string xref, bo .SelectMany(x => context.Outputs.FromPipeline(x).Select(y => (PipelineName: x, Document: y))) .Select(x => (x.Document.GetString(WebKeys.Xref), x)) .Where(x => x.Item1 is object) - .GroupBy(x => x.Item1, x => x.Item2, StringComparer.OrdinalIgnoreCase) + .GroupBy(x => x.Item1, x => x.x, StringComparer.OrdinalIgnoreCase) .ToDictionary(x => x.Key, x => (ICollection<(string, IDocument)>)x.ToArray(), StringComparer.OrdinalIgnoreCase); } } \ No newline at end of file diff --git a/src/Statiq.Web/Templates/Templates.cs b/src/Statiq.Web/Templates/Templates.cs index 0524e9b19..adf5875fe 100644 --- a/src/Statiq.Web/Templates/Templates.cs +++ b/src/Statiq.Web/Templates/Templates.cs @@ -15,7 +15,9 @@ namespace Statiq.Web { +#pragma warning disable CA1710 // Rename to TemplatesDictionary or TemplatesCollection public class Templates : IReadOnlyList