diff --git a/.editorconfig b/.editorconfig index 55dcd648..38a28be4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,15 +5,8 @@ trim_trailing_whitespace = true insert_final_newline = true indent_style = space indent_size = 4 -end_of_line = lf [*.{csproj,json,config,yml,props}] indent_size = 2 -[*.sh] -end_of_line = lf - -[*.{cmd, bat}] -end_of_line = crlf - csharp_style_namespace_declarations = file_scoped:suggestion diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..acd3bc6f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +# If this file is renamed, the incrementing run attempt number will be reset. + +name: CI + +on: + push: + branches: [ "dev", "main" ] + pull_request: + branches: [ "dev", "main" ] + +env: + CI_BUILD_NUMBER_BASE: ${{ github.run_number }} + CI_TARGET_BRANCH: ${{ github.head_ref || github.ref_name }} + +jobs: + build: + + # The build must run on Windows so that .NET Framework targets can be built and tested. + runs-on: windows-latest + + permissions: + contents: write + + steps: + - uses: actions/checkout@v4 + - name: Setup + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + - name: Compute build number + shell: bash + run: | + echo "CI_BUILD_NUMBER=$(($CI_BUILD_NUMBER_BASE+2300))" >> $GITHUB_ENV + - name: Build and Publish + env: + DOTNET_CLI_TELEMETRY_OPTOUT: true + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + shell: pwsh + run: | + ./Build.ps1 diff --git a/.gitignore b/.gitignore index c90bd95b..318ac620 100644 --- a/.gitignore +++ b/.gitignore @@ -1,203 +1,8 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -build/ -bld/ -[Bb]in/ -[Oo]bj/ - -# Visual Studo 2015 cache/options directory .vs/ - -# JetBrains project files .idea/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding addin-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config - -# Windows Azure Build Output -csx/ -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -*.[Cc]ache -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -project.lock.json - +bin/ +obj/ +test/ artifacts/ + +.DS_Store diff --git a/Build.ps1 b/Build.ps1 index 15133822..33920c45 100644 --- a/Build.ps1 +++ b/Build.ps1 @@ -1,38 +1,80 @@ +Write-Output "build: Tool versions follow" + +dotnet --version +dotnet --list-sdks + Write-Output "build: Build started" Push-Location $PSScriptRoot +try { + if (Test-Path .\artifacts) { + Write-Output "build: Cleaning ./artifacts" + Remove-Item ./artifacts -Force -Recurse + } -if(Test-Path .\artifacts) { - Write-Output "build: Cleaning .\artifacts" - Remove-Item .\artifacts -Force -Recurse -} + & dotnet restore --no-cache -$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL]; -$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL]; -$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"] -$commitHash = $(git rev-parse --short HEAD) -$buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($commitHash)" }[$suffix -ne ""] + $dbp = [Xml] (Get-Content .\Directory.Version.props) + $versionPrefix = $dbp.Project.PropertyGroup.VersionPrefix -Write-Output "build: Package version suffix is $suffix" -Write-Output "build: Build version suffix is $buildSuffix" + Write-Output "build: Package version prefix is $versionPrefix" -& dotnet build --configuration Release --version-suffix=$buildSuffix /p:ContinuousIntegrationBuild=true + $branch = @{ $true = $env:CI_TARGET_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$NULL -ne $env:CI_TARGET_BRANCH]; + $revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:CI_BUILD_NUMBER, 10); $false = "local" }[$NULL -ne $env:CI_BUILD_NUMBER]; + $suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)) -replace '([^a-zA-Z0-9\-]*)', '')-$revision"}[$branch -eq "main" -and $revision -ne "local"] + $commitHash = $(git rev-parse --short HEAD) + $buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($commitHash)" }[$suffix -ne ""] -if($LASTEXITCODE -ne 0) { throw 'build failed' } + Write-Output "build: Package version suffix is $suffix" + Write-Output "build: Build version suffix is $buildSuffix" -if($suffix) { - & dotnet pack src\Serilog.Settings.Configuration --configuration Release --no-build --no-restore -o artifacts --version-suffix=$suffix -} else { - & dotnet pack src\Serilog.Settings.Configuration --configuration Release --no-build --no-restore -o artifacts -} + & dotnet format --no-restore --verify-no-changes --severity error + & dotnet build -c Release --version-suffix=$buildSuffix /p:ContinuousIntegrationBuild=true + if ($LASTEXITCODE -ne 0) { throw "Build failed" } + + foreach ($src in Get-ChildItem src/*) { + Push-Location $src + + Write-Output "build: Packaging project in $src" + + if ($suffix) { + & dotnet pack -c Release --no-build --no-restore -o ../../artifacts --version-suffix=$suffix + } else { + & dotnet pack -c Release --no-build --no-restore -o ../../artifacts + } + if ($LASTEXITCODE -ne 0) { throw "Packaging failed" } -if($LASTEXITCODE -ne 0) { throw 'pack failed' } + Pop-Location + } -Write-Output "build: Testing" + foreach ($test in Get-ChildItem test/*.Tests) { + Push-Location $test -# Dotnet test doesn't run separate TargetFrameworks in parallel: https://github.com/dotnet/sdk/issues/19147 -# Workaround: use `dotnet test` on dlls directly in order to pass the `--parallel` option to vstest. -# The _reported_ runtime is wrong but the _actual_ used runtime is correct, see https://github.com/microsoft/vstest/issues/2037#issuecomment-720549173 -& dotnet test test\Serilog.Settings.Configuration.Tests\bin\Release\*\Serilog.Settings.Configuration.Tests.dll --parallel + Write-Output "build: Testing project in $test" -if($LASTEXITCODE -ne 0) { throw 'unit tests failed' } \ No newline at end of file + & dotnet test -c Release --no-build --no-restore + if ($LASTEXITCODE -ne 0) { throw "Testing failed" } + + Pop-Location + } + + if ($env:NUGET_API_KEY) { + # GitHub Actions will only supply this to branch builds and not PRs. We publish + # builds from any branch this action targets (i.e. main and dev). + + Write-Output "build: Publishing NuGet packages" + + foreach ($nupkg in Get-ChildItem artifacts/*.nupkg) { + & dotnet nuget push -k $env:NUGET_API_KEY -s https://api.nuget.org/v3/index.json "$nupkg" + if ($LASTEXITCODE -ne 0) { throw "Publishing failed" } + } + + if (!($suffix)) { + Write-Output "build: Creating release for version $versionPrefix" + + iex "gh release create v$versionPrefix --title v$versionPrefix --generate-notes $(get-item ./artifacts/*.nupkg) $(get-item ./artifacts/*.snupkg)" + } + } +} finally { + Pop-Location +} diff --git a/Directory.Build.props b/Directory.Build.props index 736814b0..c114992d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,11 +1,25 @@ + + latest True - true + + true $(MSBuildThisFileDirectory)assets/Serilog.snk - enable false enable + enable + true + true + true + true + snupkg + + + + + diff --git a/Directory.Version.props b/Directory.Version.props new file mode 100644 index 00000000..8c3cc169 --- /dev/null +++ b/Directory.Version.props @@ -0,0 +1,6 @@ + + + + 9.0.0 + + diff --git a/README.md b/README.md index 2eb4531b..17d3910d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Serilog.Settings.Configuration [![Build status](https://ci.appveyor.com/api/projects/status/r2bgfimd9ocr61px/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-settings-configuration/branch/master) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Settings.Configuration.svg?style=flat)](https://www.nuget.org/packages/Serilog.Settings.Configuration/) +# Serilog.Settings.Configuration [![Build status](https://github.com/serilog/serilog-settings-configuration/actions/workflows/ci.yml/badge.svg?branch=dev)](https://github.com/serilog/serilog-settings-configuration/actions) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Settings.Configuration.svg?style=flat)](https://www.nuget.org/packages/Serilog.Settings.Configuration/) A Serilog settings provider that reads from [Microsoft.Extensions.Configuration](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1) sources, including .NET Core's `appsettings.json` file. @@ -349,7 +349,7 @@ public record MyDto(int Id, int Name); public class FirstDestructuringPolicy : IDestructuringPolicy { - public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, + public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, [NotNullWhen(true)] out LogEventPropertyValue? result) { if (value is not MyDto dto) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index eb9d04eb..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,52 +0,0 @@ -version: '{build}' - -skip_tags: true - -image: - - Visual Studio 2022 - - Ubuntu - - macOS - -build_script: -- pwsh: | - if ($isWindows) { - Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -OutFile "./dotnet-install.ps1" - ./dotnet-install.ps1 -JSonFile global.json -Architecture x64 -InstallDir 'C:\Program Files\dotnet' - ./Build.ps1 - } - if ($isLinux) { - Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh" - sudo chmod u+x dotnet-install.sh - sudo ./dotnet-install.sh --jsonfile global.json --architecture x64 --install-dir '/usr/share/dotnet' - ./Build.ps1 - } - if ($isMacOS) { - Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh" - sudo chmod u+x dotnet-install.sh - sudo ./dotnet-install.sh --jsonfile global.json --architecture x64 --install-dir '/usr/local/share/dotnet' - ./Build.ps1 - } - -test: off - -artifacts: -- path: artifacts/Serilog.*.nupkg -- path: artifacts/Serilog.*.snupkg - -deploy: -- provider: NuGet - api_key: - secure: JIfNMRv3l/2dmM/i//mpeEKqgxyEcnGr8XFlEoSDgp2JDVmRP8nUxc4gYznBvXQV - on: - branch: /^(main|dev)$/ - OS: Windows_NT -- provider: GitHub - auth_token: - secure: p4LpVhBKxGS5WqucHxFQ5c7C8cP74kbNB0Z8k9Oxx/PMaDQ1+ibmoexNqVU5ZlmX - artifacts: - /Serilog.*\.nupkg/ - /Serilog.*\.snupkg/ - tag: v$(appveyor_build_version) - on: - branch: main - OS: Windows_NT diff --git a/global.json b/global.json index b7e33571..db8627a2 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.100", "allowPrerelease": false, "rollForward": "latestFeature" } diff --git a/sample/Sample/Sample.csproj b/sample/Sample/Sample.csproj index ce3fee4a..1c8a2a79 100644 --- a/sample/Sample/Sample.csproj +++ b/sample/Sample/Sample.csproj @@ -1,8 +1,9 @@  - net462;net6.0;net7.0;net8.0 + net462;net8.0;net9.0 Exe + false @@ -14,15 +15,15 @@ - - - - - + + + + + - + - + diff --git a/serilog-settings-configuration.sln b/serilog-settings-configuration.sln index f0209fd7..4e06158e 100644 --- a/serilog-settings-configuration.sln +++ b/serilog-settings-configuration.sln @@ -9,7 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{62D0B9 ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig .gitignore = .gitignore - appveyor.yml = appveyor.yml Build.ps1 = Build.ps1 CHANGES.md = CHANGES.md Directory.Build.props = Directory.Build.props @@ -18,6 +17,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{62D0B9 README.md = README.md serilog-settings-configuration.sln.DotSettings = serilog-settings-configuration.sln.DotSettings global.json = global.json + Directory.Version.props = Directory.Version.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{D551DCB0-7771-4D01-BEBD-F7B57D1CF0E3}" @@ -34,6 +34,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDummies", "test\TestDum EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApp", "test\TestApp\TestApp.csproj", "{1B6E08F3-16C9-4912-BEEE-57DB78C92A12}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{21A409AD-2C11-41A8-88C8-360062EA8E48}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{391B84C5-A7BA-4BE1-95A0-E459FA61D971}" + ProjectSection(SolutionItems) = preProject + .github\workflows\ci.yml = .github\workflows\ci.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -68,6 +75,7 @@ Global {A00E5E32-54F9-401A-BBA1-2F6FCB6366CD} = {D24872B9-57F3-42A7-BC8D-F9DA222FCE1B} {B7CF5068-DD19-4868-A268-5280BDE90361} = {D551DCB0-7771-4D01-BEBD-F7B57D1CF0E3} {1B6E08F3-16C9-4912-BEEE-57DB78C92A12} = {D551DCB0-7771-4D01-BEBD-F7B57D1CF0E3} + {391B84C5-A7BA-4BE1-95A0-E459FA61D971} = {21A409AD-2C11-41A8-88C8-360062EA8E48} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {485F8843-42D7-4267-B5FB-20FE9181DEE9} diff --git a/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs b/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs index 0a2bb7d3..25f77ddc 100644 --- a/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs +++ b/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs @@ -218,8 +218,8 @@ public static LoggerConfiguration Configuration( { var configurationReader = readerOptions switch { - { ConfigurationAssemblySource: {} } => GetConfigurationReader(configuration, readerOptions, readerOptions.ConfigurationAssemblySource.Value), - { Assemblies: {} } => GetConfigurationReader(configuration, readerOptions, readerOptions.Assemblies), + { ConfigurationAssemblySource: { } } => GetConfigurationReader(configuration, readerOptions, readerOptions.ConfigurationAssemblySource.Value), + { Assemblies: { } } => GetConfigurationReader(configuration, readerOptions, readerOptions.Assemblies), _ => GetConfigurationReader(configuration, readerOptions ?? new ConfigurationReaderOptions(), readerOptions?.DependencyContext), }; return settingConfiguration.Settings(configurationReader); diff --git a/src/Serilog.Settings.Configuration/Properties/AssemblyInfo.cs b/src/Serilog.Settings.Configuration/Properties/AssemblyInfo.cs deleted file mode 100644 index 2527091f..00000000 --- a/src/Serilog.Settings.Configuration/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Serilog.Settings.Configuration.Tests, PublicKey=" + - "0024000004800000940000000602000000240000525341310004000001000100fb8d13fd344a1c" + - "6fe0fe83ef33c1080bf30690765bc6eb0df26ebfdf8f21670c64265b30db09f73a0dea5b3db4c9" + - "d18dbf6d5a25af5ce9016f281014d79dc3b4201ac646c451830fc7e61a2dfd633d34c39f87b818" + - "94191652df5ac63cc40c77f3542f702bda692e6e8a9158353df189007a49da0f3cfd55eb250066" + - "b19485ec")] \ No newline at end of file diff --git a/src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj b/src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj index 15664443..51e95896 100644 --- a/src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj +++ b/src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj @@ -1,43 +1,31 @@ - + Microsoft.Extensions.Configuration (appsettings.json) support for Serilog. - - 8.0.4 Serilog Contributors - - net462;netstandard2.0;net6.0;net7.0;net8.0 - true - Serilog.Settings.Configuration - serilog;json + net462;netstandard2.0;net8.0;net9.0 + serilog;json;appsettings icon.png README.md Apache-2.0 https://github.com/serilog/serilog-settings-configuration $(PackageProjectUrl)/releases Serilog - true - true - true - snupkg - - - - - - + - + + - - + + diff --git a/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs b/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs index bd469b36..3b861708 100644 --- a/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs +++ b/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs @@ -18,7 +18,7 @@ class ConfigurationReader : IConfigurationReader const string LevelSwitchNameRegex = @"^\${0,1}[A-Za-z]+[A-Za-z0-9]*$"; // Section names that can be handled by Serilog itself (hence builtin) without requiring any additional assemblies. - static readonly string[] BuiltinSectionNames = { "LevelSwitches", "MinimumLevel", "Properties" }; + static readonly string[] BuiltinSectionNames = ["LevelSwitches", "MinimumLevel", "Properties"]; readonly IConfiguration _section; readonly IReadOnlyCollection _configurationAssemblies; @@ -218,7 +218,7 @@ void ApplyMinimumLevelConfiguration(IConfigurationSection directive, Action logger/sink config parameter? var typeInfo = toType.GetTypeInfo(); if (typeInfo.IsGenericType && - typeInfo.GetGenericTypeDefinition() is {} genericType && genericType == typeof(Action<>)) + typeInfo.GetGenericTypeDefinition() is { } genericType && genericType == typeof(Action<>)) { var configType = typeInfo.GenericTypeArguments[0]; IConfigurationReader configReader = new ConfigurationReader(_section, _configurationAssemblies, resolutionContext); @@ -101,7 +101,7 @@ bool TryCreateContainer([NotNullWhen(true)] out object? result) { var argumentValue = FromSection(section, _configurationAssemblies); var value = argumentValue.ConvertTo(elementType, resolutionContext); - addMethod.Invoke(result, new[] { value }); + addMethod.Invoke(result, [value]); } return true; } @@ -185,14 +185,28 @@ bool TryCallCtor(Type type, Dictionary suppliedAr } else { - return new { ci, args, isCallable = false, matches, stringMatches, - usedArguments = suppliedNames }; + return new + { + ci, + args, + isCallable = false, + matches, + stringMatches, + usedArguments = suppliedNames + }; } } } - return new { ci, args, isCallable = true, matches, stringMatches, - usedArguments = suppliedNames }; + return new + { + ci, + args, + isCallable = true, + matches, + stringMatches, + usedArguments = suppliedNames + }; }) .Where(binding => binding.isCallable) .OrderByDescending(binding => binding.matches) diff --git a/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs b/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs index 61d40d86..493cad2a 100644 --- a/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs +++ b/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs @@ -70,7 +70,7 @@ public void AddFilterSwitch(string filterSwitchName, LoggingFilterSwitchProxy fi _declaredFilterSwitches[referenceName] = filterSwitch; } - string ToSwitchReference(string switchName) + static string ToSwitchReference(string switchName) { return switchName.StartsWith("$") ? switchName : $"${switchName}"; } diff --git a/test/Serilog.Settings.Configuration.Tests/ApiApprovalTests.cs b/test/Serilog.Settings.Configuration.Tests/Approval/ApiApprovalTests.cs similarity index 85% rename from test/Serilog.Settings.Configuration.Tests/ApiApprovalTests.cs rename to test/Serilog.Settings.Configuration.Tests/Approval/ApiApprovalTests.cs index 08bf7f46..fd50fc66 100644 --- a/test/Serilog.Settings.Configuration.Tests/ApiApprovalTests.cs +++ b/test/Serilog.Settings.Configuration.Tests/Approval/ApiApprovalTests.cs @@ -1,4 +1,4 @@ -#if NET7_0 +#if NET9_0 using PublicApiGenerator; using Shouldly; @@ -15,7 +15,7 @@ public void PublicApi_Should_Not_Change_Unintentionally() new() { IncludeAssemblyAttributes = false, - ExcludeAttributes = new[] { "System.Diagnostics.DebuggerDisplayAttribute" }, + ExcludeAttributes = [ "System.Diagnostics.DebuggerDisplayAttribute" ], }); publicApi.ShouldMatchApproved(options => options.WithFilenameGenerator((_, _, fileType, fileExtension) => $"{assembly.GetName().Name!}.{fileType}.{fileExtension}")); diff --git a/test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.approved.txt b/test/Serilog.Settings.Configuration.Tests/Approval/Serilog.Settings.Configuration.approved.txt similarity index 100% rename from test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.approved.txt rename to test/Serilog.Settings.Configuration.Tests/Approval/Serilog.Settings.Configuration.approved.txt diff --git a/test/Serilog.Settings.Configuration.Tests/ConfigurationReaderTests.cs b/test/Serilog.Settings.Configuration.Tests/ConfigurationReaderTests.cs index d235e8f2..da013162 100644 --- a/test/Serilog.Settings.Configuration.Tests/ConfigurationReaderTests.cs +++ b/test/Serilog.Settings.Configuration.Tests/ConfigurationReaderTests.cs @@ -185,17 +185,17 @@ public void MethodsAreSelectedBasedOnCountOfMatchedArgumentsAndThenStringType() Assert.Equal(typeof(string), selected?.GetParameters()[2].ParameterType); } - public static IEnumerable FlatMinimumLevel => new List - { - new object[] { GetConfigRoot(appsettingsJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error }, - new object[] { GetConfigRoot(appsettingsDevelopmentJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error }, - new object[] { GetConfigRoot(envVariables: new Dictionary {{minimumLevelFlatKey, LogEventLevel.Error.ToString()}}), LogEventLevel.Error}, - new object[] { GetConfigRoot( + public static IEnumerable FlatMinimumLevel => + [ + [GetConfigRoot(appsettingsJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error], + [GetConfigRoot(appsettingsDevelopmentJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error], + [GetConfigRoot(envVariables: new Dictionary {{minimumLevelFlatKey, LogEventLevel.Error.ToString()}}), LogEventLevel.Error], + [GetConfigRoot( appsettingsJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Debug), envVariables: new Dictionary {{minimumLevelFlatKey, LogEventLevel.Error.ToString()}}), LogEventLevel.Error - } - }; + ] + ]; [Theory] [MemberData(nameof(FlatMinimumLevel))] @@ -209,17 +209,17 @@ public void FlatMinimumLevelCorrectOneIsEnabledOnLogger(IConfigurationRoot root, AssertLogEventLevels(loggerConfig, expectedMinimumLevel); } - public static IEnumerable ObjectMinimumLevel => new List - { - new object[] { GetConfigRoot(appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error }, - new object[] { GetConfigRoot(appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error.ToString().ToUpper())), LogEventLevel.Error }, - new object[] { GetConfigRoot(appsettingsDevelopmentJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error }, - new object[] { GetConfigRoot(envVariables: new Dictionary{{minimumLevelObjectKey, LogEventLevel.Error.ToString() } }), LogEventLevel.Error }, - new object[] { GetConfigRoot( + public static IEnumerable ObjectMinimumLevel => + [ + [GetConfigRoot(appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error], + [GetConfigRoot(appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error.ToString().ToUpper())), LogEventLevel.Error], + [GetConfigRoot(appsettingsDevelopmentJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error)), LogEventLevel.Error], + [GetConfigRoot(envVariables: new Dictionary{{minimumLevelObjectKey, LogEventLevel.Error.ToString() } }), LogEventLevel.Error], + [GetConfigRoot( appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error), appsettingsDevelopmentJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Debug)), - LogEventLevel.Debug } - }; + LogEventLevel.Debug ] + ]; [Theory] [MemberData(nameof(ObjectMinimumLevel))] @@ -234,25 +234,22 @@ public void ObjectMinimumLevelCorrectOneIsEnabledOnLogger(IConfigurationRoot roo } // currently only works in the .NET 4.6.1 and .NET Standard builds of Serilog.Settings.Configuration - public static IEnumerable MixedMinimumLevel => new List - { - new object[] - { + public static IEnumerable MixedMinimumLevel => + [ + [ GetConfigRoot( appsettingsJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Error), appsettingsDevelopmentJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Debug)), LogEventLevel.Debug - }, - new object[] - { + ], + [ GetConfigRoot( appsettingsJsonLevel: minimumLevelFlatTemplate.Format(LogEventLevel.Error), appsettingsDevelopmentJsonLevel: minimumLevelObjectTemplate.Format(LogEventLevel.Debug)), LogEventLevel.Debug - }, + ], // precedence should be flat > object if from the same source - new object[] - { + [ GetConfigRoot( envVariables: new Dictionary() { @@ -260,8 +257,8 @@ public void ObjectMinimumLevelCorrectOneIsEnabledOnLogger(IConfigurationRoot roo {minimumLevelFlatKey, LogEventLevel.Debug.ToString()} }), LogEventLevel.Debug - } - }; + ] + ]; [Theory] [MemberData(nameof(MixedMinimumLevel))] diff --git a/test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.Tests.csproj b/test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.Tests.csproj index 37df7b50..d3ac6ccd 100644 --- a/test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.Tests.csproj +++ b/test/Serilog.Settings.Configuration.Tests/Serilog.Settings.Configuration.Tests.csproj @@ -2,8 +2,9 @@ net48 - $(TargetFrameworks);net6.0;net7.0;net8.0 + $(TargetFrameworks);net8.0;net9.0 false + false @@ -18,17 +19,17 @@ - - - - - - + + + + + + - - + + - + diff --git a/test/Serilog.Settings.Configuration.Tests/Support/ConfigurationReaderTestHelpers.cs b/test/Serilog.Settings.Configuration.Tests/Support/ConfigurationReaderTestHelpers.cs index ae76b43f..2d568137 100644 --- a/test/Serilog.Settings.Configuration.Tests/Support/ConfigurationReaderTestHelpers.cs +++ b/test/Serilog.Settings.Configuration.Tests/Support/ConfigurationReaderTestHelpers.cs @@ -53,9 +53,9 @@ public static IConfigurationRoot GetConfigRoot( { var configBuilder = new ConfigurationBuilder(); - configBuilder.AddJsonString(appsettingsJsonLevel ?? "{}"); + configBuilder.AddJsonString(appsettingsJsonLevel ?? "{}"); configBuilder.AddJsonString(appsettingsDevelopmentJsonLevel ?? "{}"); - configBuilder.Add(new ReloadableConfigurationSource(envVariables ?? new Dictionary())); + configBuilder.Add(new ReloadableConfigurationSource(envVariables ?? [])); return configBuilder.Build(); } diff --git a/test/Serilog.Settings.Configuration.Tests/Support/TestApp.cs b/test/Serilog.Settings.Configuration.Tests/Support/TestApp.cs index 9263a66a..7cf41835 100644 --- a/test/Serilog.Settings.Configuration.Tests/Support/TestApp.cs +++ b/test/Serilog.Settings.Configuration.Tests/Support/TestApp.cs @@ -26,7 +26,7 @@ public TestApp(IMessageSink messageSink) { file.CopyTo(_workingDirectory.File(file.Name).FullName, overwrite: true); } - _executables = new Dictionary(); + _executables = []; } async Task IAsyncLifetime.InitializeAsync() diff --git a/test/TestApp-net9.0/.gitignore b/test/TestApp-net9.0/.gitignore new file mode 100644 index 00000000..1cc29f16 --- /dev/null +++ b/test/TestApp-net9.0/.gitignore @@ -0,0 +1,2 @@ +FodyWeavers.xml +FodyWeavers.xsd diff --git a/test/TestApp-net9.0/Program.cs b/test/TestApp-net9.0/Program.cs new file mode 100644 index 00000000..033b43da --- /dev/null +++ b/test/TestApp-net9.0/Program.cs @@ -0,0 +1,70 @@ +using System.Reflection; +using Microsoft.Extensions.Configuration; +using Serilog; +using Serilog.Debugging; +using Serilog.Settings.Configuration; + +if (args.Length == 1 && args[0] == "is-single-file") +{ + if (typeof(Program).Assembly.GetManifestResourceNames().Any(e => e.StartsWith("costura."))) + { + Console.WriteLine(true); + return 0; + } + // IL3000: 'System.Reflection.Assembly.Location' always returns an empty string for assemblies embedded in a single-file app +#pragma warning disable IL3000 + Console.WriteLine(string.IsNullOrEmpty(Assembly.GetEntryAssembly()?.Location)); +#pragma warning restore + return 0; +} + +SelfLog.Enable(Console.Error); + +Thread.CurrentThread.Name = "Main thread"; +const string outputTemplate = "({ThreadName}) [{Level}] {Message}{NewLine}"; + +var configurationValues = new Dictionary(); +var minimumLevelOnly = args.Contains("--minimum-level-only"); +if (minimumLevelOnly) +{ + configurationValues["Serilog:MinimumLevel"] = "Verbose"; +} +else +{ + configurationValues["Serilog:Enrich:0"] = "WithThreadName"; + configurationValues["Serilog:WriteTo:0:Name"] = "Console"; + configurationValues["Serilog:WriteTo:0:Args:outputTemplate"] = outputTemplate; +} + +if (args.Contains("--using-thread")) configurationValues["Serilog:Using:Thread"] = "Serilog.Enrichers.Thread"; +if (args.Contains("--using-console")) configurationValues["Serilog:Using:Console"] = "Serilog.Sinks.Console"; + +var assemblies = new List(); +if (args.Contains("--assembly-thread")) assemblies.Add(typeof(ThreadLoggerConfigurationExtensions).Assembly); +if (args.Contains("--assembly-console")) assemblies.Add(typeof(ConsoleLoggerConfigurationExtensions).Assembly); + +try +{ + var configuration = new ConfigurationBuilder().AddInMemoryCollection(configurationValues).Build(); + var options = assemblies.Count > 0 ? new ConfigurationReaderOptions(assemblies.ToArray()) : null; + var loggerConfiguration = new LoggerConfiguration().ReadFrom.Configuration(configuration, options); + if (minimumLevelOnly) + { + loggerConfiguration + .Enrich.WithThreadName() + .WriteTo.Console(outputTemplate: outputTemplate); + } + var logger = loggerConfiguration.CreateLogger(); + logger.Information("Expected success"); + return 0; +} +catch (InvalidOperationException exception) when (exception.Message.StartsWith("No Serilog:Using configuration section is defined and no Serilog assemblies were found.")) +{ + Console.WriteLine("Expected exception"); + return 0; +} +catch (Exception exception) +{ + Console.Error.WriteLine(exception); + return 1; +} diff --git a/test/TestApp-net9.0/Serilog.Settings.Configuration.0.0.0-IntegrationTest.0.snupkg b/test/TestApp-net9.0/Serilog.Settings.Configuration.0.0.0-IntegrationTest.0.snupkg new file mode 100644 index 00000000..bf7bdf1a Binary files /dev/null and b/test/TestApp-net9.0/Serilog.Settings.Configuration.0.0.0-IntegrationTest.0.snupkg differ diff --git a/test/TestApp-net9.0/TestApp.csproj b/test/TestApp-net9.0/TestApp.csproj new file mode 100644 index 00000000..585e7065 --- /dev/null +++ b/test/TestApp-net9.0/TestApp.csproj @@ -0,0 +1,33 @@ + + + + Exe + net48 + embedded + false + false + false + none + true + true + false + + NU1902;NU1903 + + + + + + + + + + + + + + + + + + diff --git a/test/TestApp-net9.0/nuget.config b/test/TestApp-net9.0/nuget.config new file mode 100644 index 00000000..cfec8fcc --- /dev/null +++ b/test/TestApp-net9.0/nuget.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/test/TestApp/TestApp.csproj b/test/TestApp/TestApp.csproj index b814a4dc..585e7065 100644 --- a/test/TestApp/TestApp.csproj +++ b/test/TestApp/TestApp.csproj @@ -10,6 +10,9 @@ none true true + false + + NU1902;NU1903 @@ -22,9 +25,9 @@ - - - + + + diff --git a/test/TestDummies/Console/DummyConsoleSink.cs b/test/TestDummies/Console/DummyConsoleSink.cs index 0486eaef..5605086c 100644 --- a/test/TestDummies/Console/DummyConsoleSink.cs +++ b/test/TestDummies/Console/DummyConsoleSink.cs @@ -17,7 +17,7 @@ public DummyConsoleSink(ConsoleTheme? theme = null) [ThreadStatic] static List? EmittedList; - public static List Emitted => EmittedList ??= new List(); + public static List Emitted => EmittedList ??= []; public void Emit(LogEvent logEvent) { diff --git a/test/TestDummies/DummyConfigurationSink.cs b/test/TestDummies/DummyConfigurationSink.cs index 51620add..86b24a03 100644 --- a/test/TestDummies/DummyConfigurationSink.cs +++ b/test/TestDummies/DummyConfigurationSink.cs @@ -15,7 +15,7 @@ public class DummyConfigurationSink : ILogEventSink [ThreadStatic] static IConfigurationSection? _configSection; - public static List Emitted => _emitted ?? (_emitted = new List()); + public static List Emitted => _emitted ?? (_emitted = []); public static IConfiguration? Configuration => _configuration; diff --git a/test/TestDummies/DummyLoggerConfigurationExtensions.cs b/test/TestDummies/DummyLoggerConfigurationExtensions.cs index ea870240..d7118f65 100644 --- a/test/TestDummies/DummyLoggerConfigurationExtensions.cs +++ b/test/TestDummies/DummyLoggerConfigurationExtensions.cs @@ -133,12 +133,9 @@ public static LoggerConfiguration Dummy( this LoggerSinkConfiguration loggerSinkConfiguration, Action wrappedSinkAction) { - return LoggerSinkConfiguration.Wrap( - loggerSinkConfiguration, + return loggerSinkConfiguration.Sink(LoggerSinkConfiguration.Wrap( s => new DummyWrappingSink(s), - wrappedSinkAction, - LogEventLevel.Verbose, - levelSwitch: null); + wrappedSinkAction)); } public static LoggerConfiguration WithDummyHardCodedString( diff --git a/test/TestDummies/DummyPolicy.cs b/test/TestDummies/DummyPolicy.cs index 5774510a..3fe44e85 100644 --- a/test/TestDummies/DummyPolicy.cs +++ b/test/TestDummies/DummyPolicy.cs @@ -34,7 +34,7 @@ public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyV public class CustomCollection : IEnumerable { - private readonly List inner = new List(); + private readonly List inner = []; public void Add(T item) => inner.Add(item); diff --git a/test/TestDummies/DummyRollingFileAuditSink.cs b/test/TestDummies/DummyRollingFileAuditSink.cs index 3365ba55..7f943774 100644 --- a/test/TestDummies/DummyRollingFileAuditSink.cs +++ b/test/TestDummies/DummyRollingFileAuditSink.cs @@ -8,7 +8,7 @@ public class DummyRollingFileAuditSink : ILogEventSink [ThreadStatic] static List? _emitted; - public static List Emitted => _emitted ??= new List(); + public static List Emitted => _emitted ??= []; public void Emit(LogEvent logEvent) { diff --git a/test/TestDummies/DummyRollingFileSink.cs b/test/TestDummies/DummyRollingFileSink.cs index 3f8fd0e7..115e0759 100644 --- a/test/TestDummies/DummyRollingFileSink.cs +++ b/test/TestDummies/DummyRollingFileSink.cs @@ -8,7 +8,7 @@ public class DummyRollingFileSink : ILogEventSink [ThreadStatic] static List? _emitted; - public static List Emitted => _emitted ??= new List(); + public static List Emitted => _emitted ??= []; public void Emit(LogEvent logEvent) { diff --git a/test/TestDummies/DummyWithLevelSwitchSink.cs b/test/TestDummies/DummyWithLevelSwitchSink.cs index 2a3fadb4..0d74a510 100644 --- a/test/TestDummies/DummyWithLevelSwitchSink.cs +++ b/test/TestDummies/DummyWithLevelSwitchSink.cs @@ -15,7 +15,7 @@ public DummyWithLevelSwitchSink(LoggingLevelSwitch? loggingControlLevelSwitch) [ThreadStatic] // ReSharper disable ThreadStaticFieldHasInitializer - public static List Emitted = new List(); + public static List Emitted = []; // ReSharper restore ThreadStaticFieldHasInitializer public void Emit(LogEvent logEvent) diff --git a/test/TestDummies/DummyWrappingSink.cs b/test/TestDummies/DummyWrappingSink.cs index 9dc0d35c..f2188b40 100644 --- a/test/TestDummies/DummyWrappingSink.cs +++ b/test/TestDummies/DummyWrappingSink.cs @@ -8,7 +8,7 @@ public class DummyWrappingSink : ILogEventSink [ThreadStatic] static List? _emitted; - public static List Emitted => _emitted ??= new List(); + public static List Emitted => _emitted ??= []; readonly ILogEventSink _sink; diff --git a/test/TestDummies/TestDummies.csproj b/test/TestDummies/TestDummies.csproj index c5be233d..43f8c6d8 100644 --- a/test/TestDummies/TestDummies.csproj +++ b/test/TestDummies/TestDummies.csproj @@ -2,19 +2,16 @@ netstandard2.0;net462 + false - + - - - - - +