From 297004be7bdc97207f8050301475810bdc6f6143 Mon Sep 17 00:00:00 2001 From: Artur Stolear Date: Wed, 9 Oct 2024 23:05:44 +0200 Subject: [PATCH 1/3] (build) Refactor task arguments for readability and maintainability This commit improves the arguments presented by each task in our system, switching from directly using TaskArgument with constant data to an attribute approach. This change will make our code easier to read and maintain, whilst preserving the functionality of the tasks. The attribute classes provide a more explicit specification of the argument options, leading to a better understanding of the system requirements. --- .../Tasks/ArtifactsDotnetToolTest.cs | 6 +++--- .../Tasks/ArtifactsMsBuildCoreTest.cs | 6 +++--- build/artifacts/Tasks/ArtifactsNativeTest.cs | 6 +++--- build/artifacts/Tasks/ArtifactsPrepare.cs | 6 +++--- build/artifacts/Tasks/ArtifactsTest.cs | 6 +++--- build/build/Tasks/Test/UnitTest.cs | 2 +- .../Addins/GitVersion/GitVersionAliases.cs | 10 ++------- .../Addins/GitVersion/GitVersionRunner.cs | 21 ++++++++----------- build/common/Utilities/Constants.cs | 4 +++- build/common/Utilities/Extensions.cs | 15 +++---------- .../Utilities/TaskArgumentsAttribute.cs | 20 ++++++++++++++++++ build/docker/Tasks/DockerBuild.cs | 8 +++---- build/docker/Tasks/DockerHubReadmePublish.cs | 1 + build/docker/Tasks/DockerManifest.cs | 6 +++--- build/docker/Tasks/DockerPublish.cs | 8 +++---- build/docker/Tasks/DockerTest.cs | 8 +++---- 16 files changed, 69 insertions(+), 64 deletions(-) diff --git a/build/artifacts/Tasks/ArtifactsDotnetToolTest.cs b/build/artifacts/Tasks/ArtifactsDotnetToolTest.cs index 407c66ffdf..ebe194aaf6 100644 --- a/build/artifacts/Tasks/ArtifactsDotnetToolTest.cs +++ b/build/artifacts/Tasks/ArtifactsDotnetToolTest.cs @@ -4,9 +4,9 @@ namespace Artifacts.Tasks; [TaskName(nameof(ArtifactsDotnetToolTest))] [TaskDescription("Tests the dotnet global tool in docker container")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] [IsDependentOn(typeof(ArtifactsPrepare))] public class ArtifactsDotnetToolTest : FrostingTask { diff --git a/build/artifacts/Tasks/ArtifactsMsBuildCoreTest.cs b/build/artifacts/Tasks/ArtifactsMsBuildCoreTest.cs index 273d1f7443..982351ed32 100644 --- a/build/artifacts/Tasks/ArtifactsMsBuildCoreTest.cs +++ b/build/artifacts/Tasks/ArtifactsMsBuildCoreTest.cs @@ -4,9 +4,9 @@ namespace Artifacts.Tasks; [TaskName(nameof(ArtifactsMsBuildCoreTest))] [TaskDescription("Tests the msbuild package in docker container")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] [IsDependentOn(typeof(ArtifactsPrepare))] public class ArtifactsMsBuildCoreTest : FrostingTask { diff --git a/build/artifacts/Tasks/ArtifactsNativeTest.cs b/build/artifacts/Tasks/ArtifactsNativeTest.cs index 61926bca48..2812ab76f2 100644 --- a/build/artifacts/Tasks/ArtifactsNativeTest.cs +++ b/build/artifacts/Tasks/ArtifactsNativeTest.cs @@ -4,9 +4,9 @@ namespace Artifacts.Tasks; [TaskName(nameof(ArtifactsNativeTest))] [TaskDescription("Tests the native executables in docker container")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] [IsDependentOn(typeof(ArtifactsPrepare))] public class ArtifactsNativeTest : FrostingTask { diff --git a/build/artifacts/Tasks/ArtifactsPrepare.cs b/build/artifacts/Tasks/ArtifactsPrepare.cs index 4446285831..2e55089920 100644 --- a/build/artifacts/Tasks/ArtifactsPrepare.cs +++ b/build/artifacts/Tasks/ArtifactsPrepare.cs @@ -4,9 +4,9 @@ namespace Artifacts.Tasks; [TaskName(nameof(ArtifactsPrepare))] [TaskDescription("Pulls the docker images needed for testing the artifacts")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] public class ArtifactsPrepare : FrostingTask { public override bool ShouldRun(BuildContext context) diff --git a/build/artifacts/Tasks/ArtifactsTest.cs b/build/artifacts/Tasks/ArtifactsTest.cs index ab6ca4e34a..763aeb45e9 100644 --- a/build/artifacts/Tasks/ArtifactsTest.cs +++ b/build/artifacts/Tasks/ArtifactsTest.cs @@ -4,9 +4,9 @@ namespace Artifacts.Tasks; [TaskName(nameof(ArtifactsTest))] [TaskDescription("Tests packages in docker container")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] [IsDependentOn(typeof(ArtifactsNativeTest))] [IsDependentOn(typeof(ArtifactsDotnetToolTest))] [IsDependentOn(typeof(ArtifactsMsBuildCoreTest))] diff --git a/build/build/Tasks/Test/UnitTest.cs b/build/build/Tasks/Test/UnitTest.cs index 6e012abd46..0ca142cc99 100644 --- a/build/build/Tasks/Test/UnitTest.cs +++ b/build/build/Tasks/Test/UnitTest.cs @@ -8,7 +8,7 @@ namespace Build.Tasks; [TaskName(nameof(UnitTest))] [TaskDescription("Run the unit tests")] -[TaskArgument(Arguments.DotnetTarget, Constants.VersionCurrent, Constants.VersionLatest)] +[DotnetArgument] [IsDependentOn(typeof(Build))] public class UnitTest : FrostingTask { diff --git a/build/common/Addins/GitVersion/GitVersionAliases.cs b/build/common/Addins/GitVersion/GitVersionAliases.cs index 0d4d292ea2..16ccd229d2 100644 --- a/build/common/Addins/GitVersion/GitVersionAliases.cs +++ b/build/common/Addins/GitVersion/GitVersionAliases.cs @@ -54,10 +54,7 @@ public static class GitVersionAliases [CakeMethodAlias] public static GitVersion GitVersion(this ICakeContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgumentNullException.ThrowIfNull(context); return GitVersion(context, new GitVersionSettings()); } @@ -104,10 +101,7 @@ public static GitVersion GitVersion(this ICakeContext context) [CakeMethodAlias] public static GitVersion GitVersion(this ICakeContext context, GitVersionSettings settings) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgumentNullException.ThrowIfNull(context); var gitVersionRunner = new GitVersionRunner(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools, context.Log); return gitVersionRunner.Run(settings); diff --git a/build/common/Addins/GitVersion/GitVersionRunner.cs b/build/common/Addins/GitVersion/GitVersionRunner.cs index 1143849474..dd391d2532 100644 --- a/build/common/Addins/GitVersion/GitVersionRunner.cs +++ b/build/common/Addins/GitVersion/GitVersionRunner.cs @@ -8,7 +8,7 @@ namespace Common.Addins.GitVersion; /// public sealed class GitVersionRunner : Tool { - private readonly ICakeLog log; + private readonly ICakeLog _log; /// /// Initializes a new instance of the class. @@ -23,7 +23,7 @@ public GitVersionRunner( ICakeEnvironment environment, IProcessRunner processRunner, IToolLocator tools, - ICakeLog log) : base(fileSystem, environment, processRunner, tools) => this.log = log; + ICakeLog log) : base(fileSystem, environment, processRunner, tools) => this._log = log; /// /// Runs GitVersion and processes the results. @@ -32,22 +32,19 @@ public GitVersionRunner( /// A task with the GitVersion results. public GitVersion Run(GitVersionSettings settings) { - if (settings == null) - { - throw new ArgumentNullException(nameof(settings)); - } + ArgumentNullException.ThrowIfNull(settings); var output = string.Empty; Run(settings, GetArguments(settings), new ProcessSettings { RedirectStandardOutput = true }, process => { output = string.Join("\n", process.GetStandardOutput()); - if (log.Verbosity < Verbosity.Diagnostic) + if (this._log.Verbosity < Verbosity.Diagnostic) { var errors = Regex.Matches(output, @"( *ERROR:? [^\n]*)\n([^\n]*)") .SelectMany(match => new[] { match.Groups[1].Value, match.Groups[2].Value }); foreach (var error in errors) { - log.Error(error); + this._log.Error(error); } } }); @@ -55,8 +52,8 @@ public GitVersion Run(GitVersionSettings settings) if (!settings.OutputTypes.Contains(GitVersionOutput.Json)) return new GitVersion(); - var jsonStartIndex = output.IndexOf("{", StringComparison.Ordinal); - var jsonEndIndex = output.IndexOf("}", StringComparison.Ordinal); + var jsonStartIndex = output.IndexOf('{'); + var jsonEndIndex = output.IndexOf('}'); var json = output.Substring(jsonStartIndex, jsonEndIndex - jsonStartIndex + 1); return JsonConvert.DeserializeObject(json) ?? new GitVersion(); @@ -119,7 +116,7 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) } else { - log.Warning("If you leave the branch name for GitVersion unset, it will fallback to the default branch for the repository."); + this._log.Warning("If you leave the branch name for GitVersion unset, it will fallback to the default branch for the repository."); } if (!string.IsNullOrWhiteSpace(settings.Commit)) @@ -146,7 +143,7 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) builder.Append("-nofetch"); } - var verbosity = settings.Verbosity ?? log.Verbosity; + var verbosity = settings.Verbosity ?? this._log.Verbosity; if (verbosity != Verbosity.Normal) { diff --git a/build/common/Utilities/Constants.cs b/build/common/Utilities/Constants.cs index 9347b9d937..dad50fc2f2 100644 --- a/build/common/Utilities/Constants.cs +++ b/build/common/Utilities/Constants.cs @@ -21,10 +21,13 @@ public static class Constants public const string GitHub = "github"; public const string DockerHubRegistry = "docker.io"; public const string GitHubContainerRegistry = "ghcr.io"; + public static readonly string[] DockerRegistries = [DockerHub, GitHub]; public const string Arm64 = "arm64"; public const string Amd64 = "amd64"; + public static readonly string[] Architectures = [Amd64, Arm64]; + public const string AlpineLatest = "alpine.3.20"; public const string CentosStreamLatest = "centos.stream.9"; public const string DebianLatest = "debian.12"; @@ -32,7 +35,6 @@ public static class Constants public const string Ubuntu2004 = "ubuntu.20.04"; public const string Ubuntu2204 = "ubuntu.22.04"; public const string Ubuntu2404 = "ubuntu.24.04"; - public const string UbuntuLatest = Ubuntu2404; public const string DockerDistroLatest = DebianLatest; diff --git a/build/common/Utilities/Extensions.cs b/build/common/Utilities/Extensions.cs index 1c0dde261f..5691ef09fa 100644 --- a/build/common/Utilities/Extensions.cs +++ b/build/common/Utilities/Extensions.cs @@ -13,10 +13,7 @@ where baseType.IsAssignableFrom(type) && info.IsClass && !info.IsAbstract public static string GetTaskDescription(this Type task) { - if (task is null) - { - throw new ArgumentNullException(nameof(task)); - } + ArgumentNullException.ThrowIfNull(task); var attribute = task.GetCustomAttribute(); return attribute != null ? attribute.Description : string.Empty; @@ -24,10 +21,7 @@ public static string GetTaskDescription(this Type task) public static string GetTaskName(this Type task) { - if (task is null) - { - throw new ArgumentNullException(nameof(task)); - } + ArgumentNullException.ThrowIfNull(task); var attribute = task.GetCustomAttribute(); return attribute != null ? attribute.Name : task.Name; @@ -35,10 +29,7 @@ public static string GetTaskName(this Type task) public static string GetTaskArguments(this Type task) { - if (task is null) - { - throw new ArgumentNullException(nameof(task)); - } + ArgumentNullException.ThrowIfNull(task); var attributes = task.GetCustomAttributes().ToArray(); if (attributes.Length != 0) diff --git a/build/common/Utilities/TaskArgumentsAttribute.cs b/build/common/Utilities/TaskArgumentsAttribute.cs index 54a618c953..bd856ce6f3 100644 --- a/build/common/Utilities/TaskArgumentsAttribute.cs +++ b/build/common/Utilities/TaskArgumentsAttribute.cs @@ -10,3 +10,23 @@ public class TaskArgumentAttribute(string name, params string[] possibleValues) public string Name { get; } = name; public string[] PossibleValues { get; } = possibleValues; } + +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] +public class DotnetArgumentAttribute() + : TaskArgumentAttribute(Arguments.DotnetTarget, Constants.Frameworks); + +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] +public class DockerDotnetArgumentAttribute() + : TaskArgumentAttribute(Arguments.DockerDotnetVersion, Constants.Frameworks); + +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] +public class DockerDistroArgumentAttribute() + : TaskArgumentAttribute(Arguments.DockerDistro, Constants.DockerDistrosToBuild); + +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] +public class DockerRegistryArgumentAttribute() + : TaskArgumentAttribute(Arguments.DockerRegistry, Constants.DockerRegistries); + +[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] +public class ArchitectureArgumentAttribute() + : TaskArgumentAttribute(Arguments.Architecture, Constants.Architectures); diff --git a/build/docker/Tasks/DockerBuild.cs b/build/docker/Tasks/DockerBuild.cs index 3ba1181164..da6586c776 100644 --- a/build/docker/Tasks/DockerBuild.cs +++ b/build/docker/Tasks/DockerBuild.cs @@ -4,10 +4,10 @@ namespace Docker.Tasks; [TaskName(nameof(DockerBuild))] [TaskDescription("Build the docker images containing the GitVersion Tool")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] -[TaskArgument(Arguments.Architecture, Constants.Amd64, Constants.Arm64)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] +[ArchitectureArgument] public class DockerBuild : FrostingTask { public override bool ShouldRun(BuildContext context) diff --git a/build/docker/Tasks/DockerHubReadmePublish.cs b/build/docker/Tasks/DockerHubReadmePublish.cs index f9e1531fd9..318b6ad7da 100644 --- a/build/docker/Tasks/DockerHubReadmePublish.cs +++ b/build/docker/Tasks/DockerHubReadmePublish.cs @@ -8,6 +8,7 @@ namespace Docker.Tasks; [IsDependentOn(typeof(DockerHubReadmePublishInternal))] [TaskDescription("Publish the DockerHub updated README.md")] public class DockerHubReadmePublish : FrostingTask; + [TaskName(nameof(DockerHubReadmePublishInternal))] [TaskDescription("Publish the DockerHub updated README.md")] public class DockerHubReadmePublishInternal : FrostingTask diff --git a/build/docker/Tasks/DockerManifest.cs b/build/docker/Tasks/DockerManifest.cs index 6f9e2319d0..ae099f781b 100644 --- a/build/docker/Tasks/DockerManifest.cs +++ b/build/docker/Tasks/DockerManifest.cs @@ -4,9 +4,9 @@ namespace Docker.Tasks; [TaskName(nameof(DockerManifest))] [TaskDescription("Publish the docker manifest containing the images for amd64 and arm64")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] [IsDependentOn(typeof(DockerManifestInternal))] public class DockerManifest : FrostingTask { diff --git a/build/docker/Tasks/DockerPublish.cs b/build/docker/Tasks/DockerPublish.cs index 31204c4744..b230a4d59c 100644 --- a/build/docker/Tasks/DockerPublish.cs +++ b/build/docker/Tasks/DockerPublish.cs @@ -4,10 +4,10 @@ namespace Docker.Tasks; [TaskName(nameof(DockerPublish))] [TaskDescription("Publish the docker images containing the GitVersion Tool")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] -[TaskArgument(Arguments.Architecture, Constants.Amd64, Constants.Arm64)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] +[ArchitectureArgument] [IsDependentOn(typeof(DockerPublishInternal))] public class DockerPublish : FrostingTask { diff --git a/build/docker/Tasks/DockerTest.cs b/build/docker/Tasks/DockerTest.cs index 3257f20267..3acc68372a 100644 --- a/build/docker/Tasks/DockerTest.cs +++ b/build/docker/Tasks/DockerTest.cs @@ -4,10 +4,10 @@ namespace Docker.Tasks; [TaskName(nameof(DockerTest))] [TaskDescription("Test the docker images containing the GitVersion Tool")] -[TaskArgument(Arguments.DockerRegistry, Constants.DockerHub, Constants.GitHub)] -[TaskArgument(Arguments.DockerDotnetVersion, Constants.VersionCurrent, Constants.VersionLatest)] -[TaskArgument(Arguments.DockerDistro, Constants.AlpineLatest, Constants.DebianLatest, Constants.UbuntuLatest)] -[TaskArgument(Arguments.Architecture, Constants.Amd64, Constants.Arm64)] +[DockerRegistryArgument] +[DockerDotnetArgument] +[DockerDistroArgument] +[ArchitectureArgument] [IsDependentOn(typeof(DockerBuild))] public class DockerTest : FrostingTask { From 35e272c009a1ba069e6f030391f44d4a027e55a6 Mon Sep 17 00:00:00 2001 From: Artur Stolear Date: Wed, 9 Oct 2024 23:33:33 +0200 Subject: [PATCH 2/3] (build) Added ArgumentNullException checks for context.Version in various files. Improved error messaging and updated some syntax for consistency and clarity --- .../Tasks/ArtifactsExecutableTest.cs | 6 ++-- .../Tasks/ArtifactsMsBuildFullTest.cs | 2 +- build/build/BuildLifetime.cs | 3 +- build/build/Tasks/Build.cs | 2 +- build/build/Tasks/BuildPrepare.cs | 2 +- .../build/Tasks/Package/PackageChocolatey.cs | 15 ++++----- build/build/Tasks/Test/UnitTest.cs | 2 +- build/build/Tasks/ValidateVersion.cs | 3 +- .../Addins/GitVersion/GitVersionRunner.cs | 31 +++++++++++++------ build/common/Lifetime/BuildLifetimeBase.cs | 9 +++++- build/common/Utilities/BuildContextBase.cs | 2 +- .../Utilities/DockerContextExtensions.cs | 7 +++-- build/docker/Tasks/DockerHubReadmePublish.cs | 6 ++-- build/docs/Tasks/GenerateSchemas.cs | 3 +- build/publish/Tasks/PublishChocolatey.cs | 3 +- build/publish/Tasks/PublishNuget.cs | 3 +- 16 files changed, 63 insertions(+), 36 deletions(-) diff --git a/build/artifacts/Tasks/ArtifactsExecutableTest.cs b/build/artifacts/Tasks/ArtifactsExecutableTest.cs index 7acc9f7b47..894f3ba331 100644 --- a/build/artifacts/Tasks/ArtifactsExecutableTest.cs +++ b/build/artifacts/Tasks/ArtifactsExecutableTest.cs @@ -36,10 +36,10 @@ private static void PackageTest(BuildContextBase context, string packageToTest) context.NuGetInstall(packageToTest, new NuGetInstallSettings { - Source = new[] - { + Source = + [ context.MakeAbsolute(Paths.Nuget).FullPath - }, + ], ExcludeVersion = true, Prerelease = true, OutputDirectory = outputDirectory diff --git a/build/artifacts/Tasks/ArtifactsMsBuildFullTest.cs b/build/artifacts/Tasks/ArtifactsMsBuildFullTest.cs index 26d4f372d3..8829430d07 100644 --- a/build/artifacts/Tasks/ArtifactsMsBuildFullTest.cs +++ b/build/artifacts/Tasks/ArtifactsMsBuildFullTest.cs @@ -36,7 +36,7 @@ public override void Run(BuildContext context) Verbosity = DotNetVerbosity.Minimal, Configuration = context.MsBuildConfiguration, MSBuildSettings = dotnetMsBuildSettings, - Sources = new[] { nugetSource } + Sources = [nugetSource] }); var exe = Paths.Integration.Combine("build").Combine(framework).CombineWithFilePath("app.dll"); diff --git a/build/build/BuildLifetime.cs b/build/build/BuildLifetime.cs index fb16f3e2e2..5f0f0dc943 100644 --- a/build/build/BuildLifetime.cs +++ b/build/build/BuildLifetime.cs @@ -29,7 +29,8 @@ public override void Setup(BuildContext context, ISetupContext info) private static void SetMsBuildSettingsVersion(BuildContext context) { var msBuildSettings = context.MsBuildSettings; - var version = context.Version!; + ArgumentNullException.ThrowIfNull(context.Version); + var version = context.Version; msBuildSettings.SetVersion(version.SemVersion); msBuildSettings.SetAssemblyVersion(version.Version); diff --git a/build/build/Tasks/Build.cs b/build/build/Tasks/Build.cs index a20efdde4b..0561c3f69b 100644 --- a/build/build/Tasks/Build.cs +++ b/build/build/Tasks/Build.cs @@ -16,7 +16,7 @@ public override void Run(BuildContext context) context.DotNetRestore(sln, new DotNetRestoreSettings { Verbosity = DotNetVerbosity.Minimal, - Sources = new[] { Constants.NugetOrgUrl }, + Sources = [Constants.NugetOrgUrl], MSBuildSettings = context.MsBuildSettings }); diff --git a/build/build/Tasks/BuildPrepare.cs b/build/build/Tasks/BuildPrepare.cs index fe85bbb561..46f3de017d 100644 --- a/build/build/Tasks/BuildPrepare.cs +++ b/build/build/Tasks/BuildPrepare.cs @@ -16,7 +16,7 @@ public override void Run(BuildContext context) new() { Verbosity = DotNetVerbosity.Minimal, - Sources = new[] { Constants.NugetOrgUrl }, + Sources = [Constants.NugetOrgUrl], }); context.DotNetBuild("./src/GitVersion.App/GitVersion.App.csproj", diff --git a/build/build/Tasks/Package/PackageChocolatey.cs b/build/build/Tasks/Package/PackageChocolatey.cs index 73fbe63878..22f68b5b01 100644 --- a/build/build/Tasks/Package/PackageChocolatey.cs +++ b/build/build/Tasks/Package/PackageChocolatey.cs @@ -35,10 +35,10 @@ public override void Run(BuildContext context) .Select(file => new ChocolateyNuSpecContent { Source = file.FullPath, Target = file.FullPath.Replace(artifactPath, "") }) .ToArray(); - metaPackageSettings.Dependencies = new[] - { + metaPackageSettings.Dependencies = + [ new ChocolateyNuSpecDependency { Id = "GitVersion.Portable", Version = context.Version?.ChocolateyVersion } - }; + ]; context.ChocolateyPack(metaPackageSettings); } @@ -51,8 +51,8 @@ private static ChocolateyPackSettings GetChocolateyPackSettings(BuildContextBase Version = context.Version?.ChocolateyVersion, Title = "GitVersion", Description = "Derives SemVer information from a repository following GitFlow or GitHubFlow.", - Authors = new[] { "GitTools and Contributors" }, - Owners = new[] { "GitTools and Contributors" }, + Authors = ["GitTools and Contributors"], + Owners = ["GitTools and Contributors"], Copyright = $"Copyright GitTools {DateTime.Now.Year}", DocsUrl = new Uri("https://gitversion.net/docs/"), LicenseUrl = new Uri("https://opensource.org/license/mit/"), @@ -60,8 +60,9 @@ private static ChocolateyPackSettings GetChocolateyPackSettings(BuildContextBase ProjectSourceUrl = new Uri("https://github.com/GitTools/GitVersion"), IconUrl = new Uri("https://raw.githubusercontent.com/GitTools/graphics/master/GitVersion/Color/icon_100x100.png"), RequireLicenseAcceptance = false, - Tags = new[] { "Git", "Versioning", "GitVersion", "GitFlowVersion", "GitFlow", "GitHubFlow", "SemVer" }, - ReleaseNotes = new[] { $"https://github.com/GitTools/GitVersion/releases/tag/{context.Version?.ChocolateyVersion}" }, + Tags = ["Git", "Versioning", "GitVersion", "GitFlowVersion", "GitFlow", "GitHubFlow", "SemVer"], + ReleaseNotes = [$"https://github.com/GitTools/GitVersion/releases/tag/{context.Version?.ChocolateyVersion}" + ], OutputDirectory = Paths.Nuget, LimitOutput = true, }; diff --git a/build/build/Tasks/Test/UnitTest.cs b/build/build/Tasks/Test/UnitTest.cs index 0ca142cc99..6178f34b4d 100644 --- a/build/build/Tasks/Test/UnitTest.cs +++ b/build/build/Tasks/Test/UnitTest.cs @@ -73,7 +73,7 @@ private static void TestProjectForTarget(BuildContext context, FilePath project, }; var resultsPath = context.MakeAbsolute(testResultsPath.CombineWithFilePath($"{projectName}.results.xml")); - settings.Loggers = new[] { $"junit;LogFilePath={resultsPath}" }; + settings.Loggers = [$"junit;LogFilePath={resultsPath}"]; var coverletSettings = new CoverletSettings { diff --git a/build/build/Tasks/ValidateVersion.cs b/build/build/Tasks/ValidateVersion.cs index 317a5caa7b..e88866ffca 100644 --- a/build/build/Tasks/ValidateVersion.cs +++ b/build/build/Tasks/ValidateVersion.cs @@ -9,7 +9,8 @@ public class ValidateVersion : FrostingTask { public override void Run(BuildContext context) { + ArgumentNullException.ThrowIfNull(context.Version); var gitVersionTool = context.GetGitVersionToolLocation(); - context.ValidateOutput("dotnet", $"\"{gitVersionTool}\" -version", context.Version!.GitVersion!.InformationalVersion!); + context.ValidateOutput("dotnet", $"\"{gitVersionTool}\" -version", context.Version.GitVersion.InformationalVersion); } } diff --git a/build/common/Addins/GitVersion/GitVersionRunner.cs b/build/common/Addins/GitVersion/GitVersionRunner.cs index dd391d2532..7da7defc4d 100644 --- a/build/common/Addins/GitVersion/GitVersionRunner.cs +++ b/build/common/Addins/GitVersion/GitVersionRunner.cs @@ -6,7 +6,7 @@ namespace Common.Addins.GitVersion; /// /// The GitVersion runner. /// -public sealed class GitVersionRunner : Tool +public sealed partial class GitVersionRunner : Tool { private readonly ICakeLog _log; @@ -38,14 +38,13 @@ public GitVersion Run(GitVersionSettings settings) Run(settings, GetArguments(settings), new ProcessSettings { RedirectStandardOutput = true }, process => { output = string.Join("\n", process.GetStandardOutput()); - if (this._log.Verbosity < Verbosity.Diagnostic) + if (this._log.Verbosity >= Verbosity.Diagnostic) return; + var regex = ParseErrorRegex(); + var errors = regex.Matches(output) + .SelectMany(match => new[] { match.Groups[1].Value, match.Groups[2].Value }); + foreach (var error in errors) { - var errors = Regex.Matches(output, @"( *ERROR:? [^\n]*)\n([^\n]*)") - .SelectMany(match => new[] { match.Groups[1].Value, match.Groups[2].Value }); - foreach (var error in errors) - { - this._log.Error(error); - } + this._log.Error(error); } }); @@ -68,6 +67,7 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) builder.Append("-output"); builder.Append("json"); } + if (settings.OutputTypes.Contains(GitVersionOutput.BuildServer)) { builder.Append("-output"); @@ -116,7 +116,8 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) } else { - this._log.Warning("If you leave the branch name for GitVersion unset, it will fallback to the default branch for the repository."); + this._log.Warning( + "If you leave the branch name for GitVersion unset, it will fallback to the default branch for the repository."); } if (!string.IsNullOrWhiteSpace(settings.Commit)) @@ -150,6 +151,7 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) builder.Append("-verbosity"); builder.Append(verbosity.ToString()); } + return builder; } @@ -163,5 +165,14 @@ private ProcessArgumentBuilder GetArguments(GitVersionSettings settings) /// Gets the possible names of the tool executable. /// /// The tool executable name. - protected override IEnumerable GetToolExecutableNames() => new[] { "GitVersion.exe", "dotnet-gitversion", "dotnet-gitversion.exe", "gitversion" }; + protected override IEnumerable GetToolExecutableNames() => + [ + "GitVersion.exe", + "dotnet-gitversion", + "dotnet-gitversion.exe", + "gitversion" + ]; + + [GeneratedRegex(@"( *ERROR:? [^\n]*)\n([^\n]*)")] + private static partial Regex ParseErrorRegex(); } diff --git a/build/common/Lifetime/BuildLifetimeBase.cs b/build/common/Lifetime/BuildLifetimeBase.cs index 1a7bb3fce6..139609d0f5 100644 --- a/build/common/Lifetime/BuildLifetimeBase.cs +++ b/build/common/Lifetime/BuildLifetimeBase.cs @@ -30,11 +30,18 @@ public override void Setup(T context, ISetupContext info) context.Information("Running BuildPrepare..."); return; } + + var gitVersionPath = context.GetGitVersionDotnetToolLocation(); + if (gitVersionPath is null || context.FileExists(gitVersionPath) is false) + { + throw new FileNotFoundException("Failed to locate the Release build of gitversion.dll in ./tools/gitversion. Try running \"./build.ps1 -Stage build -Target BuildPrepare\""); + } + var gitVersionSettings = new GitVersionSettings { OutputTypes = [GitVersionOutput.Json, GitVersionOutput.BuildServer], ToolPath = context.Tools.Resolve(["dotnet.exe", "dotnet"]), - ArgumentCustomization = args => args.Prepend(context.GetGitVersionDotnetToolLocation()?.FullPath ?? throw new FileNotFoundException("Failed to locate the Release build of gitversion.dll in ./tools/gitversion. Try running \"./build.ps1 -Stage build -Target BuildPrepare\"")) + ArgumentCustomization = args => args.Prepend(gitVersionPath.FullPath) }; var gitVersion = context.GitVersion(gitVersionSettings); diff --git a/build/common/Utilities/BuildContextBase.cs b/build/common/Utilities/BuildContextBase.cs index 6dba79bdc1..93be1fc1b6 100644 --- a/build/common/Utilities/BuildContextBase.cs +++ b/build/common/Utilities/BuildContextBase.cs @@ -2,7 +2,7 @@ namespace Common.Utilities; public class BuildContextBase : FrostingContext { - protected BuildContextBase(ICakeContext context) : base(context) => Platform = Environment.Platform.Family; + protected BuildContextBase(ICakeContext context) : base(context) => Platform = context.Environment.Platform.Family; public PlatformFamily Platform { get; set; } public BuildVersion? Version { get; set; } public bool IsOriginalRepo { get; set; } diff --git a/build/common/Utilities/DockerContextExtensions.cs b/build/common/Utilities/DockerContextExtensions.cs index c20e106994..06ab4de0ff 100644 --- a/build/common/Utilities/DockerContextExtensions.cs +++ b/build/common/Utilities/DockerContextExtensions.cs @@ -108,13 +108,14 @@ public static void DockerBuildXBuild(this ICakeContext context, DockerBuildXBuil public static void DockerManifest(this BuildContextBase context, DockerImage dockerImage) { + ArgumentNullException.ThrowIfNull(context.Version); var manifestTags = context.GetDockerTags(dockerImage); foreach (var tag in manifestTags) { var amd64Tag = $"{tag}-{Architecture.Amd64.ToSuffix()}"; var arm64Tag = $"{tag}-{Architecture.Arm64.ToSuffix()}"; - var settings = GetManifestSettings(dockerImage, context.Version!, tag); + var settings = GetManifestSettings(dockerImage, context.Version, tag); context.DockerBuildXImageToolsCreate(settings, [amd64Tag, arm64Tag]); } } @@ -186,13 +187,13 @@ public static void DockerTestArtifact(this BuildContextBase context, DockerImage private static void DockerTestRun(this BuildContextBase context, string image, Architecture arch, string command, params string[] args) { + ArgumentNullException.ThrowIfNull(context.Version?.GitVersion.FullSemVer); var settings = GetDockerRunSettings(context, arch); context.Information($"Testing image: {image}"); var output = context.DockerRun(settings, image, command, args); context.Information("Output : " + output); - Assert.NotNull(context.Version?.GitVersion); - Assert.Contains(context.Version.GitVersion.FullSemVer!, output); + Assert.Contains(context.Version.GitVersion.FullSemVer, output); } private static IEnumerable GetDockerTags(this BuildContextBase context, DockerImage dockerImage, diff --git a/build/docker/Tasks/DockerHubReadmePublish.cs b/build/docker/Tasks/DockerHubReadmePublish.cs index 318b6ad7da..8fb3d1f9de 100644 --- a/build/docker/Tasks/DockerHubReadmePublish.cs +++ b/build/docker/Tasks/DockerHubReadmePublish.cs @@ -26,11 +26,12 @@ public override bool ShouldRun(BuildContext context) public override void Run(BuildContext context) { + ArgumentNullException.ThrowIfNull(context.Credentials?.DockerHub); var readme = GetReadmeContent(context); var response = context.HttpPost("https://hub.docker.com/v2/users/login", settings => { - var credentials = context.Credentials!.DockerHub!; + var credentials = context.Credentials.DockerHub; settings .SetContentType("application/json") .SetJsonRequestBody(new { username = credentials.Username, password = credentials.Password }); @@ -49,7 +50,8 @@ public override void Run(BuildContext context) private static string GetReadmeContent(BuildContextBase context) { - var version = context.Version!.GitVersion.MajorMinorPatch; + ArgumentNullException.ThrowIfNull(context.Version); + var version = context.Version.GitVersion.MajorMinorPatch; const string distro = Constants.AlpineLatest; const string dotnetVersion = Constants.VersionLatest; var tag = $"{version}-{distro}-{dotnetVersion}"; diff --git a/build/docs/Tasks/GenerateSchemas.cs b/build/docs/Tasks/GenerateSchemas.cs index f4defba0dd..ffa1d1804f 100644 --- a/build/docs/Tasks/GenerateSchemas.cs +++ b/build/docs/Tasks/GenerateSchemas.cs @@ -8,8 +8,9 @@ public sealed class GenerateSchemas : FrostingTask { public override void Run(BuildContext context) { + ArgumentNullException.ThrowIfNull(context.Version); var schemaTool = context.GetSchemaDotnetToolLocation(); - var gitVersion = context.Version!.GitVersion; + var gitVersion = context.Version.GitVersion; var version = $"{gitVersion.Major}.{gitVersion.Minor}"; var schemaTargetDir = context.MakeAbsolute(Paths.Root.Combine("schemas")); context.EnsureDirectoryExists(schemaTargetDir); diff --git a/build/publish/Tasks/PublishChocolatey.cs b/build/publish/Tasks/PublishChocolatey.cs index fce099205d..078f555dc0 100644 --- a/build/publish/Tasks/PublishChocolatey.cs +++ b/build/publish/Tasks/PublishChocolatey.cs @@ -31,7 +31,8 @@ public override async Task RunAsync(BuildContext context) throw new InvalidOperationException("Could not resolve Chocolatey API key."); } - var nugetVersion = context.Version!.NugetVersion; + ArgumentNullException.ThrowIfNull(context.Version); + var nugetVersion = context.Version.NugetVersion; var packages = context.Packages .Where(x => x.IsChocoPackage) .OrderByDescending(x => x.PackageName); diff --git a/build/publish/Tasks/PublishNuget.cs b/build/publish/Tasks/PublishNuget.cs index 2abb602526..59649a35af 100644 --- a/build/publish/Tasks/PublishNuget.cs +++ b/build/publish/Tasks/PublishNuget.cs @@ -50,7 +50,8 @@ public override void Run(BuildContext context) } private static void PublishToNugetRepo(BuildContext context, string apiKey, string apiUrl) { - var nugetVersion = context.Version!.NugetVersion; + ArgumentNullException.ThrowIfNull(context.Version); + var nugetVersion = context.Version.NugetVersion; foreach (var (packageName, filePath, _) in context.Packages.Where(x => !x.IsChocoPackage)) { context.Information($"Package {packageName}, version {nugetVersion} is being published."); From ce12bb69f81f920d5505989f83237f7985c2231b Mon Sep 17 00:00:00 2001 From: Artur Stolear Date: Thu, 10 Oct 2024 00:04:21 +0200 Subject: [PATCH 3/3] (build) Refactor constants and improve code clarity Updated the `Constants.cs` to better organize and rename fields for architectures. Removed redundant constants and added proper code suppression for ReSharper. --- build/common/Utilities/Constants.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build/common/Utilities/Constants.cs b/build/common/Utilities/Constants.cs index dad50fc2f2..1dbb54c1fa 100644 --- a/build/common/Utilities/Constants.cs +++ b/build/common/Utilities/Constants.cs @@ -1,3 +1,4 @@ +// ReSharper disable MemberCanBePrivate.Global namespace Common.Utilities; public static class Constants @@ -7,12 +8,13 @@ public static class Constants public const string VersionCurrent = "6.0"; public const string VersionLatest = "8.0"; + public static readonly string[] Frameworks = [VersionCurrent, VersionLatest]; public const string DefaultBranch = "main"; public const string DefaultConfiguration = "Release"; public static readonly Architecture[] ArchToBuild = [Architecture.Amd64, Architecture.Arm64]; - public static readonly string[] Frameworks = [VersionCurrent, VersionLatest]; + public static readonly string[] Architectures = [nameof(Architecture.Amd64), nameof(Architecture.Arm64)]; public const string DockerBaseImageName = "gittools/build-images"; public const string DockerImageName = "gittools/gitversion"; @@ -23,11 +25,6 @@ public static class Constants public const string GitHubContainerRegistry = "ghcr.io"; public static readonly string[] DockerRegistries = [DockerHub, GitHub]; - public const string Arm64 = "arm64"; - public const string Amd64 = "amd64"; - - public static readonly string[] Architectures = [Amd64, Arm64]; - public const string AlpineLatest = "alpine.3.20"; public const string CentosStreamLatest = "centos.stream.9"; public const string DebianLatest = "debian.12";