From dbd103e422a3544a321ebfbbb456234e03e3d0f0 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Thu, 15 Oct 2026 02:16:43 +0200 Subject: [PATCH 01/15] Re-enable SA1516 and list every StyleCop rule in .globalconfig .globalconfig had SA1516 at none, because StyleCop.Analyzers 1.2.0-beta.556 predates C# 12 and reported the rule on syntax it did not understand. 1.3.79-beta audits every rule against C# 8 to 15, so SA1516 goes back to warning. SA1141, SA1142, SA1317, and SA1653 get an explicit severity, because the file lists every StyleCop rule. Every rule set to none gets a comment saying why. Co-Authored-By: Claude Fable 5.1 --- .globalconfig | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/.globalconfig b/.globalconfig index d7fb4e60..7efcd097 100644 --- a/.globalconfig +++ b/.globalconfig @@ -239,7 +239,7 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case # Ordering and grouping follows the categories listed in the official documentation. # See https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation # ---------------------------------------------------------------------------------------------- -# Last update: 2026-06-21 (StyleCop.Analyzers v1.2.0-beta.556) +# Last update: 2026-10-15 (StyleCop.Analyzers v1.3.79-beta) # ============================================================================================== # StyleCop Analyzers - Special rules @@ -279,7 +279,7 @@ dotnet_diagnostic.SA1028.severity = warning # Code should not contain trailing w # StyleCop Analyzers - Readability rules dotnet_diagnostic.SA1100.severity = warning # Do not prefix calls with base unless local implementation exists -dotnet_diagnostic.SA1101.severity = none # Prefix local calls with this +dotnet_diagnostic.SA1101.severity = none # Prefix local calls with this # SX1101 is enabled instead dotnet_diagnostic.SX1101.severity = warning # Do not prefix local calls with this dotnet_diagnostic.SA1102.severity = warning # Query clause should follow previous clause dotnet_diagnostic.SA1103.severity = warning # Query clauses should be on separate lines or all on one line @@ -318,6 +318,8 @@ dotnet_diagnostic.SA1136.severity = warning # Enum values should be on separate dotnet_diagnostic.SA1137.severity = warning # Elements should have the same indentation # There is no SA1138 rule - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/pull/2034 dotnet_diagnostic.SA1139.severity = warning # Use literal suffix notation instead of casting +dotnet_diagnostic.SA1141.severity = warning # Use tuple syntax +dotnet_diagnostic.SA1142.severity = warning # Refer to tuple elements by name # StyleCop Analyzers - Ordering rules dotnet_diagnostic.SA1200.severity = warning # Using directives should be placed correctly @@ -325,7 +327,7 @@ dotnet_diagnostic.SA1201.severity = warning # Elements should appear in the corr dotnet_diagnostic.SA1202.severity = warning # Elements should be ordered by access dotnet_diagnostic.SA1203.severity = warning # Constants should appear before fields dotnet_diagnostic.SA1204.severity = warning # Static elements should appear before instance elements -dotnet_diagnostic.SA1205.severity = none # Partial elements should declare access +dotnet_diagnostic.SA1205.severity = none # Partial elements should declare access # Declaring access more than once for the same type violates single source of truth dotnet_diagnostic.SA1206.severity = warning # Declaration keywords should follow order dotnet_diagnostic.SA1207.severity = warning # Protected should come before internal dotnet_diagnostic.SA1208.severity = warning # System using directives should be placed before other using directives @@ -345,13 +347,13 @@ dotnet_diagnostic.SA1301.severity = warning # Element should begin with lower-ca dotnet_diagnostic.SA1302.severity = warning # Interface names should begin with I dotnet_diagnostic.SA1303.severity = warning # Const field names should begin with upper-case letter dotnet_diagnostic.SA1304.severity = warning # Non-private readonly fields should begin with upper-case letter -dotnet_diagnostic.SA1305.severity = none # Field names should not use Hungarian notation +dotnet_diagnostic.SA1305.severity = none # Field names should not use Hungarian notation # Nobody uses Hungarian notation anymore; this rule would flag names that are most probably prefixed for valid reasons dotnet_diagnostic.SA1306.severity = warning # Field names should begin with lower-case letter dotnet_diagnostic.SA1307.severity = warning # Accessible fields should begin with upper-case letter dotnet_diagnostic.SA1308.severity = warning # Variable names should not be prefixed -dotnet_diagnostic.SA1309.severity = none # Private instance field names should not begin with underscore +dotnet_diagnostic.SA1309.severity = none # Private instance field names should not begin with underscore # SX1309 is enabled instead dotnet_diagnostic.SX1309.severity = warning # Private instance field names should begin with underscore -dotnet_diagnostic.SX1309S.severity = none # Static field names should begin with underscore +dotnet_diagnostic.SX1309S.severity = none # Static field names should begin with underscore # SX1309 is enabled instead dotnet_diagnostic.SA1310.severity = warning # Field names should not contain underscore dotnet_diagnostic.SA1311.severity = warning # Static readonly fields should begin with upper-case letter dotnet_diagnostic.SA1312.severity = warning # Variable names should begin with lower-case letter @@ -359,6 +361,7 @@ dotnet_diagnostic.SA1313.severity = warning # Parameter names should begin with dotnet_diagnostic.SA1314.severity = warning # Type parameter names should begin with T # Rule SA1315 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1949 dotnet_diagnostic.SA1316.severity = warning # Tuple element names should use correct casing +dotnet_diagnostic.SA1317.severity = warning # Identifier should be named only with Latin letters # StyleCop Analyzers - Maintainability rules dotnet_diagnostic.SA1119.severity = warning # Statement should not use unnecessary parenthesis @@ -369,12 +372,12 @@ dotnet_diagnostic.SA1403.severity = warning # File may only contain a single nam dotnet_diagnostic.SA1404.severity = warning # Code analysis suppression should have justification dotnet_diagnostic.SA1405.severity = warning # Debug.Assert should provide message text dotnet_diagnostic.SA1406.severity = warning # Debug.Fail should provide message text -dotnet_diagnostic.SA1407.severity = none # Arithmetic expressions should declare precedence +dotnet_diagnostic.SA1407.severity = none # Arithmetic expressions should declare precedence # Conflicts with ReSharper's RedundantParentheses inspection dotnet_diagnostic.SA1408.severity = warning # Conditional expressions should declare precedence # Rule SA1409 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1058 dotnet_diagnostic.SA1410.severity = warning # Remove delegate parenthesis when possible dotnet_diagnostic.SA1411.severity = warning # Attribute constructor should not use unnecessary parenthesis -dotnet_diagnostic.SA1412.severity = none # Store files as UTF-8 with byte order mark +dotnet_diagnostic.SA1412.severity = none # Store files as UTF-8 with byte order mark # Practically all IDEs and editors save source code as UTF-8 anyway; Claude Code's Write tool does not add a BOM dotnet_diagnostic.SA1413.severity = warning # Use trailing comma in multi-line initializers dotnet_diagnostic.SA1414.severity = warning # Tuple types in signatures should have element names @@ -395,7 +398,7 @@ dotnet_diagnostic.SA1512.severity = warning # Single-line comments should not be dotnet_diagnostic.SA1513.severity = warning # Closing brace should be followed by blank line dotnet_diagnostic.SA1514.severity = warning # Element documentation header should be preceded by blank line dotnet_diagnostic.SA1515.severity = warning # Single-line comment should be preceded by blank line -dotnet_diagnostic.SA1516.severity = none # Elements should be separated by blank line +dotnet_diagnostic.SA1516.severity = warning # Elements should be separated by blank line dotnet_diagnostic.SA1517.severity = warning # Code should not contain blank lines at start of file dotnet_diagnostic.SA1518.severity = warning # Use line endings correctly at end of file dotnet_diagnostic.SA1519.severity = warning # Braces should not be omitted from multi-line child statement @@ -403,7 +406,7 @@ dotnet_diagnostic.SA1520.severity = warning # Use braces consistently # StyleCop Analyzers - Documentation rules dotnet_diagnostic.SA1600.severity = warning # Elements should be documented -dotnet_diagnostic.SA1601.severity = none # Partial elements should be documented +dotnet_diagnostic.SA1601.severity = none # Partial elements should be documented # Elements should be documented once (single source of truth) dotnet_diagnostic.SA1602.severity = warning # Enumeration items should be documented # Rule SA1603 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1291 dotnet_diagnostic.SA1604.severity = warning # Element documentation should have summary @@ -411,8 +414,8 @@ dotnet_diagnostic.SA1605.severity = warning # Partial element documentation shou dotnet_diagnostic.SA1606.severity = warning # Element documentation should have summary text dotnet_diagnostic.SA1607.severity = warning # Partial element documentation should have summary text dotnet_diagnostic.SA1608.severity = warning # Element documentation should not have default summary -dotnet_diagnostic.SA1609.severity = none # Property documentation should have value -dotnet_diagnostic.SA1610.severity = none # Property documentation should have value text +dotnet_diagnostic.SA1609.severity = none # Property documentation should have value # Would add very little value in practice +dotnet_diagnostic.SA1610.severity = none # Property documentation should have value text # Would add very little value in practice dotnet_diagnostic.SA1611.severity = warning # Element parameters should be documented dotnet_diagnostic.SA1612.severity = warning # Element parameter documentation should match element parameters dotnet_diagnostic.SA1613.severity = warning # Element parameter documentation should declare parameter name @@ -455,6 +458,7 @@ dotnet_diagnostic.SA1649.severity = warning # File name should match first type # Rule SA1650 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1057 dotnet_diagnostic.SA1651.severity = warning # Do not use placeholder elements # Rule SA1652 superseded by SA0001 +dotnet_diagnostic.SA1653.severity = warning # Only one partial declaration should contain summary documentation # ============================================================================================== # PUBLIC API ANALYZERS From 06d87e2ccc8e6534490b7618202e31cf38a755a8 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Thu, 15 Oct 2026 22:46:23 +0200 Subject: [PATCH 02/15] Use nint instead of IntPtr in VirtualTerminal StyleCop.Analyzers 1.3.79-beta reports IntPtr under SA1121, which asks for the built-in alias nint. Co-Authored-By: Claude Opus 5.5 --- src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs b/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs index f1b60a3f..e344d2cc 100644 --- a/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs +++ b/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs @@ -41,7 +41,7 @@ public static bool TryEnableOnStandardError() } var handle = GetStdHandle(StdErrorHandle); - if (handle == IntPtr.Zero || handle == -1) + if (handle is 0 or -1) { return false; } @@ -78,17 +78,17 @@ internal static bool IsNonWindowsTerminalCapable(string? term) [ExcludeFromCodeCoverage(Justification = "P/Invoke wrapper; behavior is owned by the Win32 console subsystem.")] [LibraryImport("kernel32.dll", SetLastError = true)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] - private static partial IntPtr GetStdHandle(int nStdHandle); + private static partial nint GetStdHandle(int nStdHandle); [ExcludeFromCodeCoverage(Justification = "P/Invoke wrapper; behavior is owned by the Win32 console subsystem.")] [LibraryImport("kernel32.dll", SetLastError = true)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode); + private static partial bool GetConsoleMode(nint hConsoleHandle, out uint lpMode); [ExcludeFromCodeCoverage(Justification = "P/Invoke wrapper; behavior is owned by the Win32 console subsystem.")] [LibraryImport("kernel32.dll", SetLastError = true)] [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] [return: MarshalAs(UnmanagedType.Bool)] - private static partial bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode); + private static partial bool SetConsoleMode(nint hConsoleHandle, uint dwMode); } From 80070869d435142bf9215453af64f8d8595d7ffc Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Thu, 15 Oct 2026 22:47:12 +0200 Subject: [PATCH 03/15] Stop SA1500 from rejecting expression braces at end of line SA1500 reports an initializer, switch expression, or collection expression whose opening brace ends a line. The ReSharper formatter settings of this repository put that brace at end of line, and SA1500 has no option to accept it. Three ReSharper inspections take over the check, and they follow the formatter settings. One more formatter setting keeps auto-properties on one line, which the inspections would otherwise split. Co-Authored-By: Claude Opus 5.5 --- .editorconfig | 7 +++++++ .globalconfig | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 0f188265..26f43fb1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -85,6 +85,9 @@ resharper_property_can_be_made_init_only_global_highlighting = warning # Entity Framework # Formatting +resharper_bad_declaration_braces_line_breaks_highlighting = warning +resharper_bad_control_braces_line_breaks_highlighting = warning +resharper_bad_expression_braces_line_breaks_highlighting = warning # Grammar Issues @@ -138,3 +141,7 @@ resharper_class_never_instantiated_global_highlighting = none resharper_unused_type_global_highlighting = none resharper_unused_member_global_highlighting = none resharper_member_can_be_private_global_highlighting = none + +# A formatter setting, not a severity. BadDeclarationBracesLineBreaks splits every auto-property without it. +# The same setting in Buildvana.slnx.DotSettings has no effect. +resharper_csharp_place_abstract_accessorholder_on_single_line = true diff --git a/.globalconfig b/.globalconfig index 7efcd097..e232233c 100644 --- a/.globalconfig +++ b/.globalconfig @@ -382,7 +382,7 @@ dotnet_diagnostic.SA1413.severity = warning # Use trailing comma in multi-line i dotnet_diagnostic.SA1414.severity = warning # Tuple types in signatures should have element names # StyleCop Analyzers - Layout rules -dotnet_diagnostic.SA1500.severity = warning # Braces for multi-line statements should not share line +dotnet_diagnostic.SA1500.severity = none # Braces for multi-line statements should not share line # Replaced by ReSharper's brace line break inspections, which put expression braces at end of line dotnet_diagnostic.SA1501.severity = warning # Statement should not be on a single line dotnet_diagnostic.SA1502.severity = warning # Element should not be on a single line dotnet_diagnostic.SA1503.severity = warning # Braces should not be omitted From 93e9f076a831c79f3b65f3dd4e59bcc0c150e837 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Fri, 16 Oct 2026 00:49:02 +0200 Subject: [PATCH 04/15] Stop inspect.cs from reusing stale inspectcode results inspectcode's rather aggressive result caching can cause inspect.cs to report false positives and false negatives. Now inspect.cs forces inspectcode to use a temporary cache directory under `.buildvana-temp` and cleans it before every invocation. Co-Authored-By: Claude Opus 5.5 --- .claude/tools/inspect.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.claude/tools/inspect.cs b/.claude/tools/inspect.cs index 952715b8..0e9b16c5 100644 --- a/.claude/tools/inspect.cs +++ b/.claude/tools/inspect.cs @@ -25,7 +25,8 @@ * * Both modes write one `path(line,col): severity ID: message` per diagnostic to standard output and nothing * else, which is what the `$msCompile` problem matcher consumes; progress and failure context go to standard - * error. The raw output of the three child processes, and the SARIF report, are left in `.buildvana-temp`. + * error. The raw output of the three child processes, the SARIF report, and the inspectcode caches are left in + * `.buildvana-temp`. The caches start empty on every run. */ using System; @@ -85,6 +86,7 @@ var scratchPath = Path.Combine(repoRoot, ".buildvana-temp"); var sarifPath = Path.Combine(scratchPath, "inspect.sarif"); +var cachesPath = Path.Combine(scratchPath, "inspectcode-caches"); // bv's own narration: leveled lines (`info: ...`) and activity lines (`[1] Build: starting...`). Everything else // a child writes is MSBuild's, which is far too verbose to echo. @@ -206,12 +208,21 @@ // --all has to name the lowest severity rather than leave the option out: inspectcode's own default is // WARNING, so omitting it would silently produce exactly what the gate produces. var severity = all ? "HINT" : gate ? "WARNING" : "SUGGESTION"; + +// inspectcode reuses its cached results for files that have not changed, so a change to the inspection +// settings would reach only the changed files. An empty cache on every run reports every file afresh. +if (Directory.Exists(cachesPath)) +{ + Directory.Delete(cachesPath, recursive: true); +} + Console.Error.WriteLine($"info: running inspectcode at severity {severity} (this takes a while)..."); string[] inspectArguments = [ "dnx", "JetBrains.ReSharper.GlobalTools", "inspectcode", "--swea", + $"--caches-home={cachesPath}", $"--severity={severity}", $"--output={sarifPath}", "--format=Sarif", From 29ca38feda2d97b0d73c5f68f28a7f0a4b17ec16 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Fri, 16 Oct 2026 01:53:43 +0200 Subject: [PATCH 05/15] Move expression opening braces off their own line Initializers, switch expressions, collection expressions, with expressions, and lambda blocks need not have their opening brace on a line of its own. Updated analyzer rules enforce this, so this commit applies the rule to existing code to avoid code analysis warnings. Co-Authored-By: Claude Opus 5.5 --- .../ConsoleOutput/MessageLevelExtensions.cs | 3 +- .../MSBuild/MSBuildBoolean.cs | 3 +- .../BuildvanaConfigFactory.cs | 39 ++++------ .../BuildvanaJsonConfigExample.cs | 9 +-- .../BuildvanaJsonConfigProvider.cs | 9 +-- .../BuildvanaJsonConfigSchema.cs | 3 +- .../BuildvanaJsonConfigSerialization.cs | 3 +- .../TextWriterReporter.cs | 3 +- .../CaseSensitivityModeExtensions.cs | 3 +- .../Gitignore/GitignoreCharClass.cs | 3 +- .../Gitignore/GitignorePattern-matching.cs | 3 +- .../Gitignore/GitignorePattern-parsing.cs | 3 +- .../JsonHelper-InsertProperty.cs | 6 +- src/Buildvana.Core.Json/JsonHelper.cs | 12 +-- .../JsonSchemaGenerator-KeyedObjects.cs | 3 +- .../Schema/JsonSchemaGenerator.cs | 9 +-- .../Schema/JsonSchemaValidator.cs | 9 +-- .../Schema/JsonSourceMap.cs | 3 +- src/Buildvana.Core.Testing/TempGitRepo.cs | 6 +- .../VersionSpecExtensions.cs | 3 +- .../AdditionalAssemblyInfoGenerator.cs | 3 +- .../Internal/ConstantValueParser.cs | 3 +- .../ThisAssemblyClassGenerator.cs | 3 +- .../Internal/JetBrainsAnnotationsExporter.cs | 9 +-- .../TaskLoggingHelperLogger.cs | 3 +- .../Tasks/ComputeVersion-caching.cs | 3 +- .../Tasks/WritePackagePinDump.cs | 6 +- src/Buildvana.Tool/Build/BuildPipeline.cs | 3 +- .../CommandLine/CommandLineOverridesParser.cs | 3 +- .../CommandLine/VerbosityParser.cs | 3 +- .../Execution/CommandRegistry.cs | 3 +- src/Buildvana.Tool/Program.cs | 3 +- .../Dependencies/AdditionalGroupPinReader.cs | 3 +- .../Dependencies/DependencyDiscovery.cs | 6 +- .../Services/Dependencies/DependencyPin.cs | 3 +- .../Dependencies/DependencyReportRenderer.cs | 9 +-- .../Dependencies/DependencyResolution.cs | 9 +-- .../Dependencies/DependencyResolver.cs | 18 ++--- .../Dependencies/DependencyScopeNames.cs | 3 +- .../Dependencies/EffectivePolicyResolver.cs | 3 +- .../Services/Dependencies/NetSdkPin.cs | 3 +- .../Dependencies/NuGetReporterLogger.cs | 3 +- .../OverrideLifecycle.RunState.cs | 6 +- .../Dependencies/OverrideLifecycle.cs | 3 +- .../Services/Dependencies/OverrideProject.cs | 6 +- .../Services/Dependencies/PackagePinReader.cs | 3 +- .../Services/Dependencies/PinNotes.cs | 3 +- .../Dependencies/ProjectAssetsReader.cs | 3 +- .../Dependencies/UpdatePolicyEngine.cs | 9 +-- src/Buildvana.Tool/Services/Git/GitService.cs | 12 +-- .../Services/Hooks/HookArgsFactory`1.cs | 3 +- .../Hooks/PostReleaseHookArgsFactory.cs | 6 +- .../Hooks/PostUpdateHookArgsFactory.cs | 18 ++--- .../Services/SelfReferenceUpdater.cs | 9 +-- .../Services/SelfUpdate/SelfVersionService.cs | 3 +- .../Internal/GitHub/GitHubServerAdapter.cs | 15 ++-- .../Internal/GitHub/GitHubServerRelease.cs | 3 +- .../Services/ServerAdapters/ServerRelease.cs | 12 +-- .../Services/Versioning/VersionService.cs | 12 +-- .../Subcommands/DependenciesPruneSettings.cs | 3 +- .../Subcommands/DependenciesSettings.cs | 3 +- .../Subcommands/DependenciesUpdateSettings.cs | 3 +- .../Subcommands/ReleaseCommand.cs | 3 +- .../Subcommands/ReleaseSettings.cs | 3 +- .../Subcommands/SelfUpdateCommand.cs | 3 +- .../Subcommands/SelfUpdateSettings.cs | 3 +- .../Subcommands/VersionAdvanceSettings.cs | 3 +- .../Utilities/AppDirectiveEditor-scanning.cs | 3 +- .../Utilities/RepositoryFiles.cs | 3 +- .../BuildvanaConfigFactoryTests.cs | 75 +++++++------------ .../BuildvanaJsonConfigExampleTests.cs | 57 +++++--------- .../ConfigurationPageTests.cs | 6 +- .../RepositoryConfigFilesTests.cs | 3 +- .../ReporterExtensionsTests.cs | 6 +- .../ExceptionExtensionsTests.cs | 6 +- .../JsonKeyedObjectConverterTests.cs | 12 +-- .../JsonSchemaGeneratorTests.cs | 6 +- .../JsonSchemaValidatorTests.cs | 3 +- .../VersionCalculatorTests.cs | 3 +- .../VersioningSettingsTests.cs | 6 +- .../HookArgsSecretsTests.cs | 18 ++--- .../NuGetFeedConfigExtensionsTests.cs | 3 +- .../PostReleaseHookArgsTests.cs | 18 ++--- .../ThisAssemblyClassGeneratorTests.cs | 6 +- .../ComputeVersionTests.cs | 3 +- .../ConvertPfxToSnkTests.cs | 15 ++-- .../TaskLoggingHelperReporterTests.cs | 3 +- .../WritePackagePinDumpTests.cs | 30 +++----- .../WriteThisAssemblyConstantsFileTests.cs | 18 ++--- tests/Buildvana.Sdk.Tests/SdkPropsFixture.cs | 6 +- .../AdditionalGroupPinReaderTests.cs | 18 ++--- .../AdvisoryIndexTests.cs | 3 +- .../AppDirectiveEditorTests.cs | 6 +- .../ChangelogUpdaterTests.cs | 54 +++++-------- .../Buildvana.Tool.Tests/CommandPagesTests.cs | 3 +- .../DelegationServiceTests.cs | 6 +- .../DependencyDiscoveryTests.cs | 12 +-- .../DependencyReportRendererTests.cs | 14 ++-- .../DependencyResolutionTests.cs | 9 +-- .../DependencyScopeSelectionTests.cs | 6 +- .../DependencyUpdateReportTests.cs | 24 ++---- .../DotNetReleaseIndexTests.cs | 3 +- .../DotNetServicePushFeedTests.cs | 6 +- .../EffectivePolicyResolverTests.cs | 27 +++---- .../FakePackageVersionSource.cs | 3 +- .../FamilyPinUpdaterTests.cs | 18 ++--- .../FileBasedAppHelperTests.cs | 3 +- tests/Buildvana.Tool.Tests/GitServiceTests.cs | 6 +- tests/Buildvana.Tool.Tests/HookRunnerTests.cs | 12 +-- .../MsBuildPinEditorTests.cs | 3 +- .../NetSdkPinWriterTests.cs | 3 +- .../OrphanDetectorTests.cs | 6 +- .../OverrideLifecycleTests.cs | 24 ++---- .../OverrideSelectorTests.cs | 9 +-- .../PackagePinReaderTests.cs | 9 +-- .../PackagePinWriterTests.cs | 3 +- .../PackageVersionCatalogTests.cs | 3 +- .../PostUpdateHookArgsFactoryTests.cs | 15 ++-- .../ReleaseCommandChangelogTests.cs | 12 +-- .../ReleaseCommandFailureTests.cs | 3 +- .../ReleaseCommandReportingTests.cs | 6 +- .../ReleaseCommandTests.cs | 18 ++--- tests/Buildvana.Tool.Tests/ReleaseHarness.cs | 33 +++----- .../Buildvana.Tool.Tests/SdkPinWriterTests.cs | 3 +- .../SelfVersionServiceTests.cs | 12 +-- .../SolutionPinReaderTests.cs | 12 +-- .../ToolPinUpdaterTests.cs | 6 +- 127 files changed, 372 insertions(+), 740 deletions(-) diff --git a/src/Buildvana.Core.Abstractions/ConsoleOutput/MessageLevelExtensions.cs b/src/Buildvana.Core.Abstractions/ConsoleOutput/MessageLevelExtensions.cs index 5c198fe4..9ac5be6c 100644 --- a/src/Buildvana.Core.Abstractions/ConsoleOutput/MessageLevelExtensions.cs +++ b/src/Buildvana.Core.Abstractions/ConsoleOutput/MessageLevelExtensions.cs @@ -30,8 +30,7 @@ public static class MessageLevelExtensions /// public Verbosity MinimumVerbosity() { - return @this switch - { + return @this switch { MessageLevel.Error => Verbosity.Quiet, MessageLevel.Warning or MessageLevel.Notice => Verbosity.Minimal, MessageLevel.Info => Verbosity.Normal, diff --git a/src/Buildvana.Core.Abstractions/MSBuild/MSBuildBoolean.cs b/src/Buildvana.Core.Abstractions/MSBuild/MSBuildBoolean.cs index 8a934a88..4040309e 100644 --- a/src/Buildvana.Core.Abstractions/MSBuild/MSBuildBoolean.cs +++ b/src/Buildvana.Core.Abstractions/MSBuild/MSBuildBoolean.cs @@ -21,8 +21,7 @@ namespace Buildvana.Core.MSBuild; /// public static class MSBuildBoolean { - private static readonly FrozenDictionary Keywords = new Dictionary - { + private static readonly FrozenDictionary Keywords = new Dictionary { ["true"] = true, ["on"] = true, ["yes"] = true, diff --git a/src/Buildvana.Core.Configuration/BuildvanaConfigFactory.cs b/src/Buildvana.Core.Configuration/BuildvanaConfigFactory.cs index 0865fc89..a53c1a9a 100644 --- a/src/Buildvana.Core.Configuration/BuildvanaConfigFactory.cs +++ b/src/Buildvana.Core.Configuration/BuildvanaConfigFactory.cs @@ -31,8 +31,7 @@ public static class BuildvanaConfigFactory public static BuildvanaConfig Create(BuildvanaJsonConfig? json, CommandLineOverrides? commandLine) { var dotNet = ComposeDotNet(json?.DotNet, commandLine); - return new BuildvanaConfig - { + return new BuildvanaConfig { Release = ComposeRelease(json?.Release, commandLine, dotNet), Versioning = ComposeVersioning(json?.Versioning), DotNet = dotNet, @@ -55,8 +54,7 @@ private static DotNetConfig ComposeDotNet(DotNetJsonConfig? json, CommandLineOve var defaults = new DotNetConfig(); var all = ComposeInvocation(json?.All, common: null, forwardedArgs: null); var forwardedArgs = commandLine?.ForwardedArgs; - return new DotNetConfig - { + return new DotNetConfig { Configuration = NormalizeBlankToNull(commandLine?.Configuration) ?? NormalizeBlankToNull(json?.Configuration) ?? defaults.Configuration, @@ -73,8 +71,7 @@ private static DotNetInvocationConfig ComposeInvocation( DotNetInvocationJsonConfig? json, DotNetInvocationConfig? common, IReadOnlyList? forwardedArgs) - => new() - { + => new() { Args = [.. common?.Args ?? [], .. json?.Args ?? [], .. forwardedArgs ?? []], Env = ComposeEnv(common?.Env, json?.Env), }; @@ -107,8 +104,7 @@ private static ReleaseConfig ComposeRelease( DotNetConfig dotNet) { var defaults = new ReleaseConfig(); - return new ReleaseConfig - { + return new ReleaseConfig { Branches = json?.Branches ?? defaults.Branches, Configuration = NormalizeBlankToNull(commandLine?.Configuration) ?? NormalizeBlankToNull(json?.Configuration) @@ -126,8 +122,7 @@ private static ReleaseConfig ComposeRelease( private static VersioningConfig ComposeVersioning(VersioningJsonConfig? json) { var defaults = new VersioningConfig(); - return new VersioningConfig - { + return new VersioningConfig { // A blank tag could never appear in a version, so it counts as not stated: prereleases are // not allowed. PrereleaseTag = NormalizeBlankToNull(json?.PrereleaseTag), @@ -140,10 +135,8 @@ private static VersioningConfig ComposeVersioning(VersioningJsonConfig? json) private static NuGetConfig ComposeNuGet(NuGetJsonConfig? json) { var release = ComposeFeed(json?.Feeds?.Release); - return new NuGetConfig - { - Feeds = new NuGetFeedsConfig - { + return new NuGetConfig { + Feeds = new NuGetFeedsConfig { Prerelease = ComposeFeed(json?.Feeds?.Prerelease) ?? release, Release = release, }, @@ -155,8 +148,7 @@ private static NuGetConfig ComposeNuGet(NuGetJsonConfig? json) private static NuGetFeedConfig? ComposeFeed(NuGetFeedJsonConfig? json) => json is null ? null - : new NuGetFeedConfig - { + : new NuGetFeedConfig { Source = json.Source, ApiKeyEnv = json.ApiKeyEnv, }; @@ -165,8 +157,7 @@ private static NuGetConfig ComposeNuGet(NuGetJsonConfig? json) private static GitHubConfig ComposeGitHub(GitHubJsonConfig? json) { var defaults = new GitHubConfig(); - return new GitHubConfig - { + return new GitHubConfig { TokenEnv = NormalizeBlankToNull(json?.TokenEnv) ?? defaults.TokenEnv, }; } @@ -174,8 +165,7 @@ private static GitHubConfig ComposeGitHub(GitHubJsonConfig? json) // The schema requires name and email whenever git.identity is stated, and forbids blank values for // them, so a wire identity that reaches the factory carries both. private static GitConfig ComposeGit(GitJsonConfig? json) - => new() - { + => new() { Identity = json?.Identity is { } identity ? new GitIdentityConfig { Name = identity.Name, Email = identity.Email } : null, @@ -184,8 +174,7 @@ private static GitConfig ComposeGit(GitJsonConfig? json) private static DependenciesConfig ComposeDependencies(DependenciesJsonConfig? json) { var scopes = ComposeDependencyScopes(json?.Scopes); - return new DependenciesConfig - { + return new DependenciesConfig { Scopes = scopes, Policies = ComposePolicies(json?.Policies), AdditionalPackages = ComposeAdditionalPackages(json?.AdditionalPackages, scopes.Packages), @@ -195,8 +184,7 @@ private static DependenciesConfig ComposeDependencies(DependenciesJsonConfig? js private static DependencyScopesConfig ComposeDependencyScopes(DependencyScopesJsonConfig? json) { var defaults = new DependencyScopesConfig(); - return new DependencyScopesConfig - { + return new DependencyScopesConfig { NetSdk = NormalizeBlankToNull(json?.NetSdk) ?? defaults.NetSdk, Sdks = NormalizeBlankToNull(json?.Sdks) ?? defaults.Sdks, Tools = NormalizeBlankToNull(json?.Tools) ?? defaults.Tools, @@ -222,8 +210,7 @@ private static IReadOnlyList ComposeAdditionalPackages private static AdditionalPackagesConfig ComposeAdditionalPackageGroup( AdditionalPackagesJsonConfig json, string packagesPolicy) - => new() - { + => new() { Caption = json.Caption, Files = json.Files, Items = json.Items, diff --git a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigExample.cs b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigExample.cs index 668536c1..2ce8912a 100644 --- a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigExample.cs +++ b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigExample.cs @@ -54,8 +54,7 @@ public static class BuildvanaJsonConfigExample // The default encoder escapes characters that are only dangerous in HTML, turning a regular expression // into a wall of \u sequences. This file is read by people and copied into a configuration file, so a // value has to appear as it will be written there. - private static readonly JsonSerializerOptions ValueOptions = new() - { + private static readonly JsonSerializerOptions ValueOptions = new() { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, }; @@ -352,8 +351,7 @@ private static void WriteKeyedObject( // The last resort: a container with nothing to show still has a shape to show. Anything else is a setting // whose value the schema cannot supply, which is a missing annotation on the model. private static string EmptyContainer(JsonObject schema, string path) - => schema["type"]?.GetValue() switch - { + => schema["type"]?.GetValue() switch { "array" => "[]", "object" => "{}", _ => throw new InvalidOperationException( @@ -364,8 +362,7 @@ private static string EmptyContainer(JsonObject schema, string path) // A value stays on one line however long it is, the $schema URL included: wrapping it would put JSON on a // continuation line, where an editor and a reader would have to reassemble it. private static string FormatValue(JsonNode? value) - => value switch - { + => value switch { null => "null", JsonArray items => "[" + string.Join(", ", items.Select(FormatValue)) + "]", JsonObject members => "{" + string.Join(", ", members.Select(FormatMember)) + "}", diff --git a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigProvider.cs b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigProvider.cs index 27bcea3e..8c0dc5b4 100644 --- a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigProvider.cs +++ b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigProvider.cs @@ -29,8 +29,7 @@ namespace Buildvana.Core.Configuration; /// public sealed class BuildvanaJsonConfigProvider { - private static readonly JsonDocumentOptions DocumentOptions = new() - { + private static readonly JsonDocumentOptions DocumentOptions = new() { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, }; @@ -117,8 +116,7 @@ public static BuildvanaJsonConfig LoadFile(string? path) // holds, so no two callers can answer differently. private static string? FindFile(IHomeDirectoryProvider home) { - string[] candidatePaths = - [ + string[] candidatePaths = [ System.IO.Path.Combine(home.HomeDirectory, BuildvanaJsonConfig.JsonFileName), System.IO.Path.Combine(home.HomeDirectory, BuildvanaJsonConfig.JsoncFileName), ]; @@ -244,8 +242,7 @@ private static void Validate(JsonNode? node, JsonSourceMap sourceMap, string pat } private static string CodeFor(JsonSchemaErrorKind kind) - => kind switch - { + => kind switch { JsonSchemaErrorKind.TypeMismatch => DiagnosticCodes.TypeMismatch, JsonSchemaErrorKind.DisallowedValue => DiagnosticCodes.DisallowedValue, JsonSchemaErrorKind.UnknownProperty => DiagnosticCodes.UnknownProperty, diff --git a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSchema.cs b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSchema.cs index 1a2ddac8..9676257f 100644 --- a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSchema.cs +++ b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSchema.cs @@ -28,8 +28,7 @@ public static class BuildvanaJsonConfigSchema /// public static string Generate() { - var json = GenerateNode().ToJsonString(new JsonSerializerOptions - { + var json = GenerateNode().ToJsonString(new JsonSerializerOptions { WriteIndented = true, IndentCharacter = ' ', IndentSize = 2, diff --git a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSerialization.cs b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSerialization.cs index 7d97761b..e08754af 100644 --- a/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSerialization.cs +++ b/src/Buildvana.Core.Configuration/BuildvanaJsonConfigSerialization.cs @@ -34,8 +34,7 @@ public static class BuildvanaJsonConfigSerialization private static JsonSerializerOptions CreateOptions() { - var options = new JsonSerializerOptions - { + var options = new JsonSerializerOptions { // Required by JsonSchemaExporter, which validates the options before generating a schema. TypeInfoResolver = new DefaultJsonTypeInfoResolver(), PropertyNamingPolicy = JsonNamingPolicy.CamelCase, diff --git a/src/Buildvana.Core.ConsoleOutput/TextWriterReporter.cs b/src/Buildvana.Core.ConsoleOutput/TextWriterReporter.cs index 6ed86bac..678daa0f 100644 --- a/src/Buildvana.Core.ConsoleOutput/TextWriterReporter.cs +++ b/src/Buildvana.Core.ConsoleOutput/TextWriterReporter.cs @@ -129,8 +129,7 @@ public void ChildError(string line, Verbosity? minimumVerbosity) } } - private static (ConsoleColor? Color, string Word) StyleFor(MessageLevel level) => level switch - { + private static (ConsoleColor? Color, string Word) StyleFor(MessageLevel level) => level switch { MessageLevel.Error => (ConsoleColor.Red, "error"), MessageLevel.Warning => (ConsoleColor.Yellow, "warning"), MessageLevel.Notice => (null, "notice"), diff --git a/src/Buildvana.Core.IO/CaseSensitivityModeExtensions.cs b/src/Buildvana.Core.IO/CaseSensitivityModeExtensions.cs index 20793607..18c43800 100644 --- a/src/Buildvana.Core.IO/CaseSensitivityModeExtensions.cs +++ b/src/Buildvana.Core.IO/CaseSensitivityModeExtensions.cs @@ -28,8 +28,7 @@ public static class CaseSensitivityModeExtensions /// public bool IgnoresCase() { - return @this switch - { + return @this switch { CaseSensitivityMode.SystemDefault => OperatingSystem.IsWindows() || OperatingSystem.IsMacOS(), CaseSensitivityMode.CaseSensitive => false, CaseSensitivityMode.CaseInsensitive => true, diff --git a/src/Buildvana.Core.IO/Gitignore/GitignoreCharClass.cs b/src/Buildvana.Core.IO/Gitignore/GitignoreCharClass.cs index fc0677d5..12ea76e7 100644 --- a/src/Buildvana.Core.IO/Gitignore/GitignoreCharClass.cs +++ b/src/Buildvana.Core.IO/Gitignore/GitignoreCharClass.cs @@ -66,8 +66,7 @@ public bool Matches(char c, bool ignoreCase) return IsNegated ? !isInSet : isInSet; } - private static bool MatchesNamedClass(GitignoreNamedClass namedClass, char c) => namedClass switch - { + private static bool MatchesNamedClass(GitignoreNamedClass namedClass, char c) => namedClass switch { GitignoreNamedClass.Alnum => char.IsAsciiLetterOrDigit(c), GitignoreNamedClass.Alpha => char.IsAsciiLetter(c), GitignoreNamedClass.Blank => c is ' ' or '\t', diff --git a/src/Buildvana.Core.IO/Gitignore/GitignorePattern-matching.cs b/src/Buildvana.Core.IO/Gitignore/GitignorePattern-matching.cs index 3c66e0a4..1ee0445c 100644 --- a/src/Buildvana.Core.IO/Gitignore/GitignorePattern-matching.cs +++ b/src/Buildvana.Core.IO/Gitignore/GitignorePattern-matching.cs @@ -134,8 +134,7 @@ private static bool MatchTokens( return tokenIndex == tokens.Length; } - private static bool MatchesChar(GitignoreToken token, char c, bool ignoreCase) => token.Kind switch - { + private static bool MatchesChar(GitignoreToken token, char c, bool ignoreCase) => token.Kind switch { GitignoreTokenKind.Literal => CharsEqual(token.Value, c, ignoreCase), GitignoreTokenKind.AnyChar => true, GitignoreTokenKind.CharClass => token.CharClass!.Matches(c, ignoreCase), diff --git a/src/Buildvana.Core.IO/Gitignore/GitignorePattern-parsing.cs b/src/Buildvana.Core.IO/Gitignore/GitignorePattern-parsing.cs index 9b2e9767..2abcc85a 100644 --- a/src/Buildvana.Core.IO/Gitignore/GitignorePattern-parsing.cs +++ b/src/Buildvana.Core.IO/Gitignore/GitignorePattern-parsing.cs @@ -315,8 +315,7 @@ private static bool TryParseNamedClass( return true; } - private static GitignoreNamedClass? GetNamedClass(string name) => name switch - { + private static GitignoreNamedClass? GetNamedClass(string name) => name switch { "alnum" => GitignoreNamedClass.Alnum, "alpha" => GitignoreNamedClass.Alpha, "blank" => GitignoreNamedClass.Blank, diff --git a/src/Buildvana.Core.Json/JsonHelper-InsertProperty.cs b/src/Buildvana.Core.Json/JsonHelper-InsertProperty.cs index 71641e8d..3fed62b9 100644 --- a/src/Buildvana.Core.Json/JsonHelper-InsertProperty.cs +++ b/src/Buildvana.Core.Json/JsonHelper-InsertProperty.cs @@ -65,8 +65,7 @@ private static bool TryLocateInsertion( { var reader = new Utf8JsonReader( originalBytes.AsSpan(bomLength), - new JsonReaderOptions - { + new JsonReaderOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip, }); @@ -268,8 +267,7 @@ private static byte[] Splice(byte[] bytes, int replaceStart, int replaceLength, private static string SerializeValue(JsonNode value, string newline, string indent) { - var text = value.ToJsonString(new JsonSerializerOptions - { + var text = value.ToJsonString(new JsonSerializerOptions { WriteIndented = true, NewLine = newline, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, diff --git a/src/Buildvana.Core.Json/JsonHelper.cs b/src/Buildvana.Core.Json/JsonHelper.cs index 4b6e6990..9281d295 100644 --- a/src/Buildvana.Core.Json/JsonHelper.cs +++ b/src/Buildvana.Core.Json/JsonHelper.cs @@ -31,8 +31,7 @@ public JsonObject ParseObject(string str, string description = "The provided str node = JsonNode.Parse( str, new JsonNodeOptions { PropertyNameCaseInsensitive = false }, - new JsonDocumentOptions - { + new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip, }); @@ -61,8 +60,7 @@ public JsonObject LoadObject(string path) node = JsonNode.Parse( stream, new JsonNodeOptions { PropertyNameCaseInsensitive = false }, - new JsonDocumentOptions - { + new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip, }); @@ -89,8 +87,7 @@ public void SaveObject(JsonNode json, string path) Guard.IsNotNull(json); Guard.IsNotNullOrEmpty(path); - var writerOptions = new JsonWriterOptions - { + var writerOptions = new JsonWriterOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, Indented = true, }; @@ -199,8 +196,7 @@ private static List CollectValueEdits( { var reader = new Utf8JsonReader( jsonSpan, - new JsonReaderOptions - { + new JsonReaderOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip, }); diff --git a/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator-KeyedObjects.cs b/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator-KeyedObjects.cs index 176f2906..a25ee25a 100644 --- a/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator-KeyedObjects.cs +++ b/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator-KeyedObjects.cs @@ -55,8 +55,7 @@ private static JsonObject CreateKeyedObjectSchema( ? LiftValueSchema(elementProperties, elementType, valueJsonName) : PruneKeyProperty(elementSchema, elementProperties, keyJsonName); ThrowIfContainsReference(elementType, valuesSchema); - var keyedSchema = new JsonObject - { + var keyedSchema = new JsonObject { ["type"] = "object", ["additionalProperties"] = valuesSchema, }; diff --git a/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator.cs b/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator.cs index 68c295fb..40437f1a 100644 --- a/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator.cs +++ b/src/Buildvana.Core.Json/Schema/JsonSchemaGenerator.cs @@ -130,8 +130,7 @@ private static JsonNode ExportSchema( NullabilityInfoContext nullabilityContext, HashSet keyedTypesInProgress) { - var exporterOptions = new JsonSchemaExporterOptions - { + var exporterOptions = new JsonSchemaExporterOptions { TransformSchemaNode = (context, schema) => TransformSchemaNode(context, schema, nullabilityContext, keyedTypesInProgress), }; @@ -291,16 +290,14 @@ private static void RequireNonBlankString(JsonObject schema) private static bool SchemaTypeIncludesNull(JsonObject schema) => SchemaTypeIncludes(schema, "null"); private static bool SchemaTypeIncludes(JsonObject schema, string typeName) - => schema["type"] switch - { + => schema["type"] switch { JsonValue value => value.GetValue() == typeName, JsonArray array => array.Any(t => t?.GetValue() == typeName), _ => false, }; private static NullabilityInfo? CreateNullabilityInfo(NullabilityInfoContext context, MemberInfo member) - => member switch - { + => member switch { PropertyInfo property => context.Create(property), FieldInfo field => context.Create(field), _ => null, diff --git a/src/Buildvana.Core.Json/Schema/JsonSchemaValidator.cs b/src/Buildvana.Core.Json/Schema/JsonSchemaValidator.cs index ee6e84c7..e4497074 100644 --- a/src/Buildvana.Core.Json/Schema/JsonSchemaValidator.cs +++ b/src/Buildvana.Core.Json/Schema/JsonSchemaValidator.cs @@ -205,8 +205,7 @@ private static JsonNode ResolveReference(JsonNode root, string reference) .Replace("~1", "/", StringComparison.Ordinal) .Replace("~0", "~", StringComparison.Ordinal); - var next = current switch - { + var next = current switch { JsonObject obj => obj[token], JsonArray array when int.TryParse(token, NumberStyles.None, CultureInfo.InvariantCulture, out var index) && index < array.Count => array[index], @@ -441,8 +440,7 @@ private static void ValidateArray( private static bool TypeMatches(JsonNode? instance, string type) { var kind = instance?.GetValueKind() ?? JsonValueKind.Null; - return type switch - { + return type switch { "null" => kind is JsonValueKind.Null, "boolean" => kind is JsonValueKind.True or JsonValueKind.False, "object" => kind is JsonValueKind.Object, @@ -466,8 +464,7 @@ private static bool IsIntegral(JsonNode instance) } private static string ActualType(JsonNode? instance) - => (instance?.GetValueKind() ?? JsonValueKind.Null) switch - { + => (instance?.GetValueKind() ?? JsonValueKind.Null) switch { JsonValueKind.Null => "null", JsonValueKind.True or JsonValueKind.False => "boolean", JsonValueKind.Object => "object", diff --git a/src/Buildvana.Core.Json/Schema/JsonSourceMap.cs b/src/Buildvana.Core.Json/Schema/JsonSourceMap.cs index 6f0b2265..cb8d5d67 100644 --- a/src/Buildvana.Core.Json/Schema/JsonSourceMap.cs +++ b/src/Buildvana.Core.Json/Schema/JsonSourceMap.cs @@ -56,8 +56,7 @@ public static JsonSourceMap Build(ReadOnlySpan utf8Json) var lineStarts = BuildLineStarts(utf8Json); var reader = new Utf8JsonReader( utf8Json, - new JsonReaderOptions - { + new JsonReaderOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, }); diff --git a/src/Buildvana.Core.Testing/TempGitRepo.cs b/src/Buildvana.Core.Testing/TempGitRepo.cs index 5941a60e..b95b4abb 100644 --- a/src/Buildvana.Core.Testing/TempGitRepo.cs +++ b/src/Buildvana.Core.Testing/TempGitRepo.cs @@ -52,8 +52,7 @@ static TempGitRepo() // the process may still open one: changing them again is the race this type initializer exists to // avoid. Process exit is therefore the first moment the directory can go, and the last one at which // anything of ours still runs to delete it. - AppDomain.CurrentDomain.ProcessExit += (_, _) => - { + AppDomain.CurrentDomain.ProcessExit += (_, _) => { try { Directory.Delete(path, recursive: true); @@ -200,8 +199,7 @@ public void CreateTag(string name) public IReadOnlyList GetCommits(int count) { using var repository = new Repository(RootPath); - var filter = new CommitFilter - { + var filter = new CommitFilter { IncludeReachableFrom = repository.Head, SortBy = CommitSortStrategies.Topological, }; diff --git a/src/Buildvana.Core.Versioning/VersionSpecExtensions.cs b/src/Buildvana.Core.Versioning/VersionSpecExtensions.cs index 3f4a9b3c..d5f8b630 100644 --- a/src/Buildvana.Core.Versioning/VersionSpecExtensions.cs +++ b/src/Buildvana.Core.Versioning/VersionSpecExtensions.cs @@ -115,8 +115,7 @@ public static bool TryParse([NotNullWhen(true)] string? str, [MaybeNullWhen(fals /// A constant representing the kind of change to apply. /// A tuple of the result of applying to this instance, and a /// value indicating whether the result differs from this instance. - public (VersionSpec Result, bool Changed) ApplyChange(VersionSpecChange change) => change switch - { + public (VersionSpec Result, bool Changed) ApplyChange(VersionSpecChange change) => change switch { VersionSpecChange.Unstable => @this.Prerelease ? (@this, false) : (@this.Unstable(), true), VersionSpecChange.Stable => @this.Prerelease ? (@this.Stable(), true) : (@this, false), VersionSpecChange.Minor => (@this.NextMinor(), true), diff --git a/src/Buildvana.Sdk.SourceGenerators/AdditionalAssemblyInfoGenerator.cs b/src/Buildvana.Sdk.SourceGenerators/AdditionalAssemblyInfoGenerator.cs index 5998aac8..4f764e87 100644 --- a/src/Buildvana.Sdk.SourceGenerators/AdditionalAssemblyInfoGenerator.cs +++ b/src/Buildvana.Sdk.SourceGenerators/AdditionalAssemblyInfoGenerator.cs @@ -23,8 +23,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) p.GetBooleanMSBuildProperty("CLSCompliant"), p.GetBooleanMSBuildProperty("ComVisible"))); - context.RegisterSourceOutput(attributeValuesProvider, static (spc, values) => - { + context.RegisterSourceOutput(attributeValuesProvider, static (spc, values) => { var sb = new StringBuilder() .AppendAutoGenerated() .AppendBooleanAssemblyAttribute("System.CLSCompliant", values.CLSCompliant) diff --git a/src/Buildvana.Sdk.SourceGenerators/Internal/ConstantValueParser.cs b/src/Buildvana.Sdk.SourceGenerators/Internal/ConstantValueParser.cs index 480b47bc..55c0050f 100644 --- a/src/Buildvana.Sdk.SourceGenerators/Internal/ConstantValueParser.cs +++ b/src/Buildvana.Sdk.SourceGenerators/Internal/ConstantValueParser.cs @@ -15,8 +15,7 @@ namespace Buildvana.Sdk.SourceGenerators.Internal; /// internal static class ConstantValueParser { - private static readonly Dictionary AllowedTypes = new(StringComparer.OrdinalIgnoreCase) - { + private static readonly Dictionary AllowedTypes = new(StringComparer.OrdinalIgnoreCase) { ["System.Byte"] = typeof(byte), ["byte"] = typeof(byte), ["uint8"] = typeof(byte), diff --git a/src/Buildvana.Sdk.SourceGenerators/ThisAssemblyClassGenerator.cs b/src/Buildvana.Sdk.SourceGenerators/ThisAssemblyClassGenerator.cs index b69873e4..2df91ea4 100644 --- a/src/Buildvana.Sdk.SourceGenerators/ThisAssemblyClassGenerator.cs +++ b/src/Buildvana.Sdk.SourceGenerators/ThisAssemblyClassGenerator.cs @@ -45,8 +45,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) Namespace: p.GetMSBuildProperty("ThisAssemblyClassNamespace"))); var finalProvider = constantsTextsProvider.Combine(optionsProvider); - context.RegisterSourceOutput(finalProvider, static (spc, data) => - { + context.RegisterSourceOutput(finalProvider, static (spc, data) => { var (constantsTexts, options) = data; GenerateThisAssemblyClass(spc, constantsTexts, options.ClassName, options.Namespace); }); diff --git a/src/Buildvana.Sdk.Tasks/Internal/JetBrainsAnnotationsExporter.cs b/src/Buildvana.Sdk.Tasks/Internal/JetBrainsAnnotationsExporter.cs index 86808651..0a2a6e6e 100644 --- a/src/Buildvana.Sdk.Tasks/Internal/JetBrainsAnnotationsExporter.cs +++ b/src/Buildvana.Sdk.Tasks/Internal/JetBrainsAnnotationsExporter.cs @@ -24,8 +24,7 @@ internal static class JetBrainsAnnotationsExporter private const string JetBrainsAnnotationsNamespace = "JetBrains.Annotations"; // Attributes that ReSharper does not read from external-annotation files. - private static readonly string[] NonExportableAttributeNames = - [ + private static readonly string[] NonExportableAttributeNames = [ "AspMvcSuppressViewErrorAttribute", "LocalizationRequiredAttribute", "MeansImplicitUseAttribute", @@ -165,8 +164,7 @@ private static IEnumerable TypeToXml(INamedTypeSymbol type) } private static XElement? MemberToXml(ISymbol member) - => member switch - { + => member switch { IMethodSymbol method => BuildMember( method, [.. GetAnnotations(method), .. GetTypeParameters(method.TypeParameters), .. GetParameters(method.Parameters)]), @@ -251,8 +249,7 @@ private static string FormatArgument(TypedConstant argument) return (argument.Value as ITypeSymbol)?.ToDisplayString() ?? string.Empty; } - return argument.Value switch - { + return argument.Value switch { null => string.Empty, bool boolean => boolean ? bool.TrueString : bool.FalseString, string text => text, diff --git a/src/Buildvana.Sdk.Tasks/TaskLoggingHelperLogger.cs b/src/Buildvana.Sdk.Tasks/TaskLoggingHelperLogger.cs index 613d3449..ed1e3efb 100644 --- a/src/Buildvana.Sdk.Tasks/TaskLoggingHelperLogger.cs +++ b/src/Buildvana.Sdk.Tasks/TaskLoggingHelperLogger.cs @@ -32,8 +32,7 @@ public IDisposable BeginScope(TState state) where TState : notnull => NullLogger.Instance.BeginScope(state); - public bool IsEnabled(LogLevel logLevel) => logLevel switch - { + public bool IsEnabled(LogLevel logLevel) => logLevel switch { LogLevel.Trace or LogLevel.Debug => LogsMessagesOfImportance(MessageImportance.Low), LogLevel.Information => LogsMessagesOfImportance(MessageImportance.Normal), LogLevel.Warning => true, diff --git a/src/Buildvana.Sdk.Tasks/Tasks/ComputeVersion-caching.cs b/src/Buildvana.Sdk.Tasks/Tasks/ComputeVersion-caching.cs index 16455928..d2ed0b87 100644 --- a/src/Buildvana.Sdk.Tasks/Tasks/ComputeVersion-caching.cs +++ b/src/Buildvana.Sdk.Tasks/Tasks/ComputeVersion-caching.cs @@ -73,8 +73,7 @@ private static CachedVersion ComputeCore(string homeDirectory, IReporter reporte return null; } - string?[] parts = - [ + string?[] parts = [ repositoryStateToken, File.ReadAllText(versionPath), ReadOptionalFile(Path.Combine(homeDirectory, BuildvanaJsonConfig.JsonFileName)), diff --git a/src/Buildvana.Sdk.Tasks/Tasks/WritePackagePinDump.cs b/src/Buildvana.Sdk.Tasks/Tasks/WritePackagePinDump.cs index fa80b510..12e52566 100644 --- a/src/Buildvana.Sdk.Tasks/Tasks/WritePackagePinDump.cs +++ b/src/Buildvana.Sdk.Tasks/Tasks/WritePackagePinDump.cs @@ -60,8 +60,7 @@ protected override Undefined Run() AddItems(items, "PackageVersion", PackageVersions); AddItems(items, "GlobalPackageReference", GlobalPackageReferences); AddItems(items, "PackageReference", PackageReferences); - var dump = new PackagePinDump - { + var dump = new PackagePinDump { ProjectFullPath = ProjectFullPath, TargetFramework = NullIfEmpty(TargetFramework), ManagePackageVersionsCentrally = ManagePackageVersionsCentrally, @@ -85,8 +84,7 @@ private static void AddItems(List items, string itemType, IT { foreach (var taskItem in taskItems) { - items.Add(new PackagePinDumpItem - { + items.Add(new PackagePinDumpItem { ItemType = itemType, Id = taskItem.ItemSpec, Version = NullIfEmpty(taskItem.GetMetadata("Version")), diff --git a/src/Buildvana.Tool/Build/BuildPipeline.cs b/src/Buildvana.Tool/Build/BuildPipeline.cs index 10b15ed0..d118fa3c 100644 --- a/src/Buildvana.Tool/Build/BuildPipeline.cs +++ b/src/Buildvana.Tool/Build/BuildPipeline.cs @@ -112,8 +112,7 @@ public async Task RunAsync( configuration ??= _config.DotNet.Configuration; Guard.IsNotNullOrEmpty(configuration); using var activity = _reporter.BeginActivity(step.ToString()); - var task = step switch - { + var task = step switch { BuildStep.Clean => CleanAsync(cancellationToken), BuildStep.Restore => RestoreAsync(cancellationToken), BuildStep.Build => BuildAsync(configuration, cancellationToken), diff --git a/src/Buildvana.Tool/CommandLine/CommandLineOverridesParser.cs b/src/Buildvana.Tool/CommandLine/CommandLineOverridesParser.cs index 360273d8..ff2a591f 100644 --- a/src/Buildvana.Tool/CommandLine/CommandLineOverridesParser.cs +++ b/src/Buildvana.Tool/CommandLine/CommandLineOverridesParser.cs @@ -38,8 +38,7 @@ public static CommandLineOverrides Parse(CommandParameters parameters) // compose, so the stream is stripped even when bv's own option surface supplies the configuration. var forwardedReader = new CliOptionReader(parameters.Forwarded); var forwardedConfiguration = forwardedReader.ReadValue("--configuration", "-c"); - return new CommandLineOverrides - { + return new CommandLineOverrides { Configuration = reader.ReadValue("--configuration", "-c") ?? forwardedConfiguration, CheckPublicApi = reader.ReadBoolValue("--check-public-api"), Dogfood = reader.ReadBoolValue("--dogfood"), diff --git a/src/Buildvana.Tool/CommandLine/VerbosityParser.cs b/src/Buildvana.Tool/CommandLine/VerbosityParser.cs index 01587663..c9dc41b8 100644 --- a/src/Buildvana.Tool/CommandLine/VerbosityParser.cs +++ b/src/Buildvana.Tool/CommandLine/VerbosityParser.cs @@ -23,8 +23,7 @@ internal static class VerbosityParser public static Verbosity Parse(string raw) { Guard.IsNotNull(raw); - return raw.ToUpperInvariant() switch - { + return raw.ToUpperInvariant() switch { "QUIET" or "Q" => Verbosity.Quiet, "MINIMAL" or "M" => Verbosity.Minimal, "NORMAL" or "N" => Verbosity.Normal, diff --git a/src/Buildvana.Tool/Infrastructure/Execution/CommandRegistry.cs b/src/Buildvana.Tool/Infrastructure/Execution/CommandRegistry.cs index 02c3ceac..10ef6df4 100644 --- a/src/Buildvana.Tool/Infrastructure/Execution/CommandRegistry.cs +++ b/src/Buildvana.Tool/Infrastructure/Execution/CommandRegistry.cs @@ -31,8 +31,7 @@ internal static class CommandRegistry // Descriptions for tree nodes whose own command description does not fit the node (or that have no command // at all), keyed by full node path. Typically command-group nodes: a group aliased onto one of its // subcommands would otherwise inherit that subcommand's description. - private static readonly Dictionary NodeDescriptions = new(StringComparer.OrdinalIgnoreCase) - { + private static readonly Dictionary NodeDescriptions = new(StringComparer.OrdinalIgnoreCase) { ["dependencies"] = "Show and manage the repository's dependencies.", ["version"] = "Show or advance the project's version spec.", }; diff --git a/src/Buildvana.Tool/Program.cs b/src/Buildvana.Tool/Program.cs index 1c68c5b5..03995372 100644 --- a/src/Buildvana.Tool/Program.cs +++ b/src/Buildvana.Tool/Program.cs @@ -113,8 +113,7 @@ public static async Task Main(string[] args) var verbosity = globals.Verbosity is null ? DefaultVerbosity : VerbosityParser.Parse(globals.Verbosity); // --color / --no-color win over auto-detection; neither (or both) leaves the reporter to auto-detect. - bool? colorOverride = (globals.Color, globals.NoColor) switch - { + bool? colorOverride = (globals.Color, globals.NoColor) switch { (true, false) => true, (false, true) => false, _ => null, diff --git a/src/Buildvana.Tool/Services/Dependencies/AdditionalGroupPinReader.cs b/src/Buildvana.Tool/Services/Dependencies/AdditionalGroupPinReader.cs index 4ce16155..23430186 100644 --- a/src/Buildvana.Tool/Services/Dependencies/AdditionalGroupPinReader.cs +++ b/src/Buildvana.Tool/Services/Dependencies/AdditionalGroupPinReader.cs @@ -137,8 +137,7 @@ private async Task ReadFileAsync( return null; } - var pin = DependencyPin.Create(DependencyScope.Packages, id, versionText, declaringRelativePath) with - { + var pin = DependencyPin.Create(DependencyScope.Packages, id, versionText, declaringRelativePath) with { ItemType = group.Items, MetadataPolicy = ReadMetadata(item, "UpdatePolicy"), GroupCaption = group.Caption, diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyDiscovery.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyDiscovery.cs index 3a18298e..45b2a863 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyDiscovery.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyDiscovery.cs @@ -55,8 +55,7 @@ public async Task DiscoverAsync( ? await ReadPackagesAsync(directivePins.Pins, cancellationToken).ConfigureAwait(false) : ([], []); - return new DependencyInventory - { + return new DependencyInventory { NetSdk = scopes.Contains(DependencyScope.NetSdk) ? globalJsonPins.NetSdk : null, Sdks = wantsSdks ? [.. globalJsonPins.Sdks, .. OfScope(directivePins.Pins, DependencyScope.Sdks)] : [], Tools = scopes.Contains(DependencyScope.Tools) ? tools.Read() : [], @@ -95,8 +94,7 @@ private static IEnumerable WithoutDuplicates( var dumps = await solutionPins.ReadAsync(projectPaths, cancellationToken).ConfigureAwait(false); var solutionPackagePins = packages.Read(dumps); var groupPins = await groups.ReadAsync(cancellationToken).ConfigureAwait(false); - IReadOnlyList pins = - [ + IReadOnlyList pins = [ .. solutionPackagePins, .. WithoutDuplicates(groupPins, solutionPackagePins), .. OfScope(directivePins, DependencyScope.Packages), diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyPin.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyPin.cs index fd319a6b..1f6e7262 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyPin.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyPin.cs @@ -78,8 +78,7 @@ internal sealed record DependencyPin public static DependencyPin Create(DependencyScope scope, string id, string versionText, string declaringFile) { var management = PinVersion.Read(versionText, out var version); - return new DependencyPin - { + return new DependencyPin { Scope = scope, Id = id, VersionText = versionText.Trim(), diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyReportRenderer.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyReportRenderer.cs index d083a275..f310e2a0 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyReportRenderer.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyReportRenderer.cs @@ -170,8 +170,7 @@ private static string UpdateLineOfNetSdk(NetSdkResolution resolution) // What the arrow points at: the version a pin moves to, or the words that say why it moves nowhere. The // last state is Held, which is resolution finding nothing the policy allows. private static string Outcome(PinResolutionState state, NuGetVersion? target) - => state switch - { + => state switch { PinResolutionState.Updated => VersionText(target), PinResolutionState.UpToDate => "up to date", PinResolutionState.Disabled => "disabled", @@ -182,8 +181,7 @@ private static string Outcome(PinResolutionState state, NuGetVersion? target) // What the sources have beyond the pin, stable first, and nothing at all where they have nothing to add. private static string Latest(NuGetVersion? stable, NuGetVersion? preview) - => (stable, preview) switch - { + => (stable, preview) switch { (null, null) => string.Empty, (not null, null) => $" (latest: {VersionText(stable)})", (null, not null) => $" (latest: {VersionText(preview)})", @@ -193,8 +191,7 @@ private static string Latest(NuGetVersion? stable, NuGetVersion? preview) private static string VersionText(NuGetVersion? version) => version?.ToNormalizedString() ?? string.Empty; private static string Pins(int count) - => count switch - { + => count switch { 0 => "No pin", 1 => "1 pin", _ => $"{count} pins", diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs index 13664731..c9dd7893 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs @@ -62,8 +62,7 @@ public static DependencyResolution Skipping( Guard.IsNotNull(policies); Guard.IsNotNull(removed); var gone = new HashSet(removed); - return new DependencyResolution - { + return new DependencyResolution { NetSdk = inventory.NetSdk is { } netSdk ? Skipping(netSdk, policies) : null, Sdks = Skipping(inventory.Sdks, policies), Tools = Skipping(inventory.Tools, policies), @@ -72,8 +71,7 @@ public static DependencyResolution Skipping( } private static NetSdkResolution Skipping(NetSdkPin pin, EffectivePolicyResolver policies) - => new() - { + => new() { Pin = pin, Policy = policies.ResolveNetSdk(), State = PinResolutionState.Skipped, @@ -83,8 +81,7 @@ private static NetSdkResolution Skipping(NetSdkPin pin, EffectivePolicyResolver private static IReadOnlyList Skipping( IEnumerable pins, EffectivePolicyResolver policies) - => [.. pins.Select(pin => new PinResolution - { + => [.. pins.Select(pin => new PinResolution { Pin = pin, Policy = policies.Resolve(pin), State = PinResolutionState.Skipped, diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyResolver.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyResolver.cs index 623bc3b0..fbe17f77 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyResolver.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyResolver.cs @@ -54,8 +54,7 @@ public async Task ResolveAsync( var sdks = await ResolveAllAsync(inventory.Sdks, request, errors, cancellationToken).ConfigureAwait(false); var tools = await ResolveAllAsync(inventory.Tools, request, errors, cancellationToken).ConfigureAwait(false); var packages = await ResolveAllAsync(inventory.Packages, request, errors, cancellationToken).ConfigureAwait(false); - var resolution = new DependencyResolution - { + var resolution = new DependencyResolution { NetSdk = netSdk, Sdks = sdks, Tools = tools, @@ -101,8 +100,7 @@ private static void EnsureStatedVersionHasAPin( } private static PinResolutionState StateOf(TargetSelectionOutcome outcome) - => outcome switch - { + => outcome switch { TargetSelectionOutcome.Update => PinResolutionState.Updated, TargetSelectionOutcome.UpToDate => PinResolutionState.UpToDate, TargetSelectionOutcome.Disabled => PinResolutionState.Disabled, @@ -110,8 +108,7 @@ private static PinResolutionState StateOf(TargetSelectionOutcome outcome) }; private static PinResolution NewResolution(DependencyPin pin, PackageUpdatePolicy policy, PinResolutionState state, string note) - => new() - { + => new() { Pin = pin, Policy = policy, State = state, @@ -124,8 +121,7 @@ private static NetSdkResolution NewNetSdkResolution( PinResolutionState state, bool writesAllowPrerelease, string note) - => new() - { + => new() { Pin = pin, Policy = policy, State = state, @@ -206,8 +202,7 @@ private async Task ResolvePinAsync( // A delisted pin is resolved like any other. Delisting often means the version is vulnerable, so // moving away from it is the remedy, and refusing to would be perverse. var selection = UpdatePolicyEngine.Select(current, catalog.Listed, window); - return new PinResolution - { + return new PinResolution { Pin = pin, Policy = policy, State = StateOf(selection.Outcome), @@ -259,8 +254,7 @@ private async Task ResolveNetSdkAsync( } var selection = UpdatePolicyEngine.Select(current, releases, window); - return new NetSdkResolution - { + return new NetSdkResolution { Pin = pin, Policy = policy, State = StateOf(selection.Outcome), diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyScopeNames.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyScopeNames.cs index 18dffb5f..c2324ecb 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyScopeNames.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyScopeNames.cs @@ -30,8 +30,7 @@ internal static class DependencyScopeNames /// The scope's name. /// is not a scope. public static string Of(DependencyScope scope) - => scope switch - { + => scope switch { DependencyScope.NetSdk => NetSdk, DependencyScope.Sdks => Sdks, DependencyScope.Tools => Tools, diff --git a/src/Buildvana.Tool/Services/Dependencies/EffectivePolicyResolver.cs b/src/Buildvana.Tool/Services/Dependencies/EffectivePolicyResolver.cs index fac33831..750a342a 100644 --- a/src/Buildvana.Tool/Services/Dependencies/EffectivePolicyResolver.cs +++ b/src/Buildvana.Tool/Services/Dependencies/EffectivePolicyResolver.cs @@ -117,8 +117,7 @@ private static PackageUpdatePolicy Parse(string text) => pin.GroupCaption is { } caption && _groupPolicies.TryGetValue(caption, out var policy) ? policy : null; private string ScopeDefault(DependencyScope scope) - => scope switch - { + => scope switch { DependencyScope.Sdks => _config.Scopes.Sdks, DependencyScope.Tools => _config.Scopes.Tools, _ => _config.Scopes.Packages, diff --git a/src/Buildvana.Tool/Services/Dependencies/NetSdkPin.cs b/src/Buildvana.Tool/Services/Dependencies/NetSdkPin.cs index 365277a8..cdecf386 100644 --- a/src/Buildvana.Tool/Services/Dependencies/NetSdkPin.cs +++ b/src/Buildvana.Tool/Services/Dependencies/NetSdkPin.cs @@ -43,8 +43,7 @@ internal sealed record NetSdkPin public static NetSdkPin Create(string versionText, bool? allowPrerelease) { var management = PinVersion.Read(versionText, out var version); - return new NetSdkPin - { + return new NetSdkPin { VersionText = versionText, Management = management, Version = version, diff --git a/src/Buildvana.Tool/Services/Dependencies/NuGetReporterLogger.cs b/src/Buildvana.Tool/Services/Dependencies/NuGetReporterLogger.cs index 2fed1f14..04163cb6 100644 --- a/src/Buildvana.Tool/Services/Dependencies/NuGetReporterLogger.cs +++ b/src/Buildvana.Tool/Services/Dependencies/NuGetReporterLogger.cs @@ -64,8 +64,7 @@ public Task LogAsync(ILogMessage message) } private static MessageLevel LevelOf(LogLevel level) - => level switch - { + => level switch { LogLevel.Error => MessageLevel.Error, LogLevel.Warning => MessageLevel.Warning, LogLevel.Debug => MessageLevel.Trace, diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs index aaa78ac0..96f611fc 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs @@ -57,11 +57,9 @@ public void AddPromotion(string projectFullPath, string packageId, NuGetVersion? // Every project of the solution is in the plan, including the ones with nothing to promote: that is // what removes a file an earlier run left behind. public TransitiveOverridePlan ToPlan(IReadOnlyList projects) - => new() - { + => new() { Central = [.. _central.Select(static entry => new PackageOverride(entry.Key, entry.Value))], - Projects = [.. projects.Select(project => new ProjectOverrides - { + Projects = [.. projects.Select(project => new ProjectOverrides { ProjectFullPath = project.ProjectFullPath, Promotions = PromotionsOf(project.ProjectFullPath), })], diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.cs index 90e15488..23911124 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.cs @@ -143,8 +143,7 @@ private async Task> DecideAsync( foreach (var (packageId, resolved) in FindingsOf(projectAssets)) { var known = await versions.GetVersionsAsync(packageId, cancellationToken).ConfigureAwait(false); - var request = new OverrideRequest - { + var request = new OverrideRequest { ResolvedVersion = resolved, Candidates = known.Listed, Advisories = advisories.For(packageId), diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideProject.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideProject.cs index 65a245d8..fcbd8a62 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideProject.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideProject.cs @@ -63,8 +63,7 @@ public static IReadOnlyList Create( Guard.IsNotNull(removed); var moved = MovedCentralPins(packages); var gone = RemovedCentralPins(removed); - return - [ + return [ .. evaluations .Where(static dump => !string.IsNullOrEmpty(dump.ProjectAssetsFile)) .GroupBy(static dump => dump.ProjectFullPath, StringComparer.OrdinalIgnoreCase) @@ -129,8 +128,7 @@ private static OverrideProject Fold( AddCentralPins(home, centralPins, evaluation, moved, gone); } - return new OverrideProject - { + return new OverrideProject { ProjectFullPath = evaluations.Key, AssetsFilePath = evaluations.First().ProjectAssetsFile!, AuditLevel = auditLevel, diff --git a/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs b/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs index 5d262c7d..0ba52951 100644 --- a/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs +++ b/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs @@ -100,8 +100,7 @@ private void AddPin( return; } - var pin = DependencyPin.Create(DependencyScope.Packages, item.Id, versionText, declaringFile) with - { + var pin = DependencyPin.Create(DependencyScope.Packages, item.Id, versionText, declaringFile) with { ItemType = item.ItemType, MetadataPolicy = EvaluatedMetadata.Stated(item.UpdatePolicy), }; diff --git a/src/Buildvana.Tool/Services/Dependencies/PinNotes.cs b/src/Buildvana.Tool/Services/Dependencies/PinNotes.cs index 239e87b3..96fd7d2b 100644 --- a/src/Buildvana.Tool/Services/Dependencies/PinNotes.cs +++ b/src/Buildvana.Tool/Services/Dependencies/PinNotes.cs @@ -77,8 +77,7 @@ public static string ForNetSdk(NetSdkPin pin, NetSdkUpdatePolicy policy) /// What the pin's version text makes of it. /// The note, or an empty string for a pin bv manages. public static string Unmanaged(PinManagement management) - => management switch - { + => management switch { PinManagement.Managed => string.Empty, PinManagement.BracketExactVersion => "not managed: one version in brackets; write it without them to have bv move it", PinManagement.VersionRange => "not managed: a version range decides what resolves", diff --git a/src/Buildvana.Tool/Services/Dependencies/ProjectAssetsReader.cs b/src/Buildvana.Tool/Services/Dependencies/ProjectAssetsReader.cs index 34bddabd..e4cfc0d4 100644 --- a/src/Buildvana.Tool/Services/Dependencies/ProjectAssetsReader.cs +++ b/src/Buildvana.Tool/Services/Dependencies/ProjectAssetsReader.cs @@ -37,8 +37,7 @@ public static ProjectAssets Read(string projectFullPath, string assetsFilePath) Guard.IsNotNullOrEmpty(projectFullPath); Guard.IsNotNullOrEmpty(assetsFilePath); var lockFile = ReadLockFile(projectFullPath, assetsFilePath); - return new ProjectAssets - { + return new ProjectAssets { ProjectFullPath = projectFullPath, Packages = ReadPackages(lockFile), DirectReferences = ReadDirectReferences(lockFile), diff --git a/src/Buildvana.Tool/Services/Dependencies/UpdatePolicyEngine.cs b/src/Buildvana.Tool/Services/Dependencies/UpdatePolicyEngine.cs index 002f038b..8b9125a2 100644 --- a/src/Buildvana.Tool/Services/Dependencies/UpdatePolicyEngine.cs +++ b/src/Buildvana.Tool/Services/Dependencies/UpdatePolicyEngine.cs @@ -112,8 +112,7 @@ private static TargetSelection ComposeDisabled(IReadOnlyCollection // NuGetVersion.Revision is the fourth field of x.y.z.R, and reads zero on a version that has none, so a // three-field pin and a three-field candidate compare equal there. private static bool IsInWindow(NuGetVersion current, NuGetVersion candidate, PackageUpdatePolicyKind kind) - => kind switch - { + => kind switch { PackageUpdatePolicyKind.Exact => IsSameMajorMinorPatch(current, candidate) && candidate.Revision == current.Revision, PackageUpdatePolicyKind.Revision => IsSameMajorMinorPatch(current, candidate), PackageUpdatePolicyKind.Patch => IsSameMajorMinor(current, candidate), @@ -124,8 +123,7 @@ private static bool IsInWindow(NuGetVersion current, NuGetVersion candidate, Pac // Lts widens to everything here, having already narrowed the candidate set to LTS releases. private static bool IsInWindow(NuGetVersion current, NuGetVersion candidate, NetSdkUpdatePolicyKind kind) - => kind switch - { + => kind switch { NetSdkUpdatePolicyKind.Patch => IsSameMajorMinor(current, candidate) && FeatureBand(candidate) == FeatureBand(current), NetSdkUpdatePolicyKind.Feature => IsSameMajorMinor(current, candidate), NetSdkUpdatePolicyKind.Minor => candidate.Major == current.Major, @@ -164,8 +162,7 @@ private static TargetSelection CreateSelection( { var latestStable = Highest(candidates.Where(candidate => !candidate.IsPrerelease)); var latestPreview = Highest(candidates.Where(candidate => candidate.IsPrerelease && IsAbove(candidate, latestStable))); - return new() - { + return new() { Outcome = outcome, Target = target, LatestStable = latestStable, diff --git a/src/Buildvana.Tool/Services/Git/GitService.cs b/src/Buildvana.Tool/Services/Git/GitService.cs index d60183d5..e20a6621 100644 --- a/src/Buildvana.Tool/Services/Git/GitService.cs +++ b/src/Buildvana.Tool/Services/Git/GitService.cs @@ -182,8 +182,7 @@ public IReadOnlyList GetDirtyFiles() { var homeDirectory = _home.HomeDirectory; var scratchPrefix = Path.GetFullPath(CommonPaths.Scratch, homeDirectory) + Path.DirectorySeparatorChar; - var options = new StatusOptions - { + var options = new StatusOptions { IncludeIgnored = false, IncludeUntracked = true, RecurseUntrackedDirs = true, @@ -206,8 +205,7 @@ public void Stage(params string[] paths) } var homeDirectory = _home.HomeDirectory; - var pathsInRepo = paths.Select(path => - { + var pathsInRepo = paths.Select(path => { Guard.IsTrue(!string.IsNullOrEmpty(path), nameof(paths), "One or more paths are null or empty."); var absolutePath = Path.GetFullPath(path, homeDirectory); var pathInRepo = Path.GetRelativePath(homeDirectory, absolutePath); @@ -226,8 +224,7 @@ public void Stage(params string[] paths) Commands.Stage( _repository, pathsInRepo, - new StageOptions - { + new StageOptions { IncludeIgnored = false, ExplicitPathsOptions = new() { ShouldFailOnUnmatchedPath = true }, }); @@ -277,8 +274,7 @@ public void Push(bool force = false) var pushCredentialsFallback = PushCredentialsFallback; if (pushCredentialsFallback is not null) { - pushOptions.CredentialsProvider = (_, _, _) => new UsernamePasswordCredentials - { + pushOptions.CredentialsProvider = (_, _, _) => new UsernamePasswordCredentials { Username = pushCredentialsFallback.Username, Password = pushCredentialsFallback.Password, }; diff --git a/src/Buildvana.Tool/Services/Hooks/HookArgsFactory`1.cs b/src/Buildvana.Tool/Services/Hooks/HookArgsFactory`1.cs index 49b6b564..8906d25b 100644 --- a/src/Buildvana.Tool/Services/Hooks/HookArgsFactory`1.cs +++ b/src/Buildvana.Tool/Services/Hooks/HookArgsFactory`1.cs @@ -43,8 +43,7 @@ internal abstract class HookArgsFactory( protected RuntimeInfo CreateRuntimeInfo(string artifactsPath) { Guard.IsNotNullOrEmpty(artifactsPath); - return new() - { + return new() { Version = OwnVersion.Value.ToNormalizedString(), DelegatingVersion = Environment.GetEnvironmentVariable(DelegationService.DelegatedEnvVar), diff --git a/src/Buildvana.Tool/Services/Hooks/PostReleaseHookArgsFactory.cs b/src/Buildvana.Tool/Services/Hooks/PostReleaseHookArgsFactory.cs index 001a9238..51e395f6 100644 --- a/src/Buildvana.Tool/Services/Hooks/PostReleaseHookArgsFactory.cs +++ b/src/Buildvana.Tool/Services/Hooks/PostReleaseHookArgsFactory.cs @@ -50,11 +50,9 @@ public PostReleaseHookArgs Create( Guard.IsNotNullOrEmpty(simpleVersion); Guard.IsNotNullOrEmpty(semVer); Guard.IsNotNull(producedPackages); - return new() - { + return new() { RuntimeInfo = CreateRuntimeInfo(artifactsPath), - Release = new() - { + Release = new() { Version = simpleVersion, SemVer = semVer, PreviousVersion = latest?.ToString(), diff --git a/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs b/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs index df61cf6a..6556c6d8 100644 --- a/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs +++ b/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs @@ -39,16 +39,14 @@ internal sealed class PostUpdateHookArgsFactory( public PostUpdateHookArgs Create(DependencyResolution resolution, bool check) { Guard.IsNotNull(resolution); - return new() - { + return new() { RuntimeInfo = CreateRuntimeInfo(CommonPaths.AllArtifacts), Check = check, NetSdk = resolution.NetSdk is { } netSdk ? ResultOf(netSdk) : null, Sdks = ResultsOf(resolution.Sdks), Tools = ResultsOf(resolution.Tools), Packages = ResultsOf(resolution.Packages.Where(static pin => pin.Pin.GroupCaption is null)), - AdditionalPackages = - [ + AdditionalPackages = [ .. resolution.Packages .Where(static pin => pin.Pin.GroupCaption is not null) .GroupBy(static pin => pin.Pin.GroupCaption!) @@ -62,8 +60,7 @@ .. resolution.Packages } private static IReadOnlyList OverridesOf(IReadOnlyList entries) - => [.. entries.Select(static entry => new TransitiveOverride - { + => [.. entries.Select(static entry => new TransitiveOverride { PackageId = entry.PackageId, Version = entry.Version, DeclaringFile = entry.DeclaringFile, @@ -72,8 +69,7 @@ private static IReadOnlyList OverridesOf(IReadOnlyList ResultsOf(IEnumerable pins) => [.. pins.Select(ResultOf)]; private static DependencyResult ResultOf(PinResolution pin) - => new() - { + => new() { Id = pin.Pin.Id, DeclaringFile = pin.Pin.DeclaringFile, CurrentVersion = pin.Pin.VersionText, @@ -85,8 +81,7 @@ private static DependencyResult ResultOf(PinResolution pin) }; private static DependencyResult ResultOf(NetSdkResolution netSdk) - => new() - { + => new() { DeclaringFile = GlobalJsonPinReader.RelativePath, CurrentVersion = netSdk.Pin.VersionText, Target = Text(netSdk.Target), @@ -99,8 +94,7 @@ private static DependencyResult ResultOf(NetSdkResolution netSdk) private static string? Text(NuGetVersion? version) => version?.ToNormalizedString(); private static DependencyResultState StateOf(PinResolutionState state) - => state switch - { + => state switch { PinResolutionState.UpToDate => DependencyResultState.UpToDate, PinResolutionState.Updated => DependencyResultState.Updated, PinResolutionState.Disabled => DependencyResultState.Disabled, diff --git a/src/Buildvana.Tool/Services/SelfReferenceUpdater.cs b/src/Buildvana.Tool/Services/SelfReferenceUpdater.cs index 3c3cd7e5..8b3b05b9 100644 --- a/src/Buildvana.Tool/Services/SelfReferenceUpdater.cs +++ b/src/Buildvana.Tool/Services/SelfReferenceUpdater.cs @@ -47,8 +47,7 @@ public SelfReferenceUpdater( _reporter = reporter; _home = home; _jsonHelper = jsonHelper; - _targets = - [ + _targets = [ ("global.json", (p, produced) => UpdateJsonContainer(p, produced, container: "msbuild-sdks", versionPropertyName: null)), (ToolManifest.FileName, (p, produced) => UpdateJsonContainer( p, @@ -113,8 +112,7 @@ private bool UpdateJsonContainer( IReadOnlyDictionary produced, string container, string? versionPropertyName) - => _jsonHelper.RewriteStringValues(path, (propertyPath, currentValue) => - { + => _jsonHelper.RewriteStringValues(path, (propertyPath, currentValue) => { if (versionPropertyName is null) { if (propertyPath.Count != 2 || propertyPath[0] != container) @@ -137,8 +135,7 @@ private bool UpdateJsonContainer( }); private bool UpdateMsBuildXml(string path, IReadOnlyDictionary produced, string[] itemTypes) - => MsBuildPinEditor.RewritePins(path, itemTypes, pin => - { + => MsBuildPinEditor.RewritePins(path, itemTypes, pin => { if (!produced.TryGetValue(pin.Id, out var newVersion)) { return null; diff --git a/src/Buildvana.Tool/Services/SelfUpdate/SelfVersionService.cs b/src/Buildvana.Tool/Services/SelfUpdate/SelfVersionService.cs index 69dc4391..3adab593 100644 --- a/src/Buildvana.Tool/Services/SelfUpdate/SelfVersionService.cs +++ b/src/Buildvana.Tool/Services/SelfUpdate/SelfVersionService.cs @@ -428,8 +428,7 @@ private string UpdateGlobalJson(string? currentPinText, NuGetVersion? currentPin var targetText = target.ToNormalizedString(); var fileName = Path.GetFileName(path); string? schemaReference = null; - var changed = _jsonHelper.RewriteStringValues(path, (propertyPath, value) => - { + var changed = _jsonHelper.RewriteStringValues(path, (propertyPath, value) => { if (propertyPath is not [SchemaPropertyName]) { return null; diff --git a/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerAdapter.cs b/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerAdapter.cs index 0a6fcd69..5a1c2208 100644 --- a/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerAdapter.cs +++ b/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerAdapter.cs @@ -127,14 +127,12 @@ public override async Task CreateReleaseAsync() => await GitHubServerRelease.CreateAsync( server: this, services: _services, - createGitHubReleaseAsync: () => - { + createGitHubReleaseAsync: () => { // Create the release as a draft first, so if the token has no permissions we can bail out early var tag = _version.CurrentStr; var client = CreateGitHubClient(); _reporter.Info("Creating a provisional draft release..."); - var newRelease = new NewRelease(tag) - { + var newRelease = new NewRelease(tag) { Name = $"{tag} [provisional]", TargetCommitish = _git.CurrentBranch, Prerelease = _version.IsPrerelease, @@ -159,8 +157,7 @@ public async Task PublishReleaseAsync(Release release, string targetCommitish) var tag = _version.CurrentStr; var client = CreateGitHubClient(); _reporter.Info($"Generating release notes for {tag}..."); - var releaseNotesRequest = new GenerateReleaseNotesRequest(tag) - { + var releaseNotesRequest = new GenerateReleaseNotesRequest(tag) { TargetCommitish = targetCommitish, }; @@ -242,8 +239,7 @@ public async Task UploadReleaseAssetAsync(Release release, string path, string m var assetContents = UserFile.OpenRead(path); await using (assetContents.ConfigureAwait(false)) { - var upload = new ReleaseAssetUpload - { + var upload = new ReleaseAssetUpload { FileName = Path.GetFileName(path), ContentType = mimeType, RawData = assetContents, @@ -267,8 +263,7 @@ public async Task UploadReleaseAssetAsync(Release release, string path, string m private GitHubClient CreateGitHubClient() { - var client = new GitHubClient(new ProductHeaderValue("Buildvana")) - { + var client = new GitHubClient(new ProductHeaderValue("Buildvana")) { Credentials = new(_token), }; diff --git a/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerRelease.cs b/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerRelease.cs index efe2ebfc..e6023f00 100644 --- a/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerRelease.cs +++ b/src/Buildvana.Tool/Services/ServerAdapters/Internal/GitHub/GitHubServerRelease.cs @@ -45,8 +45,7 @@ private GitHubServerRelease( _gitHubRelease = gitHubRelease; _actionsStepOutputFile = actionsStepOutputFile; - OnRollback(async () => - { + OnRollback(async () => { // Do this only if the release has not been previously deleted by rolling back its publication if (!_gitHubReleaseDeleted) { diff --git a/src/Buildvana.Tool/Services/ServerAdapters/ServerRelease.cs b/src/Buildvana.Tool/Services/ServerAdapters/ServerRelease.cs index 0095abf9..2adbfaa3 100644 --- a/src/Buildvana.Tool/Services/ServerAdapters/ServerRelease.cs +++ b/src/Buildvana.Tool/Services/ServerAdapters/ServerRelease.cs @@ -91,8 +91,7 @@ public void EnsureReleaseCommit() _repositoryUpdated = true; NameReleaseCommit(); - OnRollback(() => - { + OnRollback(() => { // This lambda rolls back the release commit, any post-release commits added on top, // and (if appropriate) the push that carried them to the remote. var commitsToUndo = 1 + _postReleaseCommits; @@ -103,8 +102,7 @@ public void EnsureReleaseCommit() // The whole set of commits is one undoing, recorded once: a notice per commit would read // as a repeated line rather than as the several commits it actually walks back. - _reporter.Notice(_postReleaseCommits switch - { + _reporter.Notice(_postReleaseCommits switch { 0 => "Undid the release commit.", 1 => "Undid the release commit and 1 post-release commit.", var count => string.Create(CultureInfo.InvariantCulture, $"Undid the release commit and {count} post-release commits."), @@ -245,8 +243,7 @@ public async Task PublishAsync() // The record of the publication comes last, once nothing can undo it any more: OnPublishedAsync // is the final step that can still fail, and its failure rolls the whole release back - deleting // the release and the tag that a notice printed any earlier would already have claimed. - _reporter.Notice(_assets.Count switch - { + _reporter.Notice(_assets.Count switch { 0 => $"Published release {_version.CurrentStr} with no assets.", 1 => $"Published release {_version.CurrentStr} with 1 asset.", var count => string.Create(CultureInfo.InvariantCulture, $"Published release {_version.CurrentStr} with {count} assets."), @@ -283,8 +280,7 @@ public async ValueTask DisposeAsync() protected virtual Task OnPublishedAsync() => Task.CompletedTask; - protected void OnRollback(Action action) => OnRollback(() => - { + protected void OnRollback(Action action) => OnRollback(() => { action(); return ValueTask.CompletedTask; }); diff --git a/src/Buildvana.Tool/Services/Versioning/VersionService.cs b/src/Buildvana.Tool/Services/Versioning/VersionService.cs index 880a1513..394a0c4c 100644 --- a/src/Buildvana.Tool/Services/Versioning/VersionService.cs +++ b/src/Buildvana.Tool/Services/Versioning/VersionService.cs @@ -150,8 +150,7 @@ public VersionSpecChange ComputeVersionSpecChange(VersionSpecChange requestedCha // When the major version is 0, "anything MAY change" according to SemVer; // by convention, we increment the minor version for breaking changes (0.x -> 0.(x+1)) var isMajorVersionZero = LatestStable is { Major: 0 }; - var semanticVersionIncrement = publicApiChangeKind switch - { + var semanticVersionIncrement = publicApiChangeKind switch { ApiChangeKind.Breaking => isMajorVersionZero ? VersionIncrement.Minor : VersionIncrement.Major, ApiChangeKind.Additive => isMajorVersionZero ? VersionIncrement.None : VersionIncrement.Minor, _ => VersionIncrement.None, @@ -160,8 +159,7 @@ public VersionSpecChange ComputeVersionSpecChange(VersionSpecChange requestedCha // Determine the requested version increment, if any. _reporter.Info($"Requested version spec change: {requestedChange}"); - var requestedVersionIncrement = requestedChange switch - { + var requestedVersionIncrement = requestedChange switch { VersionSpecChange.Major => VersionIncrement.Major, VersionSpecChange.Minor => VersionIncrement.Minor, _ => VersionIncrement.None, @@ -181,13 +179,11 @@ public VersionSpecChange ComputeVersionSpecChange(VersionSpecChange requestedCha // Determine the actual version spec change to apply: // - forget any increment-related change (already accounted for via requestedVersionIncrement) // - set the change to the required increment if any, otherwise leave it as is (None, Unstable, Stable) - var actualChange = requestedChange switch - { + var actualChange = requestedChange switch { VersionSpecChange.Major or VersionSpecChange.Minor => VersionSpecChange.None, _ => requestedChange, }; - actualChange = actualVersionIncrement switch - { + actualChange = actualVersionIncrement switch { VersionIncrement.Major => VersionSpecChange.Major, VersionIncrement.Minor => VersionSpecChange.Minor, _ => actualChange, diff --git a/src/Buildvana.Tool/Subcommands/DependenciesPruneSettings.cs b/src/Buildvana.Tool/Subcommands/DependenciesPruneSettings.cs index 6ee99f8c..39e441c5 100644 --- a/src/Buildvana.Tool/Subcommands/DependenciesPruneSettings.cs +++ b/src/Buildvana.Tool/Subcommands/DependenciesPruneSettings.cs @@ -84,8 +84,7 @@ public static DependenciesPruneSettings Parse(IReadOnlyList options) { Guard.IsNotNull(options); var reader = new CliOptionReader(options); - return new DependenciesPruneSettings - { + return new DependenciesPruneSettings { NetSdk = reader.ReadFlag("--netsdk"), Sdks = reader.ReadFlag("--sdks"), Tools = reader.ReadFlag("--tools"), diff --git a/src/Buildvana.Tool/Subcommands/DependenciesSettings.cs b/src/Buildvana.Tool/Subcommands/DependenciesSettings.cs index 98d810a3..5f726c74 100644 --- a/src/Buildvana.Tool/Subcommands/DependenciesSettings.cs +++ b/src/Buildvana.Tool/Subcommands/DependenciesSettings.cs @@ -78,8 +78,7 @@ public static DependenciesSettings Parse(IReadOnlyList options) { Guard.IsNotNull(options); var reader = new CliOptionReader(options); - return new DependenciesSettings - { + return new DependenciesSettings { NetSdk = reader.ReadFlag("--netsdk"), Sdks = reader.ReadFlag("--sdks"), Tools = reader.ReadFlag("--tools"), diff --git a/src/Buildvana.Tool/Subcommands/DependenciesUpdateSettings.cs b/src/Buildvana.Tool/Subcommands/DependenciesUpdateSettings.cs index 7a7a3c12..e3eff266 100644 --- a/src/Buildvana.Tool/Subcommands/DependenciesUpdateSettings.cs +++ b/src/Buildvana.Tool/Subcommands/DependenciesUpdateSettings.cs @@ -110,8 +110,7 @@ public static DependenciesUpdateSettings Parse(IReadOnlyList positionals Guard.IsNotNull(positionals); Guard.IsNotNull(options); var reader = new CliOptionReader(options); - var settings = new DependenciesUpdateSettings - { + var settings = new DependenciesUpdateSettings { Filters = [.. positionals], NetSdk = reader.ReadFlag("--netsdk"), Sdks = reader.ReadFlag("--sdks"), diff --git a/src/Buildvana.Tool/Subcommands/ReleaseCommand.cs b/src/Buildvana.Tool/Subcommands/ReleaseCommand.cs index ba62639c..c74f92ad 100644 --- a/src/Buildvana.Tool/Subcommands/ReleaseCommand.cs +++ b/src/Buildvana.Tool/Subcommands/ReleaseCommand.cs @@ -369,8 +369,7 @@ public async Task ExecuteAsync(CancellationToken cancellationToken) } // Never one: a transfer yields both files of every pair it modifies, so there is no singular case to report. - private static string DescribeModifiedApiFiles(int count, string kind) => count switch - { + private static string DescribeModifiedApiFiles(int count, string kind) => count switch { 0 => $"No {kind} API files were modified.", _ => string.Create(CultureInfo.InvariantCulture, $"{count} {kind} API files were modified."), }; diff --git a/src/Buildvana.Tool/Subcommands/ReleaseSettings.cs b/src/Buildvana.Tool/Subcommands/ReleaseSettings.cs index 5a210ed7..8dd4e8e7 100644 --- a/src/Buildvana.Tool/Subcommands/ReleaseSettings.cs +++ b/src/Buildvana.Tool/Subcommands/ReleaseSettings.cs @@ -67,8 +67,7 @@ public static ReleaseSettings Parse(IReadOnlyList options) { Guard.IsNotNull(options); var reader = new CliOptionReader(options); - return new ReleaseSettings - { + return new ReleaseSettings { Configuration = reader.ReadValue("--configuration", "-c"), Bump = reader.ReadValue("--bump"), CheckPublicApi = reader.ReadBoolValue("--check-public-api"), diff --git a/src/Buildvana.Tool/Subcommands/SelfUpdateCommand.cs b/src/Buildvana.Tool/Subcommands/SelfUpdateCommand.cs index 07ffb90c..9b9bb83d 100644 --- a/src/Buildvana.Tool/Subcommands/SelfUpdateCommand.cs +++ b/src/Buildvana.Tool/Subcommands/SelfUpdateCommand.cs @@ -19,8 +19,7 @@ internal sealed class SelfUpdateCommand(SelfVersionService selfVersion, SelfUpda { public async Task ExecuteAsync(CancellationToken cancellationToken) { - var request = new SelfUpdateRequest - { + var request = new SelfUpdateRequest { To = settings.ResolveTo(), Preview = settings.Preview, Repair = settings.Repair, diff --git a/src/Buildvana.Tool/Subcommands/SelfUpdateSettings.cs b/src/Buildvana.Tool/Subcommands/SelfUpdateSettings.cs index 15684e4c..80a0918f 100644 --- a/src/Buildvana.Tool/Subcommands/SelfUpdateSettings.cs +++ b/src/Buildvana.Tool/Subcommands/SelfUpdateSettings.cs @@ -57,8 +57,7 @@ public static SelfUpdateSettings Parse(IReadOnlyList options) { Guard.IsNotNull(options); var reader = new CliOptionReader(options); - var settings = new SelfUpdateSettings - { + var settings = new SelfUpdateSettings { Force = reader.ReadFlag("--force"), Preview = reader.ReadFlag("--preview"), Repair = reader.ReadFlag("--repair"), diff --git a/src/Buildvana.Tool/Subcommands/VersionAdvanceSettings.cs b/src/Buildvana.Tool/Subcommands/VersionAdvanceSettings.cs index 59198e0a..5a9fcb12 100644 --- a/src/Buildvana.Tool/Subcommands/VersionAdvanceSettings.cs +++ b/src/Buildvana.Tool/Subcommands/VersionAdvanceSettings.cs @@ -64,8 +64,7 @@ public static VersionAdvanceSettings Parse(IReadOnlyList positionals, IR Guard.IsNotNull(positionals); Guard.IsNotNull(options); var reader = new CliOptionReader(options); - return new VersionAdvanceSettings - { + return new VersionAdvanceSettings { Change = positionals.Count > 0 ? positionals[0] : null, CheckPublicApi = reader.ReadBoolValue("--check-public-api"), Force = reader.ReadFlag("--force"), diff --git a/src/Buildvana.Tool/Utilities/AppDirectiveEditor-scanning.cs b/src/Buildvana.Tool/Utilities/AppDirectiveEditor-scanning.cs index 187b0351..130c2f3e 100644 --- a/src/Buildvana.Tool/Utilities/AppDirectiveEditor-scanning.cs +++ b/src/Buildvana.Tool/Utilities/AppDirectiveEditor-scanning.cs @@ -148,8 +148,7 @@ private static void ParseDirective(string text, int start, int end, List AppDirectiveKind.Package, "sdk" => AppDirectiveKind.Sdk, _ => null, diff --git a/src/Buildvana.Tool/Utilities/RepositoryFiles.cs b/src/Buildvana.Tool/Utilities/RepositoryFiles.cs index 39c432e2..69f752ab 100644 --- a/src/Buildvana.Tool/Utilities/RepositoryFiles.cs +++ b/src/Buildvana.Tool/Utilities/RepositoryFiles.cs @@ -16,8 +16,7 @@ internal static class RepositoryFiles { // Exclusions on top of what .gitignore files dictate: bv's own outputs, anchored at the home directory, // plus the conventional build and dependency directories at any depth. The finder skips `.git` on its own. - private static readonly string[] ExclusionPatterns = - [ + private static readonly string[] ExclusionPatterns = [ "/" + CommonPaths.AllArtifacts + "/", "/" + CommonPaths.Scratch + "/", "bin/", diff --git a/tests/Buildvana.Core.Configuration.Tests/BuildvanaConfigFactoryTests.cs b/tests/Buildvana.Core.Configuration.Tests/BuildvanaConfigFactoryTests.cs index 077ceb6a..4cfd4108 100644 --- a/tests/Buildvana.Core.Configuration.Tests/BuildvanaConfigFactoryTests.cs +++ b/tests/Buildvana.Core.Configuration.Tests/BuildvanaConfigFactoryTests.cs @@ -40,18 +40,15 @@ public async Task Create_NoSources_YieldsDomainDefaults() [Test] public async Task Create_FileValues_OverrideDefaults() { - var json = new BuildvanaJsonConfig - { - Release = new() - { + var json = new BuildvanaJsonConfig { + Release = new() { Branches = ["^main$"], CheckPublicApi = false, ChangelogUpdates = ChangelogUpdates.All, EmptyChangelog = "No changes.", Dogfood = false, }, - Versioning = new() - { + Versioning = new() { PrereleaseTag = "preview", AssemblyVersionPrecision = AssemblyVersionPrecision.Build, }, @@ -76,13 +73,11 @@ public async Task Create_FileValues_OverrideDefaults() [Test] public async Task Create_CommandLine_BeatsFileAndDefaults() { - var json = new BuildvanaJsonConfig - { + var json = new BuildvanaJsonConfig { Release = new() { CheckPublicApi = true, Dogfood = true }, DotNet = new() { Configuration = "Debug" }, }; - var commandLine = new CommandLineOverrides - { + var commandLine = new CommandLineOverrides { Configuration = "Custom", CheckPublicApi = false, Dogfood = false, @@ -107,8 +102,7 @@ public async Task Create_ReleaseConfiguration_FollowsFileOverDotNetChain() // A release-specific configuration wins over dotnet.configuration. var both = BuildvanaConfigFactory.Create( - new BuildvanaJsonConfig - { + new BuildvanaJsonConfig { Release = new() { Configuration = "ReleaseOnly" }, DotNet = new() { Configuration = "Debug" }, }, @@ -160,10 +154,8 @@ public async Task Create_TokenEnv_BlankFallsBackToDefault() [Test] public async Task Create_DotNetInvocations_FoldCommonTierIntoEachCommand() { - var json = new BuildvanaJsonConfig - { - DotNet = new() - { + var json = new BuildvanaJsonConfig { + DotNet = new() { All = new() { Args = ["-common"], Env = new Dictionary { ["A"] = "1" } }, Test = new() { Args = ["--coverage"], Env = new Dictionary { ["B"] = null } }, }, @@ -186,10 +178,8 @@ public async Task Create_DotNetInvocations_FoldCommonTierIntoEachCommand() [Test] public async Task Create_DotNetEnv_PerCommandOverridesCommonKey() { - var json = new BuildvanaJsonConfig - { - DotNet = new() - { + var json = new BuildvanaJsonConfig { + DotNet = new() { All = new() { Env = new Dictionary { ["KEY"] = "from-all", ["ONLY_ALL"] = "kept" } }, Build = new() { Env = new Dictionary { ["KEY"] = "from-build" } }, }, @@ -208,10 +198,8 @@ public async Task Create_DotNetEnv_PerCommandOverridesCommonKey() [Test] public async Task Create_ForwardedArgs_AppendToPipelineCommandsOnly() { - var json = new BuildvanaJsonConfig - { - DotNet = new() - { + var json = new BuildvanaJsonConfig { + DotNet = new() { All = new() { Args = ["-common"] }, Pack = new() { Args = ["--pack-arg"] }, }, @@ -231,12 +219,9 @@ public async Task Create_ForwardedArgs_AppendToPipelineCommandsOnly() [Test] public async Task Create_Feeds_MapVerbatim() { - var json = new BuildvanaJsonConfig - { - NuGet = new() - { - Feeds = new() - { + var json = new BuildvanaJsonConfig { + NuGet = new() { + Feeds = new() { Prerelease = new() { Source = "https://prerelease.example/v3/index.json", ApiKeyEnv = "PRE_KEY" }, Release = new() { Source = "https://nuget.example/v3/index.json", ApiKeyEnv = "KEY" }, }, @@ -256,12 +241,9 @@ public async Task Create_Feeds_MapVerbatim() [Test] public async Task Create_Feeds_PrereleaseFallsBackToReleaseFeed() { - var json = new BuildvanaJsonConfig - { - NuGet = new() - { - Feeds = new() - { + var json = new BuildvanaJsonConfig { + NuGet = new() { + Feeds = new() { Release = new() { Source = "https://nuget.example/v3/index.json", ApiKeyEnv = "KEY" }, }, }, @@ -276,8 +258,7 @@ public async Task Create_Feeds_PrereleaseFallsBackToReleaseFeed() [Test] public async Task Create_GitIdentity_MapsNameAndEmail() { - var json = new BuildvanaJsonConfig - { + var json = new BuildvanaJsonConfig { Git = new() { Identity = new() { Name = "Buildvana Bot", Email = "bot@buildvana.invalid" } }, }; @@ -314,12 +295,9 @@ public async Task Create_FileBasedApps_CannotNegateTheBuiltInScope() [Test] public async Task Create_DependencyPolicies_KeepFileOrder() { - var json = new BuildvanaJsonConfig - { - Dependencies = new() - { - Policies = - [ + var json = new BuildvanaJsonConfig { + Dependencies = new() { + Policies = [ new() { Pattern = "Microsoft.CodeAnalysis.*", Policy = "minor" }, new() { Pattern = "*", Policy = "patch" }, ], @@ -341,13 +319,10 @@ public async Task Create_DependencyPolicies_KeepFileOrder() [Arguments("patch", "patch")] public async Task Create_AdditionalPackageGroup_ResolvesItsPolicy(string? stated, string expected) { - var json = new BuildvanaJsonConfig - { - Dependencies = new() - { + var json = new BuildvanaJsonConfig { + Dependencies = new() { Scopes = new() { Packages = "major-" }, - AdditionalPackages = - [ + AdditionalPackages = [ new() { Caption = "Group", Files = "src/*.props", Items = "BV_PackageVersion", Policy = stated }, ], }, diff --git a/tests/Buildvana.Core.Configuration.Tests/BuildvanaJsonConfigExampleTests.cs b/tests/Buildvana.Core.Configuration.Tests/BuildvanaJsonConfigExampleTests.cs index b9e24ffb..06e7e0d5 100644 --- a/tests/Buildvana.Core.Configuration.Tests/BuildvanaJsonConfigExampleTests.cs +++ b/tests/Buildvana.Core.Configuration.Tests/BuildvanaJsonConfigExampleTests.cs @@ -14,15 +14,11 @@ internal sealed class BuildvanaJsonConfigExampleTests [Test] public async Task Generate_Schema_WalksItIntoAnObject() { - var root = new JsonObject - { - ["properties"] = new JsonObject - { + var root = new JsonObject { + ["properties"] = new JsonObject { ["flag"] = new JsonObject { ["description"] = "Whether the thing is on.", ["default"] = true }, - ["section"] = new JsonObject - { - ["properties"] = new JsonObject - { + ["section"] = new JsonObject { + ["properties"] = new JsonObject { ["name"] = new JsonObject { ["examples"] = new JsonArray { "value" } }, }, }, @@ -47,10 +43,8 @@ await Assert.That(BodyOf(root)).IsEqualTo( [Test] public async Task Generate_EmptyContainers_WriteTheirShape() { - var root = new JsonObject - { - ["properties"] = new JsonObject - { + var root = new JsonObject { + ["properties"] = new JsonObject { ["list"] = new JsonObject { ["type"] = "array" }, ["map"] = new JsonObject { ["type"] = "object" }, }, @@ -70,8 +64,7 @@ await Assert.That(BodyOf(root)).IsEqualTo( [Test] public async Task Generate_Reference_WritesWhatItPointsAt() { - var root = new JsonObject - { + var root = new JsonObject { ["$defs"] = new JsonObject { ["shared"] = new JsonObject { ["default"] = 42 } }, ["properties"] = new JsonObject { ["value"] = new JsonObject { ["$ref"] = "#/$defs/shared" } }, }; @@ -92,8 +85,7 @@ public async Task Generate_ExampleBesideMembers_Throws() { var root = SchemaOf( "section", - new JsonObject - { + new JsonObject { ["examples"] = new JsonArray { "whole section" }, ["properties"] = new JsonObject { ["member"] = new JsonObject { ["default"] = true } }, }); @@ -113,8 +105,7 @@ public async Task Generate_ExampleBesideMemberNames_Throws() { var root = SchemaOf( "groups", - new JsonObject - { + new JsonObject { ["examples"] = new JsonArray { "whole section" }, ["propertyNames"] = new JsonObject { ["examples"] = new JsonArray { "My group" } }, ["additionalProperties"] = new JsonObject { ["type"] = "object" }, @@ -133,19 +124,14 @@ await Assert.That(problem).IsEqualTo( [Test] public async Task Generate_ExampleOnAReferenceToASection_Throws() { - var root = new JsonObject - { - ["$defs"] = new JsonObject - { - ["shared"] = new JsonObject - { + var root = new JsonObject { + ["$defs"] = new JsonObject { + ["shared"] = new JsonObject { ["properties"] = new JsonObject { ["member"] = new JsonObject { ["default"] = true } }, }, }, - ["properties"] = new JsonObject - { - ["section"] = new JsonObject - { + ["properties"] = new JsonObject { + ["section"] = new JsonObject { ["examples"] = new JsonArray { "whole section" }, ["$ref"] = "#/$defs/shared", }, @@ -167,8 +153,7 @@ public async Task Generate_ExampleOnADictionary_WritesTheExample() { var root = SchemaOf( "env", - new JsonObject - { + new JsonObject { ["type"] = "object", ["examples"] = new JsonArray { new JsonObject { ["KEY"] = "value" } }, ["additionalProperties"] = new JsonObject { ["type"] = "string" }, @@ -188,8 +173,7 @@ public async Task Generate_KeyedObjectWithoutAKeyExample_Throws() { var root = SchemaOf( "groups", - new JsonObject - { + new JsonObject { ["propertyNames"] = new JsonObject { ["type"] = "string" }, ["additionalProperties"] = new JsonObject { ["type"] = "object" }, }); @@ -210,8 +194,7 @@ public async Task Generate_KeyedObjectWithAnEmptyKeySchema_Throws() { var root = SchemaOf( "groups", - new JsonObject - { + new JsonObject { ["type"] = "object", ["additionalProperties"] = new JsonObject { ["type"] = "object" }, ["propertyNames"] = new JsonObject(), @@ -398,10 +381,8 @@ private static async Task ProblemOf(JsonObject root) private static JsonObject Reference(string pointer) => new() { ["$ref"] = pointer }; - private static JsonObject SampleSchema() => new() - { - ["properties"] = new JsonObject - { + private static JsonObject SampleSchema() => new() { + ["properties"] = new JsonObject { ["args"] = new JsonObject { ["type"] = "array" }, ["a/b"] = new JsonObject { ["type"] = "string" }, ["c~d"] = new JsonObject { ["type"] = "boolean" }, diff --git a/tests/Buildvana.Core.Configuration.Tests/ConfigurationPageTests.cs b/tests/Buildvana.Core.Configuration.Tests/ConfigurationPageTests.cs index a18e25d6..14b57669 100644 --- a/tests/Buildvana.Core.Configuration.Tests/ConfigurationPageTests.cs +++ b/tests/Buildvana.Core.Configuration.Tests/ConfigurationPageTests.cs @@ -26,8 +26,7 @@ internal sealed class ConfigurationPageTests // The settings that fall back to another setting, as the "Resolution" section of the page names them. The // schema states no default for them, because BuildvanaConfigFactory resolves the fallback at run time. - private static readonly Dictionary Fallbacks = new(StringComparer.Ordinal) - { + private static readonly Dictionary Fallbacks = new(StringComparer.Ordinal) { ["release.configuration"] = "dotnet.configuration", ["nuget.feeds.prerelease.source"] = "nuget.feeds.release.source", ["nuget.feeds.prerelease.apiKeyEnv"] = "nuget.feeds.release.apiKeyEnv", @@ -94,8 +93,7 @@ private static DocumentationPage LoadPage() // A default as the page writes it: the text of a string, and the JSON of anything else. private static string? RenderDefault(JsonNode? node) - => node switch - { + => node switch { null => null, JsonValue value when value.TryGetValue(out var text) => text, _ => node.ToJsonString(), diff --git a/tests/Buildvana.Core.Configuration.Tests/RepositoryConfigFilesTests.cs b/tests/Buildvana.Core.Configuration.Tests/RepositoryConfigFilesTests.cs index 8640c9ba..09b607da 100644 --- a/tests/Buildvana.Core.Configuration.Tests/RepositoryConfigFilesTests.cs +++ b/tests/Buildvana.Core.Configuration.Tests/RepositoryConfigFilesTests.cs @@ -23,8 +23,7 @@ internal sealed class RepositoryConfigFilesTests // Comments and trailing commas are what the .jsonc extension advertises, and both configuration files use // them. The tool manifest uses neither, and accepting them there costs nothing. - private static readonly JsonDocumentOptions ReaderOptions = new() - { + private static readonly JsonDocumentOptions ReaderOptions = new() { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true, }; diff --git a/tests/Buildvana.Core.ConsoleOutput.Tests/ReporterExtensionsTests.cs b/tests/Buildvana.Core.ConsoleOutput.Tests/ReporterExtensionsTests.cs index cd5fefe6..846f3cef 100644 --- a/tests/Buildvana.Core.ConsoleOutput.Tests/ReporterExtensionsTests.cs +++ b/tests/Buildvana.Core.ConsoleOutput.Tests/ReporterExtensionsTests.cs @@ -19,8 +19,7 @@ public async Task MessageShortcuts_ReportAtTheirOwnLevel() reporter.Info("working"); reporter.Detail("details"); reporter.Trace("trace"); - string[] expected = - [ + string[] expected = [ "error: boom", "warning: careful", "notice: noted", @@ -42,8 +41,7 @@ public async Task FormattingShortcuts_FormatArgumentsAndReportAtTheirOwnLevel() reporter.Info(Format, "working", 4); reporter.Detail(Format, "details", 5); reporter.Trace(Format, "trace", 6); - string[] expected = - [ + string[] expected = [ "error: boom in 1", "warning: careful in 2", "notice: noted in 3", diff --git a/tests/Buildvana.Core.Diagnostics.Tests/ExceptionExtensionsTests.cs b/tests/Buildvana.Core.Diagnostics.Tests/ExceptionExtensionsTests.cs index 46bdaf1c..435692f0 100644 --- a/tests/Buildvana.Core.Diagnostics.Tests/ExceptionExtensionsTests.cs +++ b/tests/Buildvana.Core.Diagnostics.Tests/ExceptionExtensionsTests.cs @@ -10,8 +10,7 @@ internal sealed class ExceptionExtensionsTests [Test] public async Task IsIORelatedException_IsTrueForEnvironmentDrivenIOFailures() { - Exception[] exceptions = - [ + Exception[] exceptions = [ new IOException(), new FileNotFoundException(), new DirectoryNotFoundException(), @@ -77,8 +76,7 @@ public async Task IsFatalException_IsFalseForAggregateOfNonFatalExceptions() [Test] public async Task IsCriticalException_IsTrueForCriticalExceptions() { - Exception[] exceptions = - [ + Exception[] exceptions = [ new AppDomainUnloadedException(), new BadImageFormatException(), new CannotUnloadAppDomainException(), diff --git a/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs b/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs index e2ce953c..3def2ed3 100644 --- a/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs +++ b/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs @@ -237,8 +237,7 @@ public async Task ReadWrite_SourceGeneratedContext_ResolvesGeneratedNames() // Default.Options is read-only, so the copy constructor is how a converter joins a generated context. // The copy carries the context's naming policy and unmapped-member handling; the resolver is the context, // so elements go through generated metadata, not reflection. - var options = new JsonSerializerOptions(KeyedSampleJsonContext.Default.Options) - { + var options = new JsonSerializerOptions(KeyedSampleJsonContext.Default.Options) { Converters = { new JsonKeyedObjectConverter() }, }; @@ -258,8 +257,7 @@ public async Task ReadWrite_CustomizedContract_FollowsTypeInfoNames() // source that knows the effective name; recomputing it from the naming policy would synthesize a document // the element deserializer rejects. var resolver = new DefaultJsonTypeInfoResolver(); - resolver.Modifiers.Add(static typeInfo => - { + resolver.Modifiers.Add(static typeInfo => { if (typeInfo.Type == typeof(KeyedGroupSample)) { foreach (var property in typeInfo.Properties) @@ -271,8 +269,7 @@ public async Task ReadWrite_CustomizedContract_FollowsTypeInfoNames() } } }); - var options = new JsonSerializerOptions - { + var options = new JsonSerializerOptions { TypeInfoResolver = resolver, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new JsonKeyedObjectConverter() }, @@ -323,8 +320,7 @@ public async Task Read_SameKeyAndValueProperty_Throws() } private static JsonSerializerOptions CreateOptions(bool allowDuplicateProperties = true) - => new() - { + => new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, AllowDuplicateProperties = allowDuplicateProperties, Converters = { new JsonKeyedObjectConverter() }, diff --git a/tests/Buildvana.Core.Json.Tests/JsonSchemaGeneratorTests.cs b/tests/Buildvana.Core.Json.Tests/JsonSchemaGeneratorTests.cs index 95560103..8ce574ac 100644 --- a/tests/Buildvana.Core.Json.Tests/JsonSchemaGeneratorTests.cs +++ b/tests/Buildvana.Core.Json.Tests/JsonSchemaGeneratorTests.cs @@ -10,16 +10,14 @@ internal sealed class JsonSchemaGeneratorTests { - private static readonly JsonSerializerOptions Options = new() - { + private static readonly JsonSerializerOptions Options = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver(), PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase), new JsonKeyedObjectConverter() }, }; // Deliberately lacking JsonKeyedObjectConverter, to prove the keyed rendering is gated on its registration. - private static readonly JsonSerializerOptions KeyedConverterlessOptions = new() - { + private static readonly JsonSerializerOptions KeyedConverterlessOptions = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver(), PropertyNamingPolicy = JsonNamingPolicy.CamelCase, }; diff --git a/tests/Buildvana.Core.Json.Tests/JsonSchemaValidatorTests.cs b/tests/Buildvana.Core.Json.Tests/JsonSchemaValidatorTests.cs index 9f7c1778..50be0bef 100644 --- a/tests/Buildvana.Core.Json.Tests/JsonSchemaValidatorTests.cs +++ b/tests/Buildvana.Core.Json.Tests/JsonSchemaValidatorTests.cs @@ -9,8 +9,7 @@ internal sealed class JsonSchemaValidatorTests { - private static readonly JsonSerializerOptions KeyedOptions = new() - { + private static readonly JsonSerializerOptions KeyedOptions = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver(), PropertyNamingPolicy = JsonNamingPolicy.CamelCase, Converters = { new JsonKeyedObjectConverter() }, diff --git a/tests/Buildvana.Core.Versioning.Tests/VersionCalculatorTests.cs b/tests/Buildvana.Core.Versioning.Tests/VersionCalculatorTests.cs index 09e6448a..164bf13a 100644 --- a/tests/Buildvana.Core.Versioning.Tests/VersionCalculatorTests.cs +++ b/tests/Buildvana.Core.Versioning.Tests/VersionCalculatorTests.cs @@ -80,8 +80,7 @@ public async Task Calculate_PrereleasePublicRelease_AppendsTagOnly() repo.WriteFile("VERSION", "2.3-x\n"); repo.CommitAll(); repo.CheckoutNewBranch("rel"); - var config = new BuildvanaConfig - { + var config = new BuildvanaConfig { Release = new ReleaseConfig { Branches = ["^rel$"] }, Versioning = new VersioningConfig { PrereleaseTag = "preview" }, }; diff --git a/tests/Buildvana.Core.Versioning.Tests/VersioningSettingsTests.cs b/tests/Buildvana.Core.Versioning.Tests/VersioningSettingsTests.cs index 94a368a7..98830dce 100644 --- a/tests/Buildvana.Core.Versioning.Tests/VersioningSettingsTests.cs +++ b/tests/Buildvana.Core.Versioning.Tests/VersioningSettingsTests.cs @@ -19,11 +19,9 @@ public async Task Constructor_EmptyConfig_AppliesDefaults() [Test] public async Task Constructor_ReadsConfiguredValues() { - var config = new BuildvanaConfig - { + var config = new BuildvanaConfig { Release = new ReleaseConfig { Branches = ["^main$"] }, - Versioning = new VersioningConfig - { + Versioning = new VersioningConfig { PrereleaseTag = "preview", AssemblyVersionPrecision = AssemblyVersionPrecision.Build, }, diff --git a/tests/Buildvana.Runtime.Tests/HookArgsSecretsTests.cs b/tests/Buildvana.Runtime.Tests/HookArgsSecretsTests.cs index 7009cf6b..c6d52540 100644 --- a/tests/Buildvana.Runtime.Tests/HookArgsSecretsTests.cs +++ b/tests/Buildvana.Runtime.Tests/HookArgsSecretsTests.cs @@ -31,29 +31,23 @@ public async Task Serialize_WritesCredentialVariableNames_NeverTheirValues() } } - private static PostReleaseHookArgs SampleArgs(string credentialEnvVar) => new() - { - RuntimeInfo = new() - { + private static PostReleaseHookArgs SampleArgs(string credentialEnvVar) => new() { + RuntimeInfo = new() { Version = "1.2.3", HomeDirectory = "/repo", ArtifactsDirectory = "/repo/artifacts/Release", ScratchDirectory = "/repo/.buildvana-temp", ConfigFile = null, - Configuration = new() - { + Configuration = new() { GitHub = new() { TokenEnv = credentialEnvVar }, - NuGet = new() - { - Feeds = new() - { + NuGet = new() { + Feeds = new() { Release = new() { Source = "https://nuget.example/v3/index.json", ApiKeyEnv = credentialEnvVar }, }, }, }, }, - Release = new() - { + Release = new() { Version = "1.2.3", SemVer = "1.2.3", PreviousVersion = null, diff --git a/tests/Buildvana.Runtime.Tests/NuGetFeedConfigExtensionsTests.cs b/tests/Buildvana.Runtime.Tests/NuGetFeedConfigExtensionsTests.cs index 2a6f612f..0594c6fa 100644 --- a/tests/Buildvana.Runtime.Tests/NuGetFeedConfigExtensionsTests.cs +++ b/tests/Buildvana.Runtime.Tests/NuGetFeedConfigExtensionsTests.cs @@ -29,8 +29,7 @@ public async Task GetApiKey_Throws_WhenTheVariableIsMissing() await Assert.That(() => Feed(name).GetApiKey()).Throws(); } - private static NuGetFeedConfig Feed(string apiKeyEnv) => new() - { + private static NuGetFeedConfig Feed(string apiKeyEnv) => new() { Source = "https://nuget.example/v3/index.json", ApiKeyEnv = apiKeyEnv, }; diff --git a/tests/Buildvana.Runtime.Tests/PostReleaseHookArgsTests.cs b/tests/Buildvana.Runtime.Tests/PostReleaseHookArgsTests.cs index 65df50e6..5abb3f64 100644 --- a/tests/Buildvana.Runtime.Tests/PostReleaseHookArgsTests.cs +++ b/tests/Buildvana.Runtime.Tests/PostReleaseHookArgsTests.cs @@ -135,31 +135,25 @@ public async Task Load_UnreadableArgsFile_Throws() } } - private static PostReleaseHookArgs SampleArgs(string home, bool withConfigFile = true) => new() - { - RuntimeInfo = new() - { + private static PostReleaseHookArgs SampleArgs(string home, bool withConfigFile = true) => new() { + RuntimeInfo = new() { Version = "1.2.3-preview", DelegatingVersion = "1.2.4", HomeDirectory = home, ArtifactsDirectory = Path.Combine(home, "artifacts", "Release"), ScratchDirectory = Path.Combine(home, WellKnownPaths.ScratchDirectory), ConfigFile = withConfigFile ? Path.Combine(home, "buildvana.jsonc") : null, - Configuration = new() - { + Configuration = new() { Release = new() { Branches = ["^main$"] }, - DotNet = new() - { - Test = new() - { + DotNet = new() { + Test = new() { Args = ["--coverage"], Env = new Dictionary { ["RUNNER"] = null }, }, }, }, }, - Release = new() - { + Release = new() { Version = "1.2.3", SemVer = "1.2.3-preview", PreviousVersion = null, diff --git a/tests/Buildvana.Sdk.SourceGenerators.Tests/ThisAssemblyClassGeneratorTests.cs b/tests/Buildvana.Sdk.SourceGenerators.Tests/ThisAssemblyClassGeneratorTests.cs index c25497a7..e82c3aaf 100644 --- a/tests/Buildvana.Sdk.SourceGenerators.Tests/ThisAssemblyClassGeneratorTests.cs +++ b/tests/Buildvana.Sdk.SourceGenerators.Tests/ThisAssemblyClassGeneratorTests.cs @@ -10,8 +10,7 @@ internal sealed class ThisAssemblyClassGeneratorTests { private const string ConstantsFilePath = "/obj/Test.ThisAssemblyConstants.txt"; - private static readonly IReadOnlyDictionary ConstantsFileMetadata = new Dictionary - { + private static readonly IReadOnlyDictionary ConstantsFileMetadata = new Dictionary { ["build_metadata.AdditionalFiles.BV_ItemType"] = "ThisAssemblyConstants", }; @@ -86,8 +85,7 @@ public async Task Constants_WithSpecialCharacters_GenerateEscapedLiterals() [Test] public async Task CustomClassNameAndNamespace_AreHonored() { - var globalOptions = new Dictionary - { + var globalOptions = new Dictionary { ["build_property.ThisAssemblyClassName"] = "MyAssemblyInfo", ["build_property.ThisAssemblyClassNamespace"] = "Some.Name.Space", }; diff --git a/tests/Buildvana.Sdk.Tasks.Tests/ComputeVersionTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/ComputeVersionTests.cs index 1df8e7f7..19f80255 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/ComputeVersionTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/ComputeVersionTests.cs @@ -137,8 +137,7 @@ public async Task Execute_AfterConfigurationFileChange_RecomputesVersion() private static ComputeVersion RunTask(TempGitRepo repo, RecordingBuildEngine? engine = null) { - var task = new ComputeVersion - { + var task = new ComputeVersion { BuildEngine = engine ?? new RecordingBuildEngine(), HomeDirectory = repo.RootPath, }; diff --git a/tests/Buildvana.Sdk.Tasks.Tests/ConvertPfxToSnkTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/ConvertPfxToSnkTests.cs index b7b2ea17..df1d162c 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/ConvertPfxToSnkTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/ConvertPfxToSnkTests.cs @@ -16,8 +16,7 @@ internal sealed class ConvertPfxToSnkTests [Test] public async Task Execute_WritesThePrivateKeyOfThePfx() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var (pfxPath, key) = WriteRsaPfx(directory, Password); var outputPath = Path.Combine(directory, "key.snk"); await Assert.That(CreateTask(engine, pfxPath, Password, outputPath).Execute()).IsTrue(); @@ -28,8 +27,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithNoPassword_WritesThePrivateKeyOfThePfx() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var (pfxPath, key) = WriteRsaPfx(directory, null); var outputPath = Path.Combine(directory, "key.snk"); await Assert.That(CreateTask(engine, pfxPath, string.Empty, outputPath).Execute()).IsTrue(); @@ -40,8 +38,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithWrongPassword_LogsBVSDK1201() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var (pfxPath, _) = WriteRsaPfx(directory, Password); var outputPath = Path.Combine(directory, "key.snk"); await Assert.That(CreateTask(engine, pfxPath, "wrong", outputPath).Execute()).IsFalse(); @@ -53,8 +50,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithEcdsaKey_LogsBVSDK1202() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var pfxPath = WriteEcdsaPfx(directory); var outputPath = Path.Combine(directory, "key.snk"); await Assert.That(CreateTask(engine, pfxPath, Password, outputPath).Execute()).IsFalse(); @@ -73,8 +69,7 @@ public async Task Execute_WithMissingPfxPath_LogsBVSDK1050() } private static ConvertPfxToSnk CreateTask(IBuildEngine engine, string pfxPath, string password, string outputPath) - => new() - { + => new() { BuildEngine = engine, PfxPath = pfxPath, PfxPassword = password, diff --git a/tests/Buildvana.Sdk.Tasks.Tests/TaskLoggingHelperReporterTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/TaskLoggingHelperReporterTests.cs index f5670775..909eeef2 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/TaskLoggingHelperReporterTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/TaskLoggingHelperReporterTests.cs @@ -233,8 +233,7 @@ private static (IReporter Reporter, RecordingBuildEngine Engine) CreateReporter( private static (IReporter Reporter, RecordingBuildEngine Engine) CreateReporter( MessageImportance? minimumImportance) { - var engine = new RecordingBuildEngine10 - { + var engine = new RecordingBuildEngine10 { EngineServices = new StubEngineServices { MinimumImportance = minimumImportance }, }; var task = new ReporterProbeTask { BuildEngine = engine }; diff --git a/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs index 501ec713..ec112def 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs @@ -14,8 +14,7 @@ internal sealed class WritePackagePinDumpTests [Test] public async Task Execute_WritesOneItemPerGivenItem() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var task = CreateTask(engine, directory); task.PackageVersions = [Item("Newtonsoft.Json", ("Version", "13.0.3"))]; task.GlobalPackageReferences = [Item("Nerdbank.GitVersioning", ("Version", "3.6.0"))]; @@ -33,11 +32,9 @@ await Assert.That(types).IsEqualTo( [Test] public async Task Execute_ReadsTheMetadataThatDecidesAPin() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var task = CreateTask(engine, directory); - task.PackageVersions = - [ + task.PackageVersions = [ Item( "Serilog", ("Version", "4.0.0"), @@ -58,8 +55,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithMetadataUnstated_WritesNothingForIt() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var task = CreateTask(engine, directory); task.PackageVersions = [Item("Serilog", ("Version", "4.0.0"))]; await Assert.That(task.Execute()).IsTrue(); @@ -75,8 +71,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WritesTheEvaluationItDescribes() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var task = CreateTask(engine, directory); task.TargetFramework = "net10.0"; task.ManagePackageVersionsCentrally = true; @@ -95,8 +90,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithNoTargetFramework_WritesNoneInTheDump() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { await Assert.That(CreateTask(engine, directory).Execute()).IsTrue(); var dump = await ReadDumpAsync(directory).ConfigureAwait(false); await Assert.That(dump.TargetFramework).IsNull(); @@ -108,8 +102,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_WithNoAssetsFileAndNoAuditLevel_WritesNoneForEither() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { await Assert.That(CreateTask(engine, directory).Execute()).IsTrue(); var dump = await ReadDumpAsync(directory).ConfigureAwait(false); await Assert.That(dump.ProjectAssetsFile).IsNull(); @@ -120,8 +113,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_ForTwoTargetFrameworks_WritesTwoFiles() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var first = CreateTask(engine, directory); first.TargetFramework = "net9.0"; var second = CreateTask(engine, directory); @@ -135,8 +127,7 @@ await RunInTempDirectory(async (engine, directory) => [Test] public async Task Execute_ForTwoProjectsOfOneName_WritesTwoFiles() { - await RunInTempDirectory(async (engine, directory) => - { + await RunInTempDirectory(async (engine, directory) => { var first = CreateTask(engine, directory); var second = CreateTask(engine, directory); second.ProjectFullPath = @"C:\repo\other\Test.csproj"; @@ -157,8 +148,7 @@ public async Task Execute_WithMissingOutputDirectory_LogsError() } private static WritePackagePinDump CreateTask(IBuildEngine engine, string outputDirectory) - => new() - { + => new() { BuildEngine = engine, OutputDirectory = outputDirectory, ProjectFullPath = ProjectFullPath, diff --git a/tests/Buildvana.Sdk.Tasks.Tests/WriteThisAssemblyConstantsFileTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/WriteThisAssemblyConstantsFileTests.cs index 97b38633..693dda8b 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/WriteThisAssemblyConstantsFileTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/WriteThisAssemblyConstantsFileTests.cs @@ -10,8 +10,7 @@ internal sealed class WriteThisAssemblyConstantsFileTests [Test] public async Task Execute_WritesEncodedConstants() { - await RunInTempDirectory(async (engine, outputPath) => - { + await RunInTempDirectory(async (engine, outputPath) => { var task = CreateTask(engine, outputPath, ("Answer", "42"), ("My Constant", "string:Hello World"), ("Tricky", "a=b\nc;d")); await Assert.That(task.Execute()).IsTrue(); var content = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); @@ -22,8 +21,7 @@ await RunInTempDirectory(async (engine, outputPath) => [Test] public async Task Execute_TrimsNamesAndValues() { - await RunInTempDirectory(async (engine, outputPath) => - { + await RunInTempDirectory(async (engine, outputPath) => { var task = CreateTask(engine, outputPath, (" Answer ", " 42 ")); await Assert.That(task.Execute()).IsTrue(); var content = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); @@ -34,8 +32,7 @@ await RunInTempDirectory(async (engine, outputPath) => [Test] public async Task Execute_WithNoConstants_WritesEmptyFile() { - await RunInTempDirectory(async (engine, outputPath) => - { + await RunInTempDirectory(async (engine, outputPath) => { var task = CreateTask(engine, outputPath); await Assert.That(task.Execute()).IsTrue(); await Assert.That(File.Exists(outputPath)).IsTrue(); @@ -47,8 +44,7 @@ await RunInTempDirectory(async (engine, outputPath) => [Test] public async Task Execute_WithUnchangedContent_DoesNotRewriteFile() { - await RunInTempDirectory(async (engine, outputPath) => - { + await RunInTempDirectory(async (engine, outputPath) => { await Assert.That(CreateTask(engine, outputPath, ("Answer", "42")).Execute()).IsTrue(); var pastTime = DateTime.UtcNow.AddHours(-1); File.SetLastWriteTimeUtc(outputPath, pastTime); @@ -60,8 +56,7 @@ await RunInTempDirectory(async (engine, outputPath) => [Test] public async Task Execute_WithChangedContent_RewritesFile() { - await RunInTempDirectory(async (engine, outputPath) => - { + await RunInTempDirectory(async (engine, outputPath) => { await Assert.That(CreateTask(engine, outputPath, ("Answer", "42")).Execute()).IsTrue(); await Assert.That(CreateTask(engine, outputPath, ("Answer", "13")).Execute()).IsTrue(); var content = await File.ReadAllTextAsync(outputPath).ConfigureAwait(false); @@ -83,8 +78,7 @@ private static WriteThisAssemblyConstantsFile CreateTask( IBuildEngine engine, string outputPath, params (string Name, string Value)[] constants) - => new() - { + => new() { BuildEngine = engine, OutputPath = outputPath, Constants = [.. constants.Select(c => new TaskItem(c.Name, new Dictionary { ["Value"] = c.Value }))], diff --git a/tests/Buildvana.Sdk.Tests/SdkPropsFixture.cs b/tests/Buildvana.Sdk.Tests/SdkPropsFixture.cs index 8dffd68b..824481a6 100644 --- a/tests/Buildvana.Sdk.Tests/SdkPropsFixture.cs +++ b/tests/Buildvana.Sdk.Tests/SdkPropsFixture.cs @@ -12,8 +12,7 @@ // directory is empty. Evaluation-only: no targets are executed, so assertions are limited to properties and items. internal sealed class SdkPropsFixture : IDisposable { - private static readonly string[] StubFileNames = - [ + private static readonly string[] StubFileNames = [ "SdkVersion.props", "ImportConfiguration.props", "PackageVersions.props", @@ -25,8 +24,7 @@ internal sealed class SdkPropsFixture : IDisposable "Import.AfterCommon.targets.proj", ]; - private static readonly string[] ProjectTypeProperties = - [ + private static readonly string[] ProjectTypeProperties = [ "BV_IsFileBasedAppProject", "BV_IsNoTargetsProject", "BV_IsTestProject", diff --git a/tests/Buildvana.Tool.Tests/AdditionalGroupPinReaderTests.cs b/tests/Buildvana.Tool.Tests/AdditionalGroupPinReaderTests.cs index 2f06c55f..b4157e28 100644 --- a/tests/Buildvana.Tool.Tests/AdditionalGroupPinReaderTests.cs +++ b/tests/Buildvana.Tool.Tests/AdditionalGroupPinReaderTests.cs @@ -138,8 +138,7 @@ public async Task ReadAsync_WhenEvaluationFails_ReportsAFailedStep() { using var home = new TempHome(); Write(home, GroupFile, GroupFileContent); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (executable, _) => new ProcessResult(executable, 1, "error MSB4025: no.", string.Empty, TimeSpan.Zero), }; @@ -155,14 +154,10 @@ private static Task> ReadAsync(TempHome home, IProc private static AdditionalGroupPinReader CreateReader(TempHome home, IProcessRunner runner) { - var config = new BuildvanaConfig - { - Dependencies = new DependenciesConfig - { - AdditionalPackages = - [ - new AdditionalPackagesConfig - { + var config = new BuildvanaConfig { + Dependencies = new DependenciesConfig { + AdditionalPackages = [ + new AdditionalPackagesConfig { Caption = "SDK package injections", Files = "src/Sdk/PackageVersions.props", Items = "BV_PackageVersion", @@ -195,8 +190,7 @@ private static FakeProcessRunner Answer( { "Items": { "BV_PackageVersion": [ {{string.Join(",", elements)}} ] } } """; - return new FakeProcessRunner - { + return new FakeProcessRunner { OnRun = (executable, _) => new ProcessResult(executable, 0, output, string.Empty, TimeSpan.Zero), }; } diff --git a/tests/Buildvana.Tool.Tests/AdvisoryIndexTests.cs b/tests/Buildvana.Tool.Tests/AdvisoryIndexTests.cs index e92d8494..618c691a 100644 --- a/tests/Buildvana.Tool.Tests/AdvisoryIndexTests.cs +++ b/tests/Buildvana.Tool.Tests/AdvisoryIndexTests.cs @@ -10,8 +10,7 @@ internal sealed class AdvisoryIndexTests [Test] public async Task For_AnIdWithAdvisories_HasThemAll() { - var index = new AdvisoryIndex( - [ + var index = new AdvisoryIndex([ ("Newtonsoft.Json", Advisory("(, 12.0.3)")), ("Serilog", Advisory("(, 2.0.0)")), ("Newtonsoft.Json", Advisory("(, 13.0.1)")), diff --git a/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs b/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs index d24e97d2..5ea85cb8 100644 --- a/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs +++ b/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs @@ -181,8 +181,7 @@ public async Task RewriteVersions_SplicesOnlyTheVersionTexts() Console.WriteLine("#:package Fake@9.9.9"); """; var path = WriteFile(home, content); - var newVersions = new Dictionary - { + var newVersions = new Dictionary { ["Buildvana.Sdk"] = "1.0.1", ["Buildvana.Runtime"] = "1.0.1", ["Fake"] = "0.0.1", @@ -215,8 +214,7 @@ public async Task RewriteVersions_OffersOnlyVersionedDirectives() var path = WriteFile(home, content); var offered = new List(); - var changed = AppDirectiveEditor.RewriteVersions(path, d => - { + var changed = AppDirectiveEditor.RewriteVersions(path, d => { offered.Add(d); return null; }); diff --git a/tests/Buildvana.Tool.Tests/ChangelogUpdaterTests.cs b/tests/Buildvana.Tool.Tests/ChangelogUpdaterTests.cs index fc8e5e4d..206ea69f 100644 --- a/tests/Buildvana.Tool.Tests/ChangelogUpdaterTests.cs +++ b/tests/Buildvana.Tool.Tests/ChangelogUpdaterTests.cs @@ -12,8 +12,7 @@ internal sealed class ChangelogUpdaterTests [Test] public async Task HasUnreleasedChanges_IsFalseWhenSectionIsEmpty() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -31,8 +30,7 @@ public async Task HasUnreleasedChanges_IsFalseWhenSectionIsEmpty() [Test] public async Task HasUnreleasedChanges_IsTrueWhenSectionHasContent() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -52,8 +50,7 @@ public async Task HasUnreleasedChanges_IsTrueWhenSectionHasContent() [Test] public async Task HasUnreleasedChanges_IsFalseWhenEmptySectionEndsTheFile() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -78,8 +75,7 @@ public async Task HasUnreleasedChanges_FailsWhenThereAreNoSections() [Test] public async Task PrepareForRelease_MovesUnreleasedContentToNewSection() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -115,8 +111,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_RecreatesSubsectionsAndMovesOnlyNonEmptyOnes() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -159,8 +154,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_SubstitutesConfiguredTextForEmptySection() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -194,8 +188,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_SubstitutesConfiguredTextWhenNewSectionIsLast() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -221,8 +214,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_MovesEmptySectionVerbatimWithoutSubstitute() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -251,8 +243,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_IgnoresWhitespaceOnlySubstitute() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -280,8 +271,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_TrimsTrailingBlankLinesWhenNewSectionIsLast() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -311,8 +301,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task PrepareForRelease_UsesLineFeedAsLineSeparator() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -358,8 +347,7 @@ string MakeSectionTitle() [Test] public async Task FinalizeNewSection_ReplacesTitleOfSectionAfterUnreleasedChanges() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -398,8 +386,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task FinalizeNewSection_PinsRelativeFileLinksToTheReleaseTag() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -437,8 +424,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task FinalizeNewSection_LeavesUrlsAndAnchorsAlone() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -464,8 +450,7 @@ public async Task FinalizeNewSection_LeavesUrlsAndAnchorsAlone() [Test] public async Task FinalizeNewSection_PinsLinksOfTheNewSectionOnly() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -507,8 +492,7 @@ await Assert.That(result).IsEqualTo( [Test] public async Task FinalizeNewSection_PassesThePathWithoutItsAnchorToGetFileUrl() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -527,8 +511,7 @@ public async Task FinalizeNewSection_PassesThePathWithoutItsAnchorToGetFileUrl() [Test] public async Task FinalizeNewSection_FailsWhenThereIsOnlyOneSection() { - string[] lines = - [ + string[] lines = [ "# Changelog", string.Empty, "## Unreleased changes", @@ -612,8 +595,7 @@ private static string FinalizeNewSection(string[] lines) // Records the path of each link the updater asks a URL for, so that a test can see what reached the callback. private static Func RecordingGetFileUrl(List paths) - => path => - { + => path => { paths.Add(path); return GetFileUrl(path); }; diff --git a/tests/Buildvana.Tool.Tests/CommandPagesTests.cs b/tests/Buildvana.Tool.Tests/CommandPagesTests.cs index a75e31a9..981dea15 100644 --- a/tests/Buildvana.Tool.Tests/CommandPagesTests.cs +++ b/tests/Buildvana.Tool.Tests/CommandPagesTests.cs @@ -19,8 +19,7 @@ internal sealed class CommandPagesTests // The page under docs/tool-commands of each top-level command name. A group page holds one "Options" table // for all of its subcommands, with a "Subcommand" column. - private static readonly Dictionary Pages = new(StringComparer.Ordinal) - { + private static readonly Dictionary Pages = new(StringComparer.Ordinal) { ["clean"] = "build-pipeline.md", ["restore"] = "build-pipeline.md", ["build"] = "build-pipeline.md", diff --git a/tests/Buildvana.Tool.Tests/DelegationServiceTests.cs b/tests/Buildvana.Tool.Tests/DelegationServiceTests.cs index 44d8fd6a..2d4acd77 100644 --- a/tests/Buildvana.Tool.Tests/DelegationServiceTests.cs +++ b/tests/Buildvana.Tool.Tests/DelegationServiceTests.cs @@ -304,8 +304,7 @@ public async Task TryDelegate_WithDifferentVersionInstalled_RestoresFirst() public async Task TryDelegate_StreamsRestoreOutput() { using var home = CreateDelegatableHome("2.1.40-preview"); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (executable, args) => new ProcessResult($"{executable} {string.Join(' ', args)}", 0, "Restored bv.\nRestored ngbv.", string.Empty, TimeSpan.Zero), }; var output = new StringWriter(); @@ -324,8 +323,7 @@ public async Task TryDelegate_StreamsRestoreOutput() public async Task TryDelegate_WhenRestoreFails_WarnsAndRunsAnyway() { using var home = CreateDelegatableHome("2.1.40-preview"); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (executable, args) => new ProcessResult($"{executable} {string.Join(' ', args)}", 1, string.Empty, "simulated failure", TimeSpan.Zero), OnRunWithInheritedStdio = static (_, _) => 42, }; diff --git a/tests/Buildvana.Tool.Tests/DependencyDiscoveryTests.cs b/tests/Buildvana.Tool.Tests/DependencyDiscoveryTests.cs index 7fe64dd7..9c156810 100644 --- a/tests/Buildvana.Tool.Tests/DependencyDiscoveryTests.cs +++ b/tests/Buildvana.Tool.Tests/DependencyDiscoveryTests.cs @@ -105,18 +105,14 @@ private static void WriteRepository(TempHome home) } private static Func, ProcessResult> WriteDump(TempHome home) - => (executable, args) => - { + => (executable, args) => { const string prefix = "-property:BV_PinDumpDirectory="; var directory = args.Single(arg => arg.StartsWith(prefix, StringComparison.Ordinal))[prefix.Length..]; var projectPath = home.GetFullPath("src/App/App.csproj"); - var dump = new PackagePinDump - { + var dump = new PackagePinDump { ProjectFullPath = projectPath, - Items = - [ - new PackagePinDumpItem - { + Items = [ + new PackagePinDumpItem { ItemType = "PackageReference", Id = "Serilog", Version = "4.0.0", diff --git a/tests/Buildvana.Tool.Tests/DependencyReportRendererTests.cs b/tests/Buildvana.Tool.Tests/DependencyReportRendererTests.cs index 745eaa4a..caa472e7 100644 --- a/tests/Buildvana.Tool.Tests/DependencyReportRendererTests.cs +++ b/tests/Buildvana.Tool.Tests/DependencyReportRendererTests.cs @@ -13,8 +13,7 @@ internal sealed class DependencyReportRendererTests [Test] public async Task Write_StatesEveryPinWithItsPolicy() { - var inventory = new DependencyInventory - { + var inventory = new DependencyInventory { NetSdk = NetSdkPin.Create("10.0.100", allowPrerelease: false), Tools = [DependencyPin.Create(DependencyScope.Tools, "ngbv", "0.5.1", "dotnet-tools.json")], Packages = [DependencyPin.Create(DependencyScope.Packages, "Serilog", "4.0.0", "Directory.Packages.props")], @@ -95,8 +94,9 @@ public async Task Write_WhenAllowPrereleaseDisagreesWithThePolicy_SaysSo() [Test] public async Task Write_StatesAGroupsPinsUnderItsCaption() { - var pin = DependencyPin.Create(DependencyScope.Packages, "StyleCop.Analyzers", "1.2.0", "src/Sdk/PackageVersions.props") - with { GroupCaption = "SDK package injections" }; + var pin = DependencyPin.Create(DependencyScope.Packages, "StyleCop.Analyzers", "1.2.0", "src/Sdk/PackageVersions.props") with { + GroupCaption = "SDK package injections", + }; var output = Render(new DependencyInventory { Packages = [pin] }, [DependencyScope.Packages]); await Assert.That(output).Contains("NuGet packages: SDK package injections"); await Assert.That(output).Contains("StyleCop.Analyzers"); @@ -108,8 +108,7 @@ public async Task Write_StatesAGroupsPinsUnderItsCaption() [Test] public async Task WriteOverrides_StatesEachEntryUnderTheFileThatHoldsIt() { - var output = RenderOverrides( - [ + var output = RenderOverrides([ new TransitiveOverrideEntry("Newtonsoft.Json", "13.0.3", "Directory.TransitiveOverrides.props"), new TransitiveOverrideEntry("Serilog", null, "src/Test/Test.TransitiveOverrides.props"), ]); @@ -128,8 +127,7 @@ public async Task WriteOverrides_WithNone_SaysSo() [Test] public async Task WritePrune_StatesEveryOrphanUnderItsFile() { - var orphans = new[] - { + var orphans = new[] { DependencyPin.Create(DependencyScope.Packages, "Serilog", "3.0.0", "Directory.Packages.props"), DependencyPin.Create(DependencyScope.Packages, "Newtonsoft.Json", "13.0.3", "Directory.Packages.props"), }; diff --git a/tests/Buildvana.Tool.Tests/DependencyResolutionTests.cs b/tests/Buildvana.Tool.Tests/DependencyResolutionTests.cs index 1d014299..a8552cd3 100644 --- a/tests/Buildvana.Tool.Tests/DependencyResolutionTests.cs +++ b/tests/Buildvana.Tool.Tests/DependencyResolutionTests.cs @@ -70,8 +70,7 @@ public async Task Skipping_HasNoPendingWork() [Test] public async Task Skipping_StatesThePolicyGoverningEachPin() { - var config = new DependenciesConfig - { + var config = new DependenciesConfig { Policies = [new UpdatePolicyRule { Pattern = "Alpha", Policy = "patch" }], }; @@ -84,13 +83,11 @@ public async Task Skipping_StatesThePolicyGoverningEachPin() } private static DependencyInventory Inventory() - => new() - { + => new() { NetSdk = NetSdkPin.Create("10.0.100", allowPrerelease: false), Sdks = [Pin(DependencyScope.Sdks, "Contoso.Sdk", "global.json")], Tools = [Pin(DependencyScope.Tools, "ngbv", "dotnet-tools.json")], - Packages = - [ + Packages = [ Pin(DependencyScope.Packages, "Alpha", CentralPinFileName), Pin(DependencyScope.Packages, "Beta", CentralPinFileName), ], diff --git a/tests/Buildvana.Tool.Tests/DependencyScopeSelectionTests.cs b/tests/Buildvana.Tool.Tests/DependencyScopeSelectionTests.cs index 34548007..4c197341 100644 --- a/tests/Buildvana.Tool.Tests/DependencyScopeSelectionTests.cs +++ b/tests/Buildvana.Tool.Tests/DependencyScopeSelectionTests.cs @@ -115,10 +115,8 @@ public async Task Resolve_ExcludingADisabledScope_SaysNothing() [Test] public async Task Resolve_WithAllScopesDisabled_TakesNone() { - var config = new DependenciesConfig - { - Scopes = new DependencyScopesConfig - { + var config = new DependenciesConfig { + Scopes = new DependencyScopesConfig { NetSdk = "disable", Sdks = "disable", Tools = "disable", diff --git a/tests/Buildvana.Tool.Tests/DependencyUpdateReportTests.cs b/tests/Buildvana.Tool.Tests/DependencyUpdateReportTests.cs index c27d12a5..19882a5a 100644 --- a/tests/Buildvana.Tool.Tests/DependencyUpdateReportTests.cs +++ b/tests/Buildvana.Tool.Tests/DependencyUpdateReportTests.cs @@ -29,8 +29,7 @@ public async Task WriteUpdate_StatesTheTargetAndWhatLiesBeyondIt() public async Task WriteUpdate_AtEightyColumns_BreaksNoNameAndNoVersion() { var pin = DependencyPin.Create(DependencyScope.Packages, "Microsoft.Build.NoTargets", "3.7.134", "Directory.Packages.props"); - var resolution = Packages(new PinResolution - { + var resolution = Packages(new PinResolution { Pin = pin, Policy = Policy("minor"), State = PinResolutionState.UpToDate, @@ -75,8 +74,7 @@ public async Task WriteUpdate_AskedForEveryPin_ListsTheUpToDateOnes() public async Task WriteUpdate_StatesWhyAPinDoesNotMove() { var pin = DependencyPin.Create(DependencyScope.Packages, "Serilog", "[3.0.0]", "Directory.Packages.props"); - var resolution = Packages(new PinResolution - { + var resolution = Packages(new PinResolution { Pin = pin, Policy = Policy("minor"), State = PinResolutionState.Unmanaged, @@ -92,10 +90,8 @@ public async Task WriteUpdate_StatesWhyAPinDoesNotMove() [Test] public async Task WriteUpdate_ListsTheNetSdkWhenOnlyAllowPrereleaseWouldChange() { - var resolution = new DependencyResolution - { - NetSdk = new NetSdkResolution - { + var resolution = new DependencyResolution { + NetSdk = new NetSdkResolution { Pin = NetSdkPin.Create("10.0.100", allowPrerelease: null), Policy = NetSdkPolicy("major"), State = PinResolutionState.UpToDate, @@ -139,10 +135,8 @@ public async Task WriteUpdate_StatesAGroupsPinsUnderItsCaption() [Test] public async Task WriteUpdate_OfEveryScope_StatesThemAll() { - var resolution = new DependencyResolution - { - NetSdk = new NetSdkResolution - { + var resolution = new DependencyResolution { + NetSdk = new NetSdkResolution { Pin = NetSdkPin.Create("10.0.100", allowPrerelease: false), Policy = NetSdkPolicy("major"), State = PinResolutionState.Updated, @@ -174,8 +168,7 @@ private static NetSdkUpdatePolicy NetSdkPolicy(string text) } private static PinResolution Moving(string id, string from, string to, string? latestStable = null) - => new() - { + => new() { Pin = DependencyPin.Create(DependencyScope.Packages, id, from, "Directory.Packages.props"), Policy = Policy("minor"), State = PinResolutionState.Updated, @@ -184,8 +177,7 @@ private static PinResolution Moving(string id, string from, string to, string? l }; private static PinResolution UpToDate(string id, string version) - => new() - { + => new() { Pin = DependencyPin.Create(DependencyScope.Packages, id, version, "Directory.Packages.props"), Policy = Policy("minor"), State = PinResolutionState.UpToDate, diff --git a/tests/Buildvana.Tool.Tests/DotNetReleaseIndexTests.cs b/tests/Buildvana.Tool.Tests/DotNetReleaseIndexTests.cs index 974eac0d..cb2d3eea 100644 --- a/tests/Buildvana.Tool.Tests/DotNetReleaseIndexTests.cs +++ b/tests/Buildvana.Tool.Tests/DotNetReleaseIndexTests.cs @@ -142,8 +142,7 @@ await Assert.That(async () => await index.GetReleasesAsync(NuGetVersion.Parse("1 } private static StubHttpMessageHandler NewHandler() - => new(new Dictionary - { + => new(new Dictionary { [DotNetReleaseIndex.IndexUrl] = Index, [ChannelUrl11] = Channel11, [ChannelUrl10] = Channel10, diff --git a/tests/Buildvana.Tool.Tests/DotNetServicePushFeedTests.cs b/tests/Buildvana.Tool.Tests/DotNetServicePushFeedTests.cs index 4cd8c532..8c51a02d 100644 --- a/tests/Buildvana.Tool.Tests/DotNetServicePushFeedTests.cs +++ b/tests/Buildvana.Tool.Tests/DotNetServicePushFeedTests.cs @@ -10,14 +10,12 @@ // both. What is left to resolve is which channel a version pushes to. internal sealed class DotNetServicePushFeedTests { - private static readonly NuGetFeedConfig PrereleaseFeed = new() - { + private static readonly NuGetFeedConfig PrereleaseFeed = new() { Source = "https://prerelease.example/v3/index.json", ApiKeyEnv = "BV_TEST_PRERELEASE_API_KEY", }; - private static readonly NuGetFeedConfig ReleaseFeed = new() - { + private static readonly NuGetFeedConfig ReleaseFeed = new() { Source = "https://release.example/v3/index.json", ApiKeyEnv = "BV_TEST_RELEASE_API_KEY", }; diff --git a/tests/Buildvana.Tool.Tests/EffectivePolicyResolverTests.cs b/tests/Buildvana.Tool.Tests/EffectivePolicyResolverTests.cs index 07825b98..6573fdf3 100644 --- a/tests/Buildvana.Tool.Tests/EffectivePolicyResolverTests.cs +++ b/tests/Buildvana.Tool.Tests/EffectivePolicyResolverTests.cs @@ -20,8 +20,7 @@ public async Task Resolve_WithNothingStated_TakesTheScopeDefault() [Test] public async Task Resolve_TakesTheScopeOfThePin() { - var config = new DependenciesConfig - { + var config = new DependenciesConfig { Scopes = new DependencyScopesConfig { NetSdk = "lts", Sdks = "patch", Tools = "major-", Packages = "exact" }, }; @@ -35,10 +34,8 @@ public async Task Resolve_TakesTheScopeOfThePin() [Test] public async Task Resolve_TakesTheFirstMatchingPattern() { - var config = new DependenciesConfig - { - Policies = - [ + var config = new DependenciesConfig { + Policies = [ new UpdatePolicyRule { Pattern = "Serilog", Policy = "patch" }, new UpdatePolicyRule { Pattern = "Serilog*", Policy = "major" }, ], @@ -53,8 +50,7 @@ public async Task Resolve_TakesTheFirstMatchingPattern() [Test] public async Task Resolve_AppliesPatternsToEveryIdShapedScope() { - var config = new DependenciesConfig - { + var config = new DependenciesConfig { Policies = [new UpdatePolicyRule { Pattern = "*", Policy = "patch-" }], }; @@ -75,8 +71,7 @@ public async Task Resolve_OfAGroupPin_TakesTheGroupPolicy() [Test] public async Task Resolve_OfAGroupPinMatchedByAPattern_TakesThePattern() { - var config = GroupConfig("revision") with - { + var config = GroupConfig("revision") with { Policies = [new UpdatePolicyRule { Pattern = "Serilog", Policy = "exact" }], }; @@ -89,8 +84,7 @@ public async Task Resolve_OfAGroupPinMatchedByAPattern_TakesThePattern() [Test] public async Task Resolve_OfAPinStatingItsOwnPolicy_TakesIt() { - var config = GroupConfig("revision") with - { + var config = GroupConfig("revision") with { Policies = [new UpdatePolicyRule { Pattern = "*", Policy = "exact" }], }; @@ -118,12 +112,9 @@ private static DependencyPin Pin(DependencyScope scope, string id = "Serilog") => DependencyPin.Create(scope, id, "4.0.0", "Directory.Packages.props"); private static DependenciesConfig GroupConfig(string policy) - => new() - { - AdditionalPackages = - [ - new AdditionalPackagesConfig - { + => new() { + AdditionalPackages = [ + new AdditionalPackagesConfig { Caption = "SDK package injections", Files = "src/Sdk/PackageVersions.props", Items = "BV_PackageVersion", diff --git a/tests/Buildvana.Tool.Tests/FakePackageVersionSource.cs b/tests/Buildvana.Tool.Tests/FakePackageVersionSource.cs index a9510084..c2b29c4f 100644 --- a/tests/Buildvana.Tool.Tests/FakePackageVersionSource.cs +++ b/tests/Buildvana.Tool.Tests/FakePackageVersionSource.cs @@ -26,8 +26,7 @@ internal sealed class FakePackageVersionSource : IPackageVersionSource /// This instance, for chaining. public FakePackageVersionSource Knows(string id, string[] listed, string[]? unlisted = null) { - _catalogs[id] = new PackageVersionCatalog - { + _catalogs[id] = new PackageVersionCatalog { Listed = [.. listed.Select(NuGetVersion.Parse)], Unlisted = [.. (unlisted ?? []).Select(NuGetVersion.Parse)], }; diff --git a/tests/Buildvana.Tool.Tests/FamilyPinUpdaterTests.cs b/tests/Buildvana.Tool.Tests/FamilyPinUpdaterTests.cs index dddbc617..0cadd828 100644 --- a/tests/Buildvana.Tool.Tests/FamilyPinUpdaterTests.cs +++ b/tests/Buildvana.Tool.Tests/FamilyPinUpdaterTests.cs @@ -50,8 +50,7 @@ public async Task DiscoverPins_FindsFamilyPinsAcrossFileKinds() // Walk order: depth-first, each directory's entries ordinally sorted. The versionless directive and // the non-family ids contribute nothing. var rendered = pins.Select(static p => $"{p.RelativePath}|{p.Id}|{p.VersionText}|{p.Version?.ToNormalizedString()}"); - await Assert.That(rendered).IsEquivalentTo( - [ + await Assert.That(rendered).IsEquivalentTo([ ".buildvana/hooks/hook.cs|Buildvana.Sdk|2.1.40-preview|2.1.40-preview", ".buildvana/hooks/hook.cs|Buildvana.Runtime|2.1.40-preview|2.1.40-preview", "Directory.Packages.props|Buildvana.Runtime|2.1.40-preview|2.1.40-preview", @@ -184,8 +183,7 @@ public async Task StampPins_LeavesNonLiteralAndEqualPinsAlone() var lines = updater.StampPins(pins, NuGetVersion.Parse("2.1.41-preview")); await Assert.That(home.ReadFile("Directory.Packages.props")).IsEqualTo(before); - await Assert.That(lines).IsEquivalentTo( - [ + await Assert.That(lines).IsEquivalentTo([ "Buildvana.Runtime: $(BuildvanaVersion) (Directory.Packages.props, left alone)", "Buildvana.Sdk: 2.1.41-preview (Directory.Packages.props, unchanged)", ]); @@ -219,8 +217,7 @@ public async Task StampPins_RewritesDirectiveVersionsOnly() Console.WriteLine("2.1.40-preview"); """; await Assert.That(home.ReadFile(Path.Combine(".buildvana", "hooks", "hook.cs"))).IsEqualTo(after); - await Assert.That(lines).IsEquivalentTo( - [ + await Assert.That(lines).IsEquivalentTo([ "Buildvana.Sdk: 2.1.40-preview -> 2.1.41-preview (.buildvana/hooks/hook.cs)", "Buildvana.Runtime: 2.1.40-preview -> 2.1.41-preview (.buildvana/hooks/hook.cs)", ]); @@ -386,12 +383,9 @@ public async Task DiscoverPins_WithAGroupNamingABuiltInItemType_ReportsEachPinOn private static BuildvanaConfig ConfigWithGroupItemName(string itemName) { - var json = new BuildvanaJsonConfig - { - Dependencies = new() - { - AdditionalPackages = - [ + var json = new BuildvanaJsonConfig { + Dependencies = new() { + AdditionalPackages = [ new() { Caption = "SDK-injected packages", Files = "PackageVersions.props", Items = itemName }, ], }, diff --git a/tests/Buildvana.Tool.Tests/FileBasedAppHelperTests.cs b/tests/Buildvana.Tool.Tests/FileBasedAppHelperTests.cs index ccb58318..7207fb36 100644 --- a/tests/Buildvana.Tool.Tests/FileBasedAppHelperTests.cs +++ b/tests/Buildvana.Tool.Tests/FileBasedAppHelperTests.cs @@ -77,8 +77,7 @@ public async Task GetArtifactsDirectory_AgreesWithInstalledSdk(CancellationToken { // --getProperty with no explicit target puts the CLI in evaluation-only mode; `dotnet clean` // would instead forward -t:Clean and actually run the target. - var startInfo = new ProcessStartInfo("dotnet") - { + var startInfo = new ProcessStartInfo("dotnet") { ArgumentList = { "build", appPath, "--getProperty:ArtifactsPath" }, WorkingDirectory = Path.GetTempPath(), RedirectStandardOutput = true, diff --git a/tests/Buildvana.Tool.Tests/GitServiceTests.cs b/tests/Buildvana.Tool.Tests/GitServiceTests.cs index 6badab62..8e97e251 100644 --- a/tests/Buildvana.Tool.Tests/GitServiceTests.cs +++ b/tests/Buildvana.Tool.Tests/GitServiceTests.cs @@ -79,8 +79,7 @@ public async Task TrackChangesAsync_ReportsFilesModifiedByOperation_AsAbsolutePa using var git = CreateGitService(repo); var rootPath = repo.RootPath; - var (_, changedFiles) = await git.TrackChangesAsync(async () => - { + var (_, changedFiles) = await git.TrackChangesAsync(async () => { await File.WriteAllTextAsync(Path.Combine(rootPath, "b.txt"), "new file").ConfigureAwait(false); await File.WriteAllTextAsync(Path.Combine(rootPath, "c.txt"), "another new file").ConfigureAwait(false); return true; @@ -100,8 +99,7 @@ public async Task TrackChangesAsync_ExcludesFilesAlreadyDirtyBeforeOperation() var rootPath = repo.RootPath; repo.WriteFile("a.txt", "dirty before the operation"); - var (_, changedFiles) = await git.TrackChangesAsync(async () => - { + var (_, changedFiles) = await git.TrackChangesAsync(async () => { await File.WriteAllTextAsync(Path.Combine(rootPath, "a.txt"), "dirty again during the operation").ConfigureAwait(false); await File.WriteAllTextAsync(Path.Combine(rootPath, "b.txt"), "new file").ConfigureAwait(false); return true; diff --git a/tests/Buildvana.Tool.Tests/HookRunnerTests.cs b/tests/Buildvana.Tool.Tests/HookRunnerTests.cs index 5ed6c27c..c12204fe 100644 --- a/tests/Buildvana.Tool.Tests/HookRunnerTests.cs +++ b/tests/Buildvana.Tool.Tests/HookRunnerTests.cs @@ -112,8 +112,7 @@ public async Task RunHookAsync_WhenHookFails_PropagatesAndLeavesArgsFile() { using var home = new TempHome(); _ = WriteHookFile(home, "release", "post-release"); - var appRunner = new FakeFileBasedAppRunner - { + var appRunner = new FakeFileBasedAppRunner { OnRun = (_, _, _) => throw new BuildFailedException("Hook failed."), }; var runner = new HookRunner(NullReporter.Instance, home.Provider, appRunner); @@ -231,10 +230,8 @@ public async Task CleanBuildCaches_DeletesArtifactsOfEveryHookFileRecursively() private static string ArgsPath(TempHome home) => Path.GetFullPath(WellKnownPaths.GetHookArgsFile("release", "post-release"), home.RootPath); - private static PostReleaseHookArgs SampleArgs(TempHome home) => new() - { - RuntimeInfo = new() - { + private static PostReleaseHookArgs SampleArgs(TempHome home) => new() { + RuntimeInfo = new() { Version = "1.2.3-preview", DelegatingVersion = null, HomeDirectory = home.RootPath, @@ -243,8 +240,7 @@ private static string ArgsPath(TempHome home) ConfigFile = null, Configuration = new(), }, - Release = new() - { + Release = new() { Version = "1.2.3", SemVer = "1.2.3-preview", PreviousVersion = null, diff --git a/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs b/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs index 1c365bd0..ee8b1fb8 100644 --- a/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs +++ b/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs @@ -365,8 +365,7 @@ public async Task RewritePins_SplicesOnlyTheVersions() """; var path = WriteFile(home, content); - var newVersions = new Dictionary - { + var newVersions = new Dictionary { ["Alpha"] = "1.0.1", ["Beta"] = "2.0.1", ["Gamma"] = "9.9.10", diff --git a/tests/Buildvana.Tool.Tests/NetSdkPinWriterTests.cs b/tests/Buildvana.Tool.Tests/NetSdkPinWriterTests.cs index 6a45e427..3886d88b 100644 --- a/tests/Buildvana.Tool.Tests/NetSdkPinWriterTests.cs +++ b/tests/Buildvana.Tool.Tests/NetSdkPinWriterTests.cs @@ -102,8 +102,7 @@ private static NetSdkResolution Resolution(string version, bool? stated, string? { _ = NetSdkUpdatePolicy.TryParse(policy, out var parsed); var pin = NetSdkPin.Create(version, stated); - return new NetSdkResolution - { + return new NetSdkResolution { Pin = pin, Policy = parsed, State = target is null ? PinResolutionState.UpToDate : PinResolutionState.Updated, diff --git a/tests/Buildvana.Tool.Tests/OrphanDetectorTests.cs b/tests/Buildvana.Tool.Tests/OrphanDetectorTests.cs index d9796762..db328c8a 100644 --- a/tests/Buildvana.Tool.Tests/OrphanDetectorTests.cs +++ b/tests/Buildvana.Tool.Tests/OrphanDetectorTests.cs @@ -203,8 +203,7 @@ private static DependencyInventory Inventory( IReadOnlyList? directiveReferences = null, string itemType = "PackageVersion", bool evaluated = true) - => new() - { + => new() { Packages = [.. pinnedIds.Select(id => Pin(id, itemType))], DirectiveReferences = directiveReferences ?? [], Evaluations = evaluated ? [Evaluation(home)] : [], @@ -214,8 +213,7 @@ private static DependencyPin Pin(string id, string itemType) => DependencyPin.Create(DependencyScope.Packages, id, "1.0.0", CentralPinFileName) with { ItemType = itemType }; private static PackagePinDump Evaluation(TempHome home) - => new() - { + => new() { ProjectFullPath = home.GetFullPath(ProjectPath), ProjectAssetsFile = home.GetFullPath(AssetsPath), TargetFramework = "net10.0", diff --git a/tests/Buildvana.Tool.Tests/OverrideLifecycleTests.cs b/tests/Buildvana.Tool.Tests/OverrideLifecycleTests.cs index 928aab93..169d2e25 100644 --- a/tests/Buildvana.Tool.Tests/OverrideLifecycleTests.cs +++ b/tests/Buildvana.Tool.Tests/OverrideLifecycleTests.cs @@ -148,8 +148,7 @@ public async Task RunAsync_KeepsAnOverrideALaterPassNoLongerReports() { using var home = NewHome(Finding("12.0.1")); var restorer = new FakeDependencyRestorer(); - restorer.OnRestore = suppressed => - { + restorer.OnRestore = suppressed => { if (suppressed) { return 0; @@ -224,10 +223,8 @@ public async Task RunAsync_WhenTheGraphNeverSettles_ReportsAFailedStep() { using var home = NewHome(NeverSettling(1)); var pass = 1; - var restorer = new FakeDependencyRestorer - { - OnRestore = suppressed => - { + var restorer = new FakeDependencyRestorer { + OnRestore = suppressed => { if (suppressed) { return 0; @@ -331,8 +328,7 @@ private static IReadOnlyList Removed(string? centralPin, bool rem return []; } - var pin = DependencyPin.Create(DependencyScope.Packages, Vulnerable, centralPin, CentralPinFileName) with - { + var pin = DependencyPin.Create(DependencyScope.Packages, Vulnerable, centralPin, CentralPinFileName) with { ItemType = "PackageVersion", }; @@ -348,13 +344,11 @@ private static IReadOnlyList Moved(string? centralPin, string? mo return []; } - var pin = DependencyPin.Create(DependencyScope.Packages, Vulnerable, centralPin, movedIn) with - { + var pin = DependencyPin.Create(DependencyScope.Packages, Vulnerable, centralPin, movedIn) with { ItemType = "PackageVersion", }; - var resolution = new PinResolution - { + var resolution = new PinResolution { Pin = pin, Policy = new PackageUpdatePolicy(PackageUpdatePolicyKind.Minor, AllowPrerelease: false), State = PinResolutionState.Updated, @@ -366,16 +360,14 @@ private static IReadOnlyList Moved(string? centralPin, string? mo private static PackagePinDump Evaluation(TempHome home, bool managesCentrally, string? centralPin) { - var pin = new PackagePinDumpItem - { + var pin = new PackagePinDumpItem { ItemType = "PackageVersion", Id = Vulnerable, Version = centralPin, DefiningProjectFullPath = home.GetFullPath(CentralPinFileName), }; - return new PackagePinDump - { + return new PackagePinDump { ProjectFullPath = home.GetFullPath(ProjectPath), ProjectAssetsFile = home.GetFullPath(AssetsPath), TargetFramework = "net10.0", diff --git a/tests/Buildvana.Tool.Tests/OverrideSelectorTests.cs b/tests/Buildvana.Tool.Tests/OverrideSelectorTests.cs index 5807d3f6..d7bdb889 100644 --- a/tests/Buildvana.Tool.Tests/OverrideSelectorTests.cs +++ b/tests/Buildvana.Tool.Tests/OverrideSelectorTests.cs @@ -30,8 +30,7 @@ public async Task Select_SkipsAVersionAnotherAdvisoryCovers() [Test] public async Task Select_IgnoresAnAdvisoryBelowTheProjectsAuditLevel() { - var request = Request("12.0.1", ["12.0.1", "12.0.3"], Advisory("(, 12.0.2]", PackageVulnerabilitySeverity.Low)) with - { + var request = Request("12.0.1", ["12.0.1", "12.0.3"], Advisory("(, 12.0.2]", PackageVulnerabilitySeverity.Low)) with { AuditLevel = PackageVulnerabilitySeverity.High, }; @@ -103,8 +102,7 @@ public async Task Select_ACentralPinAboveTheResolvedVersion_IsPromotedWithNoVers [Test] public async Task Select_ACentralPinBelowTheResolvedVersion_IsBlocked() { - var request = Request("12.0.2", ["12.0.1", "12.0.2", "12.0.3"], Advisory("(, 12.0.2]")) with - { + var request = Request("12.0.2", ["12.0.1", "12.0.2", "12.0.3"], Advisory("(, 12.0.2]")) with { CentralPin = NuGetVersion.Parse("12.0.1"), }; @@ -132,8 +130,7 @@ public async Task Select_WhenNoAdvisoryCoversTheResolvedVersion_HasNoFix() } private static OverrideRequest Request(string resolved, string[] candidates, params PackageAdvisory[] advisories) - => new() - { + => new() { ResolvedVersion = NuGetVersion.Parse(resolved), Candidates = [.. candidates.Select(NuGetVersion.Parse)], Advisories = advisories, diff --git a/tests/Buildvana.Tool.Tests/PackagePinReaderTests.cs b/tests/Buildvana.Tool.Tests/PackagePinReaderTests.cs index 462595e0..f302fff0 100644 --- a/tests/Buildvana.Tool.Tests/PackagePinReaderTests.cs +++ b/tests/Buildvana.Tool.Tests/PackagePinReaderTests.cs @@ -240,8 +240,7 @@ public async Task Read_LeavesOutAnItemDeclaredOutsideTheRepository() // Derived from the home directory, never written out: a literal Windows path is a relative path on // Linux, and would resolve to a file inside the repository. var outside = Path.GetFullPath(Path.Combine(home.RootPath, "..", "elsewhere", "Directory.Packages.props")); - var dump = new PackagePinDump - { + var dump = new PackagePinDump { ProjectFullPath = home.GetFullPath(ProjectFileName), Items = [Item("PackageVersion", "Serilog", "4.0.0") with { DefiningProjectFullPath = outside }], }; @@ -253,8 +252,7 @@ private static IReadOnlyList Read(TempHome home, params PackagePi => new PackagePinReader(home.Provider, NullReporter.Instance).Read(dumps); private static PackagePinDump Dump(TempHome home, params PackagePinDumpItem[] items) - => new() - { + => new() { ProjectFullPath = home.GetFullPath(ProjectFileName), Items = [.. items.Select(item => item with { DefiningProjectFullPath = home.GetFullPath(ProjectFileName) })], }; @@ -266,8 +264,7 @@ private static PackagePinDumpItem Item( string? versionOverride = null, string? updatePolicy = null, bool isImplicitlyDefined = false) - => new() - { + => new() { ItemType = itemType, Id = id, Version = version, diff --git a/tests/Buildvana.Tool.Tests/PackagePinWriterTests.cs b/tests/Buildvana.Tool.Tests/PackagePinWriterTests.cs index 8f0945fe..10e907ee 100644 --- a/tests/Buildvana.Tool.Tests/PackagePinWriterTests.cs +++ b/tests/Buildvana.Tool.Tests/PackagePinWriterTests.cs @@ -189,8 +189,7 @@ private static PackageUpdatePolicy Policy() } private static PinResolution Moving(string id, string from, string to, string file, string? itemType = "PackageVersion") - => new() - { + => new() { Pin = DependencyPin.Create(DependencyScope.Packages, id, from, file) with { ItemType = itemType }, Policy = Policy(), State = PinResolutionState.Updated, diff --git a/tests/Buildvana.Tool.Tests/PackageVersionCatalogTests.cs b/tests/Buildvana.Tool.Tests/PackageVersionCatalogTests.cs index adf5be8b..50f627b5 100644 --- a/tests/Buildvana.Tool.Tests/PackageVersionCatalogTests.cs +++ b/tests/Buildvana.Tool.Tests/PackageVersionCatalogTests.cs @@ -37,8 +37,7 @@ public async Task AVersionNoSourceHas_IsNeitherKnownNorListed() } private static PackageVersionCatalog NewCatalog(string[] listed, string[] unlisted) - => new() - { + => new() { Listed = [.. listed.Select(NuGetVersion.Parse)], Unlisted = [.. unlisted.Select(NuGetVersion.Parse)], }; diff --git a/tests/Buildvana.Tool.Tests/PostUpdateHookArgsFactoryTests.cs b/tests/Buildvana.Tool.Tests/PostUpdateHookArgsFactoryTests.cs index baaf422b..3b3180db 100644 --- a/tests/Buildvana.Tool.Tests/PostUpdateHookArgsFactoryTests.cs +++ b/tests/Buildvana.Tool.Tests/PostUpdateHookArgsFactoryTests.cs @@ -15,10 +15,8 @@ internal sealed class PostUpdateHookArgsFactoryTests public async Task Create_StatesWhatTheRunMadeOfEveryScope() { using var home = new TempHome(); - var resolution = new DependencyResolution - { - NetSdk = new NetSdkResolution - { + var resolution = new DependencyResolution { + NetSdk = new NetSdkResolution { Pin = NetSdkPin.Create("10.0.100", allowPrerelease: false), Policy = NetSdkPolicy(), State = PinResolutionState.Updated, @@ -49,10 +47,8 @@ public async Task Create_StatesAGroupsPinsUnderItsCaption() { using var home = new TempHome(); var grouped = Moving("StyleCop.Analyzers", "1.2.0", "1.3.0", DependencyScope.Packages); - var resolution = new DependencyResolution - { - Packages = - [ + var resolution = new DependencyResolution { + Packages = [ Moving("Serilog", "3.0.0", "3.1.0", DependencyScope.Packages), grouped with { Pin = grouped.Pin with { GroupCaption = "SDK package injections" } }, ], @@ -120,8 +116,7 @@ private static NetSdkUpdatePolicy NetSdkPolicy() } private static PinResolution Moving(string id, string from, string to, DependencyScope scope) - => new() - { + => new() { Pin = DependencyPin.Create(scope, id, from, "Directory.Packages.props"), Policy = Policy(), State = PinResolutionState.Updated, diff --git a/tests/Buildvana.Tool.Tests/ReleaseCommandChangelogTests.cs b/tests/Buildvana.Tool.Tests/ReleaseCommandChangelogTests.cs index e455a28c..6e452913 100644 --- a/tests/Buildvana.Tool.Tests/ReleaseCommandChangelogTests.cs +++ b/tests/Buildvana.Tool.Tests/ReleaseCommandChangelogTests.cs @@ -75,8 +75,7 @@ internal sealed class ReleaseCommandChangelogTests [Arguments("stable", "2.3")] public async Task Release_WhenPolicyApplies_MovesUnreleasedChangesToNewSection(string policy, string versionSpec) { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = versionSpec, ChangelogUpdates = policy, Changelog = ChangelogWithChanges, @@ -107,8 +106,7 @@ public async Task Release_OnPrereleaseWithStablePolicy_LeavesChangelogAlone() [Test] public async Task Release_WithNonePolicy_LeavesChangelogAlone_EvenOnStableRelease() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", ChangelogUpdates = "none", Changelog = ChangelogWithChanges, @@ -151,8 +149,7 @@ public async Task Release_WithEmptySectionAndNoSubstitute_Fails() [Test] public async Task Release_WithEmptySectionAndSubstitute_UsesTheSubstitute() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { ChangelogUpdates = "all", Changelog = EmptyChangelog, EmptyChangelog = "This release contains no user-visible changes.", @@ -199,8 +196,7 @@ public async Task Release_PinsFileLinksOfNewSection_ToTheTagActuallyReleased() [Test] public async Task Release_WithLinkOutsideRepository_FailsNamingTheTarget() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { ChangelogUpdates = "all", Changelog = ChangelogWithOutsideLink, Dogfood = false, diff --git a/tests/Buildvana.Tool.Tests/ReleaseCommandFailureTests.cs b/tests/Buildvana.Tool.Tests/ReleaseCommandFailureTests.cs index c3bf9be2..43d969f5 100644 --- a/tests/Buildvana.Tool.Tests/ReleaseCommandFailureTests.cs +++ b/tests/Buildvana.Tool.Tests/ReleaseCommandFailureTests.cs @@ -49,8 +49,7 @@ public async Task Release_OnExistingTag_UndoesTheReleaseCommit() [Test] public async Task Release_WhenPublicationFails_ResetsAndForcePushesTheBranch() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { OnPublishing = () => throw new BuildFailedException("The server said no."), }); var initialSha = harness.Repo.HeadSha; diff --git a/tests/Buildvana.Tool.Tests/ReleaseCommandReportingTests.cs b/tests/Buildvana.Tool.Tests/ReleaseCommandReportingTests.cs index 198f47a3..20e38f93 100644 --- a/tests/Buildvana.Tool.Tests/ReleaseCommandReportingTests.cs +++ b/tests/Buildvana.Tool.Tests/ReleaseCommandReportingTests.cs @@ -48,8 +48,7 @@ public async Task Release_WithBumpToUnstable_OnAPrereleaseLine_RecordsTheSpecUnc [Test] public async Task Release_ShippingPublicApis_CountsBothFilesOfThePair() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, CheckPublicApi = false, @@ -65,8 +64,7 @@ public async Task Release_ShippingPublicApis_CountsBothFilesOfThePair() [Test] public async Task Release_ShippingInternalApis_CountsBothFilesOfThePair() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, UnshippedInternalApi = "#nullable enable\nTest.Helper\n", diff --git a/tests/Buildvana.Tool.Tests/ReleaseCommandTests.cs b/tests/Buildvana.Tool.Tests/ReleaseCommandTests.cs index 4e220f57..bd0c4c5e 100644 --- a/tests/Buildvana.Tool.Tests/ReleaseCommandTests.cs +++ b/tests/Buildvana.Tool.Tests/ReleaseCommandTests.cs @@ -239,8 +239,7 @@ public async Task Release_UsesCIBotIdentity_EvenWhenTheRepositoryHasOne() [Test] public async Task Release_UsesConfiguredIdentity_OverBotAndRepositoryIdentities() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { ConfiguredIdentity = new("Configured Bot", "configured@example.invalid"), }); harness.Repo.SetCommitterIdentity("Local Committer", "local@example.invalid"); @@ -363,8 +362,7 @@ public async Task Release_WithoutBump_LeavesVersionFileAlone() [Test] public async Task Release_OnStableRelease_ShipsPublicApis() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, CheckPublicApi = false, @@ -385,8 +383,7 @@ await Assert.That(commit.ChangedFiles).IsEquivalentTo([ [Test] public async Task Release_OnStableRelease_ShipsInternalApis() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, UnshippedInternalApi = "#nullable enable\nTest.Helper\n", @@ -408,8 +405,7 @@ await Assert.That(commit.ChangedFiles).IsEquivalentTo([ [Test] public async Task Release_WithRemovedInternalApi_LeavesVersionSpecUnchanged() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, UnshippedInternalApi = "#nullable enable\n*REMOVED*Test.Helper\n", @@ -424,8 +420,7 @@ public async Task Release_WithRemovedInternalApi_LeavesVersionSpecUnchanged() [Test] public async Task Release_OnPrerelease_LeavesDeclaredApisUnshipped() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { Dogfood = false, CheckPublicApi = false, UnshippedPublicApi = "#nullable enable\nTest.Thing\n", @@ -445,8 +440,7 @@ public async Task Release_OnPrerelease_LeavesDeclaredApisUnshipped() [Test] public async Task Release_WithAdditivePublicApi_BumpsMinor_AndLeavesApisUnshipped() { - using var harness = new ReleaseHarness(new() - { + using var harness = new ReleaseHarness(new() { VersionSpec = "2.3", Dogfood = false, UnshippedPublicApi = "#nullable enable\nTest.Thing\n", diff --git a/tests/Buildvana.Tool.Tests/ReleaseHarness.cs b/tests/Buildvana.Tool.Tests/ReleaseHarness.cs index 422baa5d..033d2a71 100644 --- a/tests/Buildvana.Tool.Tests/ReleaseHarness.cs +++ b/tests/Buildvana.Tool.Tests/ReleaseHarness.cs @@ -70,8 +70,7 @@ public ReleaseHarness(ReleaseHarnessOptions? options = null) { _options = options ?? new ReleaseHarnessOptions(); ProcessRunner = new FakeProcessRunner { OnRun = RunDotNet }; - AppRunner.OnRun = (_, _, _) => - { + AppRunner.OnRun = (_, _, _) => { Record("hook"); HookBehavior?.Invoke(); }; @@ -230,14 +229,12 @@ private ServiceProvider BuildServiceProvider() // The boundaries, faked. Registered last, so that they win over what AddBvServices registers. .AddSingleton(ProcessRunner) .AddSingleton(AppRunner) - .AddSingleton(sp => new RecordingServerAdapter(sp) - { + .AddSingleton(sp => new RecordingServerAdapter(sp) { CloudBuild = _options.CloudBuild, BotIdentity = _options.WithBotIdentity ? new("Buildvana Test Bot", "bot@buildvana.invalid") : null, PushUser = _options.PushUser, PushSecret = _options.PushSecret, - OnPublishing = () => - { + OnPublishing = () => { Record("publish"); _options.OnPublishing?.Invoke(); }, @@ -350,8 +347,7 @@ private void WriteSelfReferenceTargets() return; } - var globalJson = new JsonObject - { + var globalJson = new JsonObject { ["msbuild-sdks"] = new JsonObject { [ProducedPackageIds[0]] = PreviousVersion }, }; WriteFile("global.json", globalJson.ToJsonString(IndentedJson)); @@ -360,14 +356,11 @@ private void WriteSelfReferenceTargets() return; } - var toolManifest = new JsonObject - { + var toolManifest = new JsonObject { ["version"] = 1, ["isRoot"] = true, - ["tools"] = new JsonObject - { - [ProducedPackageIds[1]] = new JsonObject - { + ["tools"] = new JsonObject { + [ProducedPackageIds[1]] = new JsonObject { ["version"] = PreviousVersion, ["commands"] = new JsonArray("test-tool"), }, @@ -392,8 +385,7 @@ private void WriteSelfReferenceTargets() private string BuildConfiguration() { - var release = new JsonObject - { + var release = new JsonObject { ["branches"] = new JsonArray($"^{BranchName}$"), ["checkPublicApi"] = _options.CheckPublicApi, ["changelogUpdates"] = _options.ChangelogUpdates, @@ -404,13 +396,11 @@ private string BuildConfiguration() release["emptyChangelog"] = emptyChangelog; } - var feed = new JsonObject - { + var feed = new JsonObject { ["source"] = "https://nuget.example.invalid/v3/index.json", ["apiKeyEnv"] = ApiKeyEnvVar, }; - var root = new JsonObject - { + var root = new JsonObject { ["release"] = release, ["versioning"] = new JsonObject { ["prereleaseTag"] = "preview" }, ["dotnet"] = new JsonObject { ["configuration"] = Configuration }, @@ -418,8 +408,7 @@ private string BuildConfiguration() }; if (_options.ConfiguredIdentity is { } identity) { - root["git"] = new JsonObject - { + root["git"] = new JsonObject { ["identity"] = new JsonObject { ["name"] = identity.Name, ["email"] = identity.Email }, }; } diff --git a/tests/Buildvana.Tool.Tests/SdkPinWriterTests.cs b/tests/Buildvana.Tool.Tests/SdkPinWriterTests.cs index 0b95c8db..5f92dccb 100644 --- a/tests/Buildvana.Tool.Tests/SdkPinWriterTests.cs +++ b/tests/Buildvana.Tool.Tests/SdkPinWriterTests.cs @@ -83,8 +83,7 @@ private static PackageUpdatePolicy Policy() } private static PinResolution Moving(string id, string from, string to, string file) - => new() - { + => new() { Pin = DependencyPin.Create(DependencyScope.Sdks, id, from, file), Policy = Policy(), State = PinResolutionState.Updated, diff --git a/tests/Buildvana.Tool.Tests/SelfVersionServiceTests.cs b/tests/Buildvana.Tool.Tests/SelfVersionServiceTests.cs index bb8eace0..78aaa8be 100644 --- a/tests/Buildvana.Tool.Tests/SelfVersionServiceTests.cs +++ b/tests/Buildvana.Tool.Tests/SelfVersionServiceTests.cs @@ -169,10 +169,8 @@ public async Task UpdateRepository_WithoutManifest_CreatesItThenRunsDotnetToolIn using var home = new TempHome(); WriteGlobalJson(home, "2.1.41-preview"); var manifestPath = Path.Combine(home.RootPath, "dotnet-tools.json"); - var runner = new FakeProcessRunner - { - OnRun = (executable, args) => - { + var runner = new FakeProcessRunner { + OnRun = (executable, args) => { if (args is ["new", "tool-manifest"]) { File.WriteAllText(manifestPath, """{ "version": 1, "isRoot": true, "tools": { } }"""); @@ -737,8 +735,7 @@ public async Task UpdateRepository_StampsFamilyPins() await Assert.That(home.ReadFile("App.csproj")).IsEqualTo(project.Replace("2.1.40-preview", "2.1.41-preview", StringComparison.Ordinal)); await Assert.That(home.ReadFile(hookPath)).IsEqualTo(hook.Replace("2.1.40-preview", "2.1.41-preview", StringComparison.Ordinal)); - await Assert.That(summary.FamilyPinLines).IsEquivalentTo( - [ + await Assert.That(summary.FamilyPinLines).IsEquivalentTo([ "Buildvana.Runtime: 2.1.40-preview -> 2.1.41-preview (.buildvana/hooks/hook.cs)", "Buildvana.Runtime: 2.1.40-preview -> 2.1.41-preview (App.csproj)", "Buildvana.Sdk: $(BuildvanaVersion) (App.csproj, left alone)", @@ -823,8 +820,7 @@ public async Task UpdateRepository_WhenToolUpdateFails_Propagates() using var home = new TempHome(); WriteGlobalJson(home, "2.1.41-preview"); WriteToolManifest(home, "2.1.40-preview"); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (executable, args) => new ProcessResult($"{executable} {string.Join(' ', args)}", 1, string.Empty, "simulated failure", TimeSpan.Zero), }; var service = CreateService(home, "2.1.41-preview", runner); diff --git a/tests/Buildvana.Tool.Tests/SolutionPinReaderTests.cs b/tests/Buildvana.Tool.Tests/SolutionPinReaderTests.cs index 3de39471..5ffdc0b0 100644 --- a/tests/Buildvana.Tool.Tests/SolutionPinReaderTests.cs +++ b/tests/Buildvana.Tool.Tests/SolutionPinReaderTests.cs @@ -79,8 +79,7 @@ public async Task ReadAsync_WithNoProject_RunsNothing() public async Task ReadAsync_WhenEvaluationFails_ReportsAFailedStep() { using var home = new TempHome(); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (executable, _) => new ProcessResult(executable, 1, "A.csproj(1,2): error MSB4025: no.", string.Empty, TimeSpan.Zero), }; @@ -106,13 +105,11 @@ private static SolutionPinReader CreateReader(TempHome home, IProcessRunner runn => new(home.Provider, runner, NullReporter.Instance); private static Func, ProcessResult> WriteDumps(string projectName, params string[] targetFrameworks) - => (executable, args) => - { + => (executable, args) => { var directory = DumpDirectoryOf(args); foreach (var targetFramework in targetFrameworks) { - var dump = new PackagePinDump - { + var dump = new PackagePinDump { ProjectFullPath = $@"C:\repo\src\{projectName}\{projectName}.csproj", TargetFramework = targetFramework, }; @@ -124,8 +121,7 @@ private static Func, ProcessResult> WriteDumps(str }; private static Func, ProcessResult> WriteText(string fileName, string content) - => (executable, args) => - { + => (executable, args) => { Write(DumpDirectoryOf(args), fileName, content); return new ProcessResult(executable, 0, string.Empty, string.Empty, TimeSpan.Zero); }; diff --git a/tests/Buildvana.Tool.Tests/ToolPinUpdaterTests.cs b/tests/Buildvana.Tool.Tests/ToolPinUpdaterTests.cs index d168924b..4662eacb 100644 --- a/tests/Buildvana.Tool.Tests/ToolPinUpdaterTests.cs +++ b/tests/Buildvana.Tool.Tests/ToolPinUpdaterTests.cs @@ -55,8 +55,7 @@ public async Task UpdateAsync_LeavesAToolThatDoesNotMoveAlone() public async Task UpdateAsync_WhenAnUpdateFails_StopsThere() { using var home = new TempHome(); - var runner = new FakeProcessRunner - { + var runner = new FakeProcessRunner { OnRun = static (_, args) => new ProcessResult(string.Join(' ', args), 1, string.Empty, "boom", TimeSpan.Zero), }; @@ -76,8 +75,7 @@ private static PackageUpdatePolicy Policy() } private static PinResolution Moving(string id, string from, string to, string declaringFile = "dotnet-tools.json") - => new() - { + => new() { Pin = DependencyPin.Create(DependencyScope.Tools, id, from, declaringFile), Policy = Policy(), State = PinResolutionState.Updated, From be1b59a913fa9d4c7095ecd9b422101bcf69ee0e Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Fri, 16 Oct 2026 02:27:42 +0200 Subject: [PATCH 06/15] Add trailing commas to multi-line collection expressions StyleCop.Analyzers 1.3.79-beta reports SA1413 on a multi-line collection expression whose last element has no trailing comma. A spread over a LINQ chain gets a line of its own, so that the comma can end the chain. The closing bracket then stands alone, as in an element list. Co-Authored-By: Claude Opus 5.5 --- .../Execution/CommandArgumentValidator.cs | 10 ++++++---- .../Services/Dependencies/DependencyResolution.cs | 14 +++++++++----- .../Services/Dependencies/OrphanDetector.cs | 12 ++++++++---- .../Dependencies/OverrideLifecycle.RunState.cs | 10 ++++++---- .../Services/Dependencies/OverrideSelector.cs | 10 ++++++---- .../Services/Dependencies/PackagePinReader.cs | 6 ++++-- src/Buildvana.Tool/Services/Git/GitService.cs | 8 +++++--- .../Services/Hooks/PostUpdateHookArgsFactory.cs | 14 +++++++++----- .../JsonKeyedObjectConverterTests.cs | 6 ++++-- tests/Buildvana.Sdk.Tests/PinDumpFixture.cs | 10 +++++++--- .../AppDirectiveEditorTests.cs | 6 ++++-- .../Buildvana.Tool.Tests/MsBuildPinEditorTests.cs | 6 ++++-- 12 files changed, 72 insertions(+), 40 deletions(-) diff --git a/src/Buildvana.Tool/Infrastructure/Execution/CommandArgumentValidator.cs b/src/Buildvana.Tool/Infrastructure/Execution/CommandArgumentValidator.cs index 5db3b9c0..d4a67686 100644 --- a/src/Buildvana.Tool/Infrastructure/Execution/CommandArgumentValidator.cs +++ b/src/Buildvana.Tool/Infrastructure/Execution/CommandArgumentValidator.cs @@ -91,10 +91,12 @@ private static IReadOnlyList DeclaredArguments(CommandRegis return []; } - return [..command.SettingsType - .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) - .Select(static p => p.GetCustomAttribute()) - .OfType()]; + return [ + .. command.SettingsType + .GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Select(static p => p.GetCustomAttribute()) + .OfType(), + ]; } private static void ConsumeDeclaredOptions(CliOptionReader reader, CommandRegistration command) diff --git a/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs b/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs index c9dd7893..3707d4c4 100644 --- a/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs +++ b/src/Buildvana.Tool/Services/Dependencies/DependencyResolution.cs @@ -81,9 +81,13 @@ private static NetSdkResolution Skipping(NetSdkPin pin, EffectivePolicyResolver private static IReadOnlyList Skipping( IEnumerable pins, EffectivePolicyResolver policies) - => [.. pins.Select(pin => new PinResolution { - Pin = pin, - Policy = policies.Resolve(pin), - State = PinResolutionState.Skipped, - })]; + { + return [ + .. pins.Select(pin => new PinResolution { + Pin = pin, + Policy = policies.Resolve(pin), + State = PinResolutionState.Skipped, + }), + ]; + } } diff --git a/src/Buildvana.Tool/Services/Dependencies/OrphanDetector.cs b/src/Buildvana.Tool/Services/Dependencies/OrphanDetector.cs index fa0bf0dd..698150c8 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OrphanDetector.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OrphanDetector.cs @@ -121,10 +121,14 @@ private static bool IsCentralPin(DependencyPin pin) // A project is evaluated once per target framework, and one assets file answers for all of them. private static IReadOnlyList<(string ProjectFullPath, string AssetsFilePath)> ProjectsOf( IReadOnlyList evaluations) - => [.. evaluations - .Where(static dump => !string.IsNullOrEmpty(dump.ProjectAssetsFile)) - .GroupBy(static dump => dump.ProjectFullPath, StringComparer.OrdinalIgnoreCase) - .Select(static grouped => (grouped.Key, grouped.First().ProjectAssetsFile!))]; + { + return [ + .. evaluations + .Where(static dump => !string.IsNullOrEmpty(dump.ProjectAssetsFile)) + .GroupBy(static dump => dump.ProjectFullPath, StringComparer.OrdinalIgnoreCase) + .Select(static grouped => (grouped.Key, grouped.First().ProjectAssetsFile!)), + ]; + } // Vulnerability data is no concern of orphan detection: what a project references does not depend on it. // NU1900, which stops the override lifecycle, therefore does not stop a prune. diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs index 96f611fc..348c7c0b 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideLifecycle.RunState.cs @@ -59,10 +59,12 @@ public void AddPromotion(string projectFullPath, string packageId, NuGetVersion? public TransitiveOverridePlan ToPlan(IReadOnlyList projects) => new() { Central = [.. _central.Select(static entry => new PackageOverride(entry.Key, entry.Value))], - Projects = [.. projects.Select(project => new ProjectOverrides { - ProjectFullPath = project.ProjectFullPath, - Promotions = PromotionsOf(project.ProjectFullPath), - })], + Projects = [ + .. projects.Select(project => new ProjectOverrides { + ProjectFullPath = project.ProjectFullPath, + Promotions = PromotionsOf(project.ProjectFullPath), + }), + ], }; private IReadOnlyList PromotionsOf(string projectFullPath) diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs index c6a82b50..0c023b78 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs @@ -76,10 +76,12 @@ private static OverrideDecision SelectForCentralPin(OverrideRequest request, Lis private static OverrideDecision SelectVersion(OverrideRequest request, List advisories) { - List safe = [.. request.Candidates - .Where(candidate => VersionComparer.VersionRelease.Compare(candidate, request.ResolvedVersion) >= 0) - .Where(candidate => !IsCovered(advisories, candidate)) - .OrderBy(static candidate => candidate, VersionComparer.VersionRelease)]; + List safe = [ + .. request.Candidates + .Where(candidate => VersionComparer.VersionRelease.Compare(candidate, request.ResolvedVersion) >= 0) + .Where(candidate => !IsCovered(advisories, candidate)) + .OrderBy(static candidate => candidate, VersionComparer.VersionRelease), + ]; if (safe.Count == 0) { diff --git a/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs b/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs index 0ba52951..574300d5 100644 --- a/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs +++ b/src/Buildvana.Tool/Services/Dependencies/PackagePinReader.cs @@ -52,8 +52,10 @@ public IReadOnlyList Read(IReadOnlyList dumps) } ReportItemsOutsideHome(outsideHome); - return [.. pins.Values.OrderBy(static pin => pin.DeclaringFile, StringComparer.Ordinal) - .ThenBy(static pin => pin.Id, StringComparer.OrdinalIgnoreCase)]; + return [ + .. pins.Values.OrderBy(static pin => pin.DeclaringFile, StringComparer.Ordinal) + .ThenBy(static pin => pin.Id, StringComparer.OrdinalIgnoreCase), + ]; } // A pin lives where it is declared, so an item declared outside the repository is nobody's to edit: a diff --git a/src/Buildvana.Tool/Services/Git/GitService.cs b/src/Buildvana.Tool/Services/Git/GitService.cs index e20a6621..6307a8e3 100644 --- a/src/Buildvana.Tool/Services/Git/GitService.cs +++ b/src/Buildvana.Tool/Services/Git/GitService.cs @@ -187,9 +187,11 @@ public IReadOnlyList GetDirtyFiles() IncludeUntracked = true, RecurseUntrackedDirs = true, }; - return [.. _repository.RetrieveStatus(options) - .Select(x => Path.GetFullPath(x.FilePath, homeDirectory)) - .Where(x => !x.StartsWith(scratchPrefix, StringComparison.Ordinal))]; + return [ + .. _repository.RetrieveStatus(options) + .Select(x => Path.GetFullPath(x.FilePath, homeDirectory)) + .Where(x => !x.StartsWith(scratchPrefix, StringComparison.Ordinal)), + ]; } /// diff --git a/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs b/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs index 6556c6d8..98485bc0 100644 --- a/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs +++ b/src/Buildvana.Tool/Services/Hooks/PostUpdateHookArgsFactory.cs @@ -60,11 +60,15 @@ .. resolution.Packages } private static IReadOnlyList OverridesOf(IReadOnlyList entries) - => [.. entries.Select(static entry => new TransitiveOverride { - PackageId = entry.PackageId, - Version = entry.Version, - DeclaringFile = entry.DeclaringFile, - })]; + { + return [ + .. entries.Select(static entry => new TransitiveOverride { + PackageId = entry.PackageId, + Version = entry.Version, + DeclaringFile = entry.DeclaringFile, + }), + ]; + } private static IReadOnlyList ResultsOf(IEnumerable pins) => [.. pins.Select(ResultOf)]; diff --git a/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs b/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs index 3def2ed3..a45434c3 100644 --- a/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs +++ b/tests/Buildvana.Core.Json.Tests/JsonKeyedObjectConverterTests.cs @@ -31,7 +31,8 @@ public async Task Write_ValueShape_WritesOneMemberPerElement() { var json = Serialize([ new() { Pattern = "Louis*", Policy = "minor" }, - new() { Pattern = "*", Policy = "latest" }]); + new() { Pattern = "*", Policy = "latest" }, + ]); await Assert.That(json).IsEqualTo("""{"Louis*":"minor","*":"latest"}"""); } @@ -142,7 +143,8 @@ public async Task Write_DuplicateKey_Throws() { static string Act() => Serialize([ new() { Pattern = "a", Policy = "one" }, - new() { Pattern = "a", Policy = "two" }]); + new() { Pattern = "a", Policy = "two" }, + ]); var exception = await Assert.That(Act).Throws(); await Assert.That(exception!.Message).Contains("Duplicate key 'a'"); diff --git a/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs b/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs index 3ca0d11e..32f20c09 100644 --- a/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs +++ b/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs @@ -50,9 +50,13 @@ public IReadOnlyList DumpPins(string projectBody) """; Run(WriteFile("Test.proj", content)); - return [.. Directory.EnumerateFiles(DumpDirectory) - .Select(static path => JsonSerializer.Deserialize(File.ReadAllText(path), PackagePinDumpJsonContext.Default.PackagePinDump)!) - .OrderBy(static dump => dump.TargetFramework, StringComparer.Ordinal)]; + return [ + .. Directory.EnumerateFiles(DumpDirectory) + .Select(static path => JsonSerializer.Deserialize( + File.ReadAllText(path), + PackagePinDumpJsonContext.Default.PackagePinDump)!) + .OrderBy(static dump => dump.TargetFramework, StringComparer.Ordinal), + ]; } public void Dispose() => Directory.Delete(_root, recursive: true); diff --git a/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs b/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs index 5ea85cb8..75060a06 100644 --- a/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs +++ b/tests/Buildvana.Tool.Tests/AppDirectiveEditorTests.cs @@ -29,7 +29,8 @@ public async Task ReadDirectives_FindsManagedDirectives_InDocumentOrder() await Assert.That(directives).IsEquivalentTo([ new AppDirective(AppDirectiveKind.Sdk, "Buildvana.Sdk", "1.0.0"), new AppDirective(AppDirectiveKind.Package, "Buildvana.Runtime", "1.0.0-preview.2"), - new AppDirective(AppDirectiveKind.Package, "Newtonsoft.Json", null)]); + new AppDirective(AppDirectiveKind.Package, "Newtonsoft.Json", null), + ]); } [Test] @@ -115,7 +116,8 @@ public async Task ReadDirectives_AcceptsAllCSharpLineTerminators() await Assert.That(directives).IsEquivalentTo([ new AppDirective(AppDirectiveKind.Package, "Alpha", "1.0.0"), - new AppDirective(AppDirectiveKind.Package, "Beta", "2.0.0")]); + new AppDirective(AppDirectiveKind.Package, "Beta", "2.0.0"), + ]); } // The SDK's own parser matches directive kinds case-sensitively; so does the editor. The line is still diff --git a/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs b/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs index ee8b1fb8..eca17eaa 100644 --- a/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs +++ b/tests/Buildvana.Tool.Tests/MsBuildPinEditorTests.cs @@ -27,7 +27,8 @@ public async Task ReadPins_FindsAttributeFormPins_InDocumentOrder() await Assert.That(pins).IsEquivalentTo([ new MsBuildPin("PackageVersion", "Alpha", "1.0.0"), - new MsBuildPin("PackageVersion", "Beta", "2.0.0-preview.3")]); + new MsBuildPin("PackageVersion", "Beta", "2.0.0-preview.3"), + ]); } // dotnet package preserves reversed attribute order, so files it wrote must stay readable. @@ -322,7 +323,8 @@ public async Task ReadPins_ReturnsEveryDeclarationOfAnId() await Assert.That(pins).IsEquivalentTo([ new MsBuildPin("PackageVersion", "Alpha", "2.0.0"), - new MsBuildPin("PackageVersion", "Alpha", "1.0.0")]); + new MsBuildPin("PackageVersion", "Alpha", "1.0.0"), + ]); } // Malformed content never throws: what cannot be parsed is skipped. The unclosed quote swallows the From 2cc319220692a4e3d53dc66505981fe385ef877e Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Fri, 16 Oct 2026 08:07:33 +0200 Subject: [PATCH 07/15] Stop reporting a null pin dump in tests as a NullReferenceException `PinDumpFixture.DumpPins` and `WritePackagePinDumpTests.ReadDumpAsync` suppressed a null result of `JsonSerializer.Deserialize` with `!`. When a pin dump file held `null`, a test failed later with a `NullReferenceException` that named no file. Both sites now throw an `InvalidOperationException` with the file path instead. Co-Authored-By: Claude Opus 5.5 --- .../Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs | 6 ++++-- tests/Buildvana.Sdk.Tests/PinDumpFixture.cs | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs b/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs index ec112def..08323ffe 100644 --- a/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs +++ b/tests/Buildvana.Sdk.Tasks.Tests/WritePackagePinDumpTests.cs @@ -159,8 +159,10 @@ private static TaskItem Item(string id, params (string Name, string Value)[] met private static async Task ReadDumpAsync(string directory) { - var content = await File.ReadAllTextAsync(Directory.GetFiles(directory).Single()).ConfigureAwait(false); - return JsonSerializer.Deserialize(content, PackagePinDumpJsonContext.Default.PackagePinDump)!; + var path = Directory.GetFiles(directory).Single(); + var content = await File.ReadAllTextAsync(path).ConfigureAwait(false); + return JsonSerializer.Deserialize(content, PackagePinDumpJsonContext.Default.PackagePinDump) + ?? throw new InvalidOperationException($"The pin dump '{path}' reads as null."); } private static async Task RunInTempDirectory(Func test) diff --git a/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs b/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs index 32f20c09..3e81af05 100644 --- a/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs +++ b/tests/Buildvana.Sdk.Tests/PinDumpFixture.cs @@ -52,9 +52,7 @@ public IReadOnlyList DumpPins(string projectBody) Run(WriteFile("Test.proj", content)); return [ .. Directory.EnumerateFiles(DumpDirectory) - .Select(static path => JsonSerializer.Deserialize( - File.ReadAllText(path), - PackagePinDumpJsonContext.Default.PackagePinDump)!) + .Select(ReadDump) .OrderBy(static dump => dump.TargetFramework, StringComparer.Ordinal), ]; } @@ -67,6 +65,10 @@ private static string GetMetadata(string key) .First(attribute => attribute.Key == key) .Value!; + private static PackagePinDump ReadDump(string path) + => JsonSerializer.Deserialize(File.ReadAllText(path), PackagePinDumpJsonContext.Default.PackagePinDump) + ?? throw new InvalidOperationException($"The pin dump '{path}' reads as null."); + private void Run(string projectPath) { var globalProperties = new Dictionary { ["BV_PinDumpDirectory"] = DumpDirectory + Path.DirectorySeparatorChar }; From 56f50c2a62ee09c0a6ce969717629c4e75cf4acd Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Fri, 16 Oct 2026 14:15:54 +0200 Subject: [PATCH 08/15] Stop SA1115 and SA1516 from failing the build of Buildvana.Tool StyleCop.Analyzers 1.3.79-beta reports SA1115 on the Forwarded parameter of CommandParameters, because a blank line separates it from the previous parameter. SA1515 accepts the comment above Forwarded without that blank line. SA1516 reports the set accessor of GitService.CommitterIdentity, because no blank line separates it from the get accessor. Co-Authored-By: Claude Opus 5.5 --- src/Buildvana.Tool/CommandLine/CommandParameters.cs | 1 - src/Buildvana.Tool/Services/Git/GitService.cs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Buildvana.Tool/CommandLine/CommandParameters.cs b/src/Buildvana.Tool/CommandLine/CommandParameters.cs index 32115aca..dd8c6f6d 100644 --- a/src/Buildvana.Tool/CommandLine/CommandParameters.cs +++ b/src/Buildvana.Tool/CommandLine/CommandParameters.cs @@ -19,6 +19,5 @@ namespace Buildvana.Tool.CommandLine; internal sealed record CommandParameters( IReadOnlyList Options, IReadOnlyList Positionals, - // ReSharper disable once NotAccessedPositionalProperty.Global -- false positive: Forwarded is read by CommandLineOverridesParser IReadOnlyList Forwarded); diff --git a/src/Buildvana.Tool/Services/Git/GitService.cs b/src/Buildvana.Tool/Services/Git/GitService.cs index 6307a8e3..76a9befd 100644 --- a/src/Buildvana.Tool/Services/Git/GitService.cs +++ b/src/Buildvana.Tool/Services/Git/GitService.cs @@ -74,6 +74,7 @@ public GitIdentity? CommitterIdentity var signature = _repository.Config.BuildSignature(DateTimeOffset.Now); return signature is null ? null : new(signature.Name, signature.Email); } + set { Guard.IsNotNull(value); From ec0ed2db1dee37758c23819489ea0af6dce95c89 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Mon, 19 Oct 2026 23:23:58 +0200 Subject: [PATCH 09/15] Wrap lines over the length limits in three files The ExcludeFromCodeCoverage justification of VirtualTerminal.TryEnableOnStandardError and the Options parameter comment of CommandParameters exceeded 140 characters. The declaration of OverrideSelector.SelectForCentralPin exceeded the 120-character limit for declarations. Co-Authored-By: Claude Opus 5.5 --- src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs | 4 +++- src/Buildvana.Tool/CommandLine/CommandParameters.cs | 3 ++- src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs | 5 ++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs b/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs index e344d2cc..4b24d779 100644 --- a/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs +++ b/src/Buildvana.Core.ConsoleOutput/VirtualTerminal.cs @@ -30,7 +30,9 @@ public static partial class VirtualTerminal /// /// if escape sequences written to standard error will be interpreted; /// otherwise (including when standard error is not attached to a console). - [ExcludeFromCodeCoverage(Justification = "Environment-owned plumbing: reads TERM off Windows, manipulates the attached console on Windows. The decision logic is tested via IsNonWindowsTerminalCapable.")] + [ExcludeFromCodeCoverage( + Justification = "Environment-owned plumbing: reads TERM off Windows, manipulates the attached console on Windows. " + + "The decision logic is tested via IsNonWindowsTerminalCapable.")] public static bool TryEnableOnStandardError() { if (!OperatingSystem.IsWindows()) diff --git a/src/Buildvana.Tool/CommandLine/CommandParameters.cs b/src/Buildvana.Tool/CommandLine/CommandParameters.cs index dd8c6f6d..aff3768f 100644 --- a/src/Buildvana.Tool/CommandLine/CommandParameters.cs +++ b/src/Buildvana.Tool/CommandLine/CommandParameters.cs @@ -11,7 +11,8 @@ namespace Buildvana.Tool.CommandLine; /// splits the command line, and /// tells the command's options from its positionals, which takes the command's own declarations. /// -/// The non-global, non-positional tokens before --, for the command to parse. Empty when none were given. +/// The non-global, non-positional tokens before --, for the command to parse. +/// Empty when none were given. /// The positional tokens for the command to bind: those left over after subcommand /// resolution, plus every operand written after an option. Empty when none were given. /// The tokens after the first --, as typed; the overrides parser consumes the diff --git a/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs b/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs index 0c023b78..5d46527c 100644 --- a/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs +++ b/src/Buildvana.Tool/Services/Dependencies/OverrideSelector.cs @@ -60,7 +60,10 @@ private static List Applicable(OverrideRequest request) private static bool IsCovered(List advisories, NuGetVersion version) => advisories.Exists(advisory => advisory.AffectedVersions.Satisfies(version)); - private static OverrideDecision SelectForCentralPin(OverrideRequest request, List advisories, NuGetVersion pin) + private static OverrideDecision SelectForCentralPin( + OverrideRequest request, + List advisories, + NuGetVersion pin) { if (VersionComparer.VersionRelease.Compare(pin, request.ResolvedVersion) < 0) { From 85a4245b7e8ce3ac290ca89bdd7d40d86141b692 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 02:04:28 +0200 Subject: [PATCH 10/15] Hold the Microsoft.Build* pins at 18.9.x, and move six other pins Under the default `minor` policy, `bv deps update` moved the `Microsoft.Build*` pins to 18.11.0. `Microsoft.Build` 18.10.1 and later target `net11.0` instead of `net10.0`, so the restore of `Buildvana.Sdk.Tests` failed with NU1701. A newer pin would also compile `Buildvana.Sdk.Tasks` against APIs missing from MSBuild 18.9, the `BV_MinMSBuildVersion` floor. A `patch` policy keeps the `Microsoft.Build*` pins at that floor. `Microsoft.Build.Locator` keeps `minor`, because it has versions of its own. Co-Authored-By: Claude Opus 5.5 --- Directory.Packages.props | 10 +++++----- buildvana.jsonc | 6 ++++++ buildvana.next.jsonc | 6 ++++++ global.json | 2 +- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index b2a35c1d..f62fba55 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -39,10 +39,10 @@ - - - - + + + + @@ -64,7 +64,7 @@ - + diff --git a/buildvana.jsonc b/buildvana.jsonc index 1bf93ca4..3269a021 100644 --- a/buildvana.jsonc +++ b/buildvana.jsonc @@ -90,6 +90,12 @@ "Louis.*": "minor-", "StyleCop.Analyzers": "minor-", "Microsoft.CodeAnalysis.*": "patch", + // Microsoft.Build.Locator has versions of its own. This entry keeps it + // out of the pattern below. + "Microsoft.Build.Locator": "minor", + // The MSBuild packages stay at BV_MinMSBuildVersion, the MSBuild floor. + // Move them with --to when the floor moves. + "Microsoft.Build*": "patch", }, "additionalPackages": { "SDK package injections": { diff --git a/buildvana.next.jsonc b/buildvana.next.jsonc index d62426d8..44ff728b 100644 --- a/buildvana.next.jsonc +++ b/buildvana.next.jsonc @@ -90,6 +90,12 @@ "Louis.*": "minor-", "StyleCop.Analyzers": "minor-", "Microsoft.CodeAnalysis.*": "patch", + // Microsoft.Build.Locator has versions of its own. This entry keeps it + // out of the pattern below. + "Microsoft.Build.Locator": "minor", + // The MSBuild packages stay at BV_MinMSBuildVersion, the MSBuild floor. + // Move them with --to when the floor moves. + "Microsoft.Build*": "patch", }, "additionalPackages": { "SDK package injections": { diff --git a/global.json b/global.json index a19d1040..a2eb1fca 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "10.0.400", + "version": "10.0.402", "rollForward": "latestMinor", "allowPrerelease": false }, From ab893980bf920cbb50bdb6b29609b0c5d4e72424 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 02:24:59 +0200 Subject: [PATCH 11/15] Inject StyleCop.Analyzers 1.3.133-beta and enable SA1315, SA1654, SX1412 Buildvana SDK injected `StyleCop.Analyzers` 1.3.79-beta, which has no SA1315, SA1654, or SX1412. An override that renamed a parameter, a `cref` with escaped angle brackets, and a C# file with a BOM all passed the build. `.globalconfig` sets the three rules to `warning`, and SX1412 takes the place of SA1412. 1.3.133-beta also adds SA1143, whose chain layout ends each line with `?` or `:`. The "Concatenated ternaries" template of `csharp-style-guide.md` starts each line with `:` instead, so SA1143 is `none`. Co-Authored-By: Claude Opus 5.5 --- .globalconfig | 9 ++++++--- CHANGELOG.md | 2 +- src/Buildvana.Sdk/Sdk/PackageVersions.props | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.globalconfig b/.globalconfig index e232233c..79a3ee28 100644 --- a/.globalconfig +++ b/.globalconfig @@ -239,7 +239,7 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case # Ordering and grouping follows the categories listed in the official documentation. # See https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation # ---------------------------------------------------------------------------------------------- -# Last update: 2026-10-15 (StyleCop.Analyzers v1.3.79-beta) +# Last update: 2026-10-20 (StyleCop.Analyzers v1.3.133-beta) # ============================================================================================== # StyleCop Analyzers - Special rules @@ -320,6 +320,7 @@ dotnet_diagnostic.SA1137.severity = warning # Elements should have the same inde dotnet_diagnostic.SA1139.severity = warning # Use literal suffix notation instead of casting dotnet_diagnostic.SA1141.severity = warning # Use tuple syntax dotnet_diagnostic.SA1142.severity = warning # Refer to tuple elements by name +dotnet_diagnostic.SA1143.severity = none # Conditional expressions should be formatted consistently # Its chain layout puts operators at line ends, against our concatenated ternaries layout # StyleCop Analyzers - Ordering rules dotnet_diagnostic.SA1200.severity = warning # Using directives should be placed correctly @@ -359,7 +360,7 @@ dotnet_diagnostic.SA1311.severity = warning # Static readonly fields should begi dotnet_diagnostic.SA1312.severity = warning # Variable names should begin with lower-case letter dotnet_diagnostic.SA1313.severity = warning # Parameter names should begin with lower-case letter dotnet_diagnostic.SA1314.severity = warning # Type parameter names should begin with T -# Rule SA1315 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1949 +dotnet_diagnostic.SA1315.severity = warning # Parameter names should match inherited names dotnet_diagnostic.SA1316.severity = warning # Tuple element names should use correct casing dotnet_diagnostic.SA1317.severity = warning # Identifier should be named only with Latin letters @@ -377,7 +378,8 @@ dotnet_diagnostic.SA1408.severity = warning # Conditional expressions should dec # Rule SA1409 omitted in StyleCop Analyzers - https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1058 dotnet_diagnostic.SA1410.severity = warning # Remove delegate parenthesis when possible dotnet_diagnostic.SA1411.severity = warning # Attribute constructor should not use unnecessary parenthesis -dotnet_diagnostic.SA1412.severity = none # Store files as UTF-8 with byte order mark # Practically all IDEs and editors save source code as UTF-8 anyway; Claude Code's Write tool does not add a BOM +dotnet_diagnostic.SA1412.severity = none # Store files as UTF-8 with byte order mark # SX1412 is enabled instead +dotnet_diagnostic.SX1412.severity = warning # Store files as UTF-8 without byte order mark dotnet_diagnostic.SA1413.severity = warning # Use trailing comma in multi-line initializers dotnet_diagnostic.SA1414.severity = warning # Tuple types in signatures should have element names @@ -459,6 +461,7 @@ dotnet_diagnostic.SA1649.severity = warning # File name should match first type dotnet_diagnostic.SA1651.severity = warning # Do not use placeholder elements # Rule SA1652 superseded by SA0001 dotnet_diagnostic.SA1653.severity = warning # Only one partial declaration should contain summary documentation +dotnet_diagnostic.SA1654.severity = warning # Properly encode generic brackets # ============================================================================================== # PUBLIC API ANALYZERS diff --git a/CHANGELOG.md b/CHANGELOG.md index 74196d76..e0c742a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,7 +101,7 @@ The patch number restarted from 1, below the 2.0.x versions already published. - `bv release` rewrites each relative file link of the changelog section it releases into a permalink to the release tag. - `bv release` runs the [build pipeline](docs/tool-commands/release.md#the-steps) once, from `clean` through `pack`, after the release commit, and no longer runs `clean` through `test` before it. - [The pages under `docs/`](docs/README.md) moved to kebab-case names, `docs/modules/` to `docs/sdk-modules/`, and `docs/DependencyManagement.md` to `docs/tool-commands/dependencies.md`, so a link to an old name breaks. -- The `StandardAnalyzers` module adds [`StyleCop.Analyzers` 1.3.79-beta](docs/sdk-modules/standard-analyzers.md#package-references), which supports C# 8 to 15 and introduces SA1317 and SA1653. +- The `StandardAnalyzers` module adds [`StyleCop.Analyzers` 1.3.133-beta](docs/sdk-modules/standard-analyzers.md#package-references), which supports C# 8 to 15 and adds several new rules. ### Bugs fixed in this release diff --git a/src/Buildvana.Sdk/Sdk/PackageVersions.props b/src/Buildvana.Sdk/Sdk/PackageVersions.props index 02e2033d..fba6a863 100644 --- a/src/Buildvana.Sdk/Sdk/PackageVersions.props +++ b/src/Buildvana.Sdk/Sdk/PackageVersions.props @@ -8,7 +8,7 @@ --> - + From d417739aec699de72c172122d24a48b1856c444a Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 03:17:06 +0200 Subject: [PATCH 12/15] Move the StyleCop settings from stylecop.json to .globalconfig StyleCop.Analyzers reads every setting from a `stylecop.*` key of `.globalconfig`, and `stylecop.json` only overrode those keys. Keeping both files split the StyleCop configuration in two. The new settings section of `.globalconfig` lists every setting with its value, defaults included, as `.globalconfig` already lists every StyleCop rule. StyleCop reads three settings from standard keys, such as `csharp_using_directive_placement`. Those settings stay implicit, because the standard keys already hold the values `stylecop.json` set. Co-Authored-By: Claude Opus 5.5 --- .claude/rules/common/file-formats.md | 2 +- .github/CODEOWNERS | 1 - .github/labeler.yml | 1 - .globalconfig | 49 +++++++++++++++++++++++++ Buildvana.slnx | 1 - stylecop.json | 54 ---------------------------- 6 files changed, 50 insertions(+), 58 deletions(-) delete mode 100644 stylecop.json diff --git a/.claude/rules/common/file-formats.md b/.claude/rules/common/file-formats.md index c4e957c1..86b8b545 100644 --- a/.claude/rules/common/file-formats.md +++ b/.claude/rules/common/file-formats.md @@ -17,7 +17,7 @@ A section below overrides them for its own file type. ## C# source files (`*.cs`) - Charset: UTF-8 without BOM, as for every other file. -- Every file opens with the copyright preamble whose text `stylecop.json` holds. SA1633, SA1634, and SA1636 check it. +- Every file opens with the copyright preamble whose text the StyleCop `copyrightText` setting holds. SA1633, SA1634, and SA1636 check it. - A scratch `.cs` file under `.claude/scratchpad/` needs no preamble. The `Common.props` there turns StyleCop off. ## MSBuild XML files (`*.*proj`, `*.props`, `*.targets`) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 08b6e2cd..e0e74378 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -17,7 +17,6 @@ THIRD-PARTY-NOTICES @rdeago Directory.Build.* @rdeago .editorconfig @rdeago .globalconfig @rdeago -stylecop.json @rdeago *.DotSettings @rdeago NuGet.config @rdeago /.buildvana/ @rdeago diff --git a/.github/labeler.yml b/.github/labeler.yml index 8203e99c..0ce013b6 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -20,7 +20,6 @@ - any-glob-to-any-file: - '**/.editorconfig' - '**/.globalconfig' - - '**/stylecop.json' - '**/*.DotSettings' 'area:repo': diff --git a/.globalconfig b/.globalconfig index 79a3ee28..793c7402 100644 --- a/.globalconfig +++ b/.globalconfig @@ -242,6 +242,55 @@ dotnet_naming_style.begins_with_i.capitalization = pascal_case # Last update: 2026-10-20 (StyleCop.Analyzers v1.3.133-beta) # ============================================================================================== +# StyleCop Analyzers - Settings +# Every setting is listed, defaults included, in the order of the settings reference: +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md#settings-reference +# A value cannot contain '#' or ';', because the compiler reads the rest of the line as a comment. +# StyleCop.Analyzers reads these settings from standard keys, set elsewhere: +# - indentation from indent_size, tab_width, and indent_style (.editorconfig); +# - systemUsingDirectivesFirst from dotnet_sort_system_directives_first; +# - usingDirectivesPlacement from csharp_using_directive_placement; +# - newlineAtEndOfFile from insert_final_newline (.editorconfig). + +# Readability +stylecop.readability.allowBuiltInTypeAliases = true + +# Ordering +stylecop.ordering.elementOrder = kind, accessibility, constant, static, readonly +# Setting memberKindOrder omitted: no value states its default, the predefined SA1201 order. +# The standard key dotnet_separate_import_directive_groups = false would read as "allow", not "omit". +stylecop.ordering.blankLinesBetweenUsingGroups = omit + +# Naming +stylecop.naming.allowCommonHungarianPrefixes = true +stylecop.naming.allowedHungarianPrefixes = db, id, x +stylecop.naming.allowedNamespaceComponents = +stylecop.naming.includeInferredTupleElementNames = false +stylecop.naming.tupleElementNameCasing = pascalCase + +# Maintainability +stylecop.maintainability.topLevelTypes = class, interface, struct, enum, delegate + +# Layout +stylecop.layout.allowConsecutiveUsings = true +stylecop.layout.allowBracelessIfStatements = off +stylecop.layout.allowDoWhileOnClosingBrace = true + +# Documentation +stylecop.documentation.documentExposedElements = true +stylecop.documentation.documentInternalElements = false +stylecop.documentation.documentPrivateElements = false +stylecop.documentation.documentPrivateFields = false +stylecop.documentation.documentInterfaces = all +stylecop.documentation.companyName = Tenacom +stylecop.documentation.copyrightText = Copyright (C) Tenacom and Contributors. Licensed under the MIT license.\nSee the LICENSE file in the project root for full license information. +# Settings stylecop.documentation.variables.* omitted: copyrightText uses no variables. +stylecop.documentation.headerDecoration = +stylecop.documentation.xmlHeader = false +stylecop.documentation.fileNamingConvention = metadata +stylecop.documentation.documentationCulture = en-US +stylecop.documentation.excludeFromPunctuationCheck = exception, seealso + # StyleCop Analyzers - Special rules dotnet_diagnostic.SA0001.severity = warning # XML comment analysis disabled dotnet_diagnostic.SA0002.severity = warning # Invalid settings file diff --git a/Buildvana.slnx b/Buildvana.slnx index cbb13bb5..accc0932 100644 --- a/Buildvana.slnx +++ b/Buildvana.slnx @@ -14,7 +14,6 @@ - diff --git a/stylecop.json b/stylecop.json deleted file mode 100644 index 7a17e19b..00000000 --- a/stylecop.json +++ /dev/null @@ -1,54 +0,0 @@ -// See https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/Configuration.md -// for a reference guide to the contents of this file. -{ - "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", - - "settings": { - - "spacingRules": { - }, - - "readabilityRules": { - "allowBuiltInTypeAliases": true - }, - - "orderingRules": { - "elementOrder": [ "kind", "accessibility", "constant", "static", "readonly" ], - "systemUsingDirectivesFirst": true, - "usingDirectivesPlacement": "outsideNamespace", - "blankLinesBetweenUsingGroups": "omit" - }, - - "namingRules": { - "allowCommonHungarianPrefixes": true, - "allowedHungarianPrefixes": ["db", "id", "x"], - "allowedNamespaceComponents": [], - "includeInferredTupleElementNames": false, - "tupleElementNameCasing": "PascalCase" - }, - - "maintainabilityRules": { - "topLevelTypes": [ "class", "interface", "struct", "enum", "delegate" ] - }, - - "layoutRules": { - "newlineAtEndOfFile": "require", - "allowConsecutiveUsings": true, - "allowDoWhileOnClosingBrace": true - }, - - "documentationRules": { - "companyName": "Tenacom", - "copyrightText": "Copyright (C) {companyName} and Contributors. Licensed under the MIT license.\nSee the LICENSE file in the project root for full license information.", - "xmlHeader": false, - "documentInterfaces": true, - "documentExposedElements": true, - "documentInternalElements": false, - "documentPrivateElements": false, - "documentPrivateFields": false, - "documentationCulture": "en-US", - "fileNamingConvention": "metadata", - "excludeFromPunctuationCheck": [ "exception", "seealso" ] - } - } -} From a79c8c83aa3ee335da85ba16f2bc36c0dbb8d7d2 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 03:17:56 +0200 Subject: [PATCH 13/15] Stop saying a project without stylecop.json gets StyleCop defaults `standard-analyzers.md` said that a project without a `stylecop.json` file runs StyleCop with its default settings. StyleCop.Analyzers also reads each setting from a key of `.editorconfig` or `.globalconfig`, and a value in `stylecop.json` wins over the key. Co-Authored-By: Claude Opus 5.5 --- docs/sdk-modules/standard-analyzers.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sdk-modules/standard-analyzers.md b/docs/sdk-modules/standard-analyzers.md index aba3a389..d163996f 100644 --- a/docs/sdk-modules/standard-analyzers.md +++ b/docs/sdk-modules/standard-analyzers.md @@ -95,7 +95,8 @@ It looks for `stylecop.json` from the project directory upward, and for `.stylec A file above the home directory does not count. The nearest file wins, so a file in the home directory serves every project, and a file nearer a project replaces it for that project. The file does not show in the project tree of an IDE. -A project with no such file runs StyleCop with its default settings. +StyleCop also reads each setting from a key of `.editorconfig` or `.globalconfig`, and a value in the file wins over the key. +A project with no such file takes its settings from those keys, and the defaults for the rest. ### Public API files From 437afc103538276ee2ec2ffaf522041bc7dc8d9c Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 09:30:38 +0200 Subject: [PATCH 14/15] Move companyName and copyrightText to the solution-specific overrides The StyleCop settings section of `.globalconfig` set `stylecop.documentation.companyName` and `stylecop.documentation.copyrightText` to the values of this repository. Every other setting above the solution-specific overrides holds a value that does not depend on the repository. The settings section now holds the StyleCop defaults for both, and the overrides set the values of this repository. Roslyn keeps the last value of a key repeated in one section, so the overrides win. Co-Authored-By: Claude Opus 5.5 --- .globalconfig | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.globalconfig b/.globalconfig index 793c7402..886a4cd6 100644 --- a/.globalconfig +++ b/.globalconfig @@ -282,8 +282,9 @@ stylecop.documentation.documentInternalElements = false stylecop.documentation.documentPrivateElements = false stylecop.documentation.documentPrivateFields = false stylecop.documentation.documentInterfaces = all -stylecop.documentation.companyName = Tenacom -stylecop.documentation.copyrightText = Copyright (C) Tenacom and Contributors. Licensed under the MIT license.\nSee the LICENSE file in the project root for full license information. +# Do not change companyName and copyrightText here. See the solution-specific section at the end of this file. +stylecop.documentation.companyName = PlaceholderCompany +stylecop.documentation.copyrightText = Copyright (c) {companyName}. All rights reserved. # Settings stylecop.documentation.variables.* omitted: copyrightText uses no variables. stylecop.documentation.headerDecoration = stylecop.documentation.xmlHeader = false @@ -584,6 +585,10 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor - No. Just n # SOLUTION-SPECIFIC OVERRIDES # ============================================================================================== +# These project-specific values are used for StyleCop documentation rules. +stylecop.documentation.companyName = Tenacom +stylecop.documentation.copyrightText = Copyright (C) Tenacom and Contributors. Licensed under the MIT license.\nSee the LICENSE file in the project root for full license information. + # Given the type of C# projects (compiled MSBuild tasks, CLI tool) we don't need to optimize logging with LoggerMessage delegates (CA1848), # nor do we need CA1873 to complain that "argument evaluation may be expensive when logging is disabled". # Disabling these rules globally helps keep code clean and simple without needing to sprinkle pragmas or suppressions around. From 5cff33dac403a1fb66ab0f6db1c8af3873264b20 Mon Sep 17 00:00:00 2001 From: Riccardo De Agostini Date: Tue, 20 Oct 2026 10:52:29 +0200 Subject: [PATCH 15/15] Stop holding Microsoft.Build.NoTargets to patch updates The `Microsoft.Build*` pattern in the `dependencies.policies` of `buildvana.jsonc` and `buildvana.next.jsonc` also matched the `Microsoft.Build.NoTargets` pin in `global.json`. `dotnet bv deps update` would then never move that pin to a new minor version. The package has versions of its own, as `Microsoft.Build.Locator` does, and so do other `Microsoft.Build.*` packages on NuGet. The `patch` policy therefore goes to `Microsoft.Build`, `Microsoft.Build.Framework`, `Microsoft.Build.Tasks.Core`, and `Microsoft.Build.Utilities.Core` by id. Every other `Microsoft.Build.*` pin gets the default policy of its scope. Co-Authored-By: Claude Opus 5.5 --- buildvana.jsonc | 8 ++++---- buildvana.next.jsonc | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/buildvana.jsonc b/buildvana.jsonc index 3269a021..1def6c28 100644 --- a/buildvana.jsonc +++ b/buildvana.jsonc @@ -90,12 +90,12 @@ "Louis.*": "minor-", "StyleCop.Analyzers": "minor-", "Microsoft.CodeAnalysis.*": "patch", - // Microsoft.Build.Locator has versions of its own. This entry keeps it - // out of the pattern below. - "Microsoft.Build.Locator": "minor", // The MSBuild packages stay at BV_MinMSBuildVersion, the MSBuild floor. // Move them with --to when the floor moves. - "Microsoft.Build*": "patch", + "Microsoft.Build": "patch", + "Microsoft.Build.Framework": "patch", + "Microsoft.Build.Tasks.Core": "patch", + "Microsoft.Build.Utilities.Core": "patch", }, "additionalPackages": { "SDK package injections": { diff --git a/buildvana.next.jsonc b/buildvana.next.jsonc index 44ff728b..68f709af 100644 --- a/buildvana.next.jsonc +++ b/buildvana.next.jsonc @@ -90,12 +90,12 @@ "Louis.*": "minor-", "StyleCop.Analyzers": "minor-", "Microsoft.CodeAnalysis.*": "patch", - // Microsoft.Build.Locator has versions of its own. This entry keeps it - // out of the pattern below. - "Microsoft.Build.Locator": "minor", // The MSBuild packages stay at BV_MinMSBuildVersion, the MSBuild floor. // Move them with --to when the floor moves. - "Microsoft.Build*": "patch", + "Microsoft.Build": "patch", + "Microsoft.Build.Framework": "patch", + "Microsoft.Build.Tasks.Core": "patch", + "Microsoft.Build.Utilities.Core": "patch", }, "additionalPackages": { "SDK package injections": {