diff --git a/.build/Build.cs b/.build/Build.cs index 3e0702b2..6ff88273 100644 --- a/.build/Build.cs +++ b/.build/Build.cs @@ -27,11 +27,11 @@ class Solution : DotNetCoreBuild, IDotNetCoreBuild .DependsOn(Pack) ; - public new Target Restore => _ => _.With(DotNetCoreBuild.Restore, this); + public new Target Restore => _ => _.With(this, DotNetCoreBuild.Restore); - public new Target Build => _ => _.With(DotNetCoreBuild.Build, this); + public new Target Build => _ => _.With(this, DotNetCoreBuild.Build); - public new Target Test => _ => _.With(DotNetCoreBuild.Test, this); + public new Target Test => _ => _.With(this, DotNetCoreBuild.Test); - public new Target Pack => _ => _.With(DotNetCoreBuild.Pack, this); + public new Target Pack => _ => _.With(this, DotNetCoreBuild.Pack); } diff --git a/src/Nuke.DotNetCore/DotNetCoreBuild.cs b/src/Nuke.DotNetCore/DotNetCoreBuild.cs index e375d238..7bd42bf4 100644 --- a/src/Nuke.DotNetCore/DotNetCoreBuild.cs +++ b/src/Nuke.DotNetCore/DotNetCoreBuild.cs @@ -12,6 +12,7 @@ using System.IO; using System.Linq; using System; +using Nuke.Common.Tooling; namespace Rocket.Surgery.Nuke.DotNetCore { @@ -65,36 +66,69 @@ public static ITargetDefinition Build(ITargetDefinition _, IDotNetCoreBuild buil /// /// dotnet test /// - public static ITargetDefinition Test(ITargetDefinition _, IDotNetCoreBuild build) => _ - .Description("Executes all the unit tests.") - .After(build.Build) - .DependentFor(build.Pack) - .DependentFor(build.Generate_Code_Coverage_Reports) - .Triggers(build.Generate_Code_Coverage_Reports) - .OnlyWhenStatic(() => DirectoryExists(build.TestDirectory)) - .OnlyWhenDynamic(() => build.TestDirectory.GlobFiles("**/*.csproj").Count > 0) - .WhenSkipped(DependencyBehavior.Execute) - .Executes(async () => - { - DotNetTest(s => s - .SetProjectFile(build.Solution) - .SetDefaultLoggers(build.LogsDirectory / "test.log") - .SetGitVersionEnvironment(build.GitVersion) - .SetConfiguration("Debug") - .EnableNoRestore() - .SetLogger($"trx") - .SetProperty("CollectCoverage", "true") - // DeterministicSourcePaths being true breaks coverlet! - .SetProperty("DeterministicSourcePaths", "false") - .SetProperty("CoverageDirectory", build.CoverageDirectory) - .SetResultsDirectory(build.TestResultsDirectory) - ); + public static ITargetDefinition Test(ITargetDefinition _, IDotNetCoreBuild build) => Test(true)(_, build); - foreach (var coverage in build.TestResultsDirectory.GlobFiles("**/*.cobertura.xml")) - { - CopyFileToDirectory(coverage, build.CoverageDirectory, FileExistsPolicy.OverwriteIfNewer); - } - }); + /// + /// dotnet test + /// + public static Func Test(bool useDataCollector) => + (ITargetDefinition _, IDotNetCoreBuild build) => _ + .Description("Executes all the unit tests.") + .After(build.Build) + .DependentFor(build.Pack) + .DependentFor(build.Generate_Code_Coverage_Reports) + .Triggers(build.Generate_Code_Coverage_Reports) + .OnlyWhenStatic(() => DirectoryExists(build.TestDirectory)) + .OnlyWhenDynamic(() => build.TestDirectory.GlobFiles("**/*.csproj").Count > 0) + .WhenSkipped(DependencyBehavior.Execute) + .Executes(() => EnsureCleanDirectory(build.TestResultsDirectory)) + .Executes(async () => + { + var runsettings = build.TestDirectory / "coverlet.runsettings"; + if (!FileExists(runsettings)) + { + runsettings = TemporaryDirectory / "default.runsettings"; + if (!FileExists(runsettings)) + { + using var tempFile = File.Open(runsettings, FileMode.CreateNew); + await typeof(DotNetCoreBuild).Assembly + .GetManifestResourceStream("Rocket.Surgery.Nuke.default.runsettings")! + .CopyToAsync(tempFile) + .ConfigureAwait(false); + } + } + + DotNetTest(s => s + .SetProjectFile(build.Solution) + .SetDefaultLoggers(build.LogsDirectory / "test.log") + .SetGitVersionEnvironment(build.GitVersion) + .SetConfiguration("Debug") + .EnableNoRestore() + .SetLogger($"trx") + // DeterministicSourcePaths being true breaks coverlet! + .SetProperty("DeterministicSourcePaths", "false") + .SetResultsDirectory(build.TestResultsDirectory) + .When(useDataCollector, x => x + .SetProperty("CollectCoverage", "true") + .SetProperty("CoverageDirectory", build.CoverageDirectory) + ) + .When(!useDataCollector, x => x + .SetProperty("CollectCoverage", "false") + .SetDataCollector("XPlat Code Coverage") + .SetSettingsFile(runsettings) + ) + ); + + foreach (var coverage in build.TestResultsDirectory.GlobFiles("**/*.cobertura.xml")) + { + CopyDirectoryRecursively( + Path.GetDirectoryName(coverage), + build.CoverageDirectory, + DirectoryExistsPolicy.Merge, + FileExistsPolicy.OverwriteIfNewer + ); + } + }); /// /// dotnet pack diff --git a/src/Nuke.DotNetCore/Rocket.Surgery.Nuke.DotNetCore.csproj b/src/Nuke.DotNetCore/Rocket.Surgery.Nuke.DotNetCore.csproj index a2ac9b3f..fdfd22da 100644 --- a/src/Nuke.DotNetCore/Rocket.Surgery.Nuke.DotNetCore.csproj +++ b/src/Nuke.DotNetCore/Rocket.Surgery.Nuke.DotNetCore.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Nuke.DotNetCore/default.runsettings b/src/Nuke.DotNetCore/default.runsettings new file mode 100644 index 00000000..33d98637 --- /dev/null +++ b/src/Nuke.DotNetCore/default.runsettings @@ -0,0 +1,14 @@ + + + + + + json,lcov,cobertura,opencover + [Bogus*]*,[Autofac*]*,[FakeItEasy*]*,[Moq*]*,[xunit*]*,[Microsoft.*]*,[XunitXml*]*,[coverlet.*]*,[System.*]*,[*]JetBrains.Annotations* + + Obsolete,GeneratedCodeAttribute,CompilerGeneratedAttribute + + + + + \ No newline at end of file diff --git a/src/Nuke.Xamarin/XamarinConfiguration.cs b/src/Nuke.Xamarin/XamarinConfiguration.cs index 4efbe5ae..6c159fcf 100644 --- a/src/Nuke.Xamarin/XamarinConfiguration.cs +++ b/src/Nuke.Xamarin/XamarinConfiguration.cs @@ -11,7 +11,6 @@ namespace Rocket.Surgery /// /// Represents xamarin build configuration. /// - [PublicAPI] [TypeConverter(typeof(TypeConverter))] public class XamarinConfiguration : Enumeration { diff --git a/src/Nuke/LoggingExtensions.cs b/src/Nuke/LoggingExtensions.cs index cab91d1d..ffe9134e 100644 --- a/src/Nuke/LoggingExtensions.cs +++ b/src/Nuke/LoggingExtensions.cs @@ -5,26 +5,37 @@ namespace Rocket.Surgery.Nuke { + /// public static class LoggingExtensions { + /// public static void Log(string log) => Logger.Normal(log); - public static void Debug(string info) { Logger.Trace(info); } + /// + public static void Debug(string info) => Logger.Trace(info); - public static void Debug(string info, params object[] args) { Logger.Trace(info, args); } + /// + public static void Debug(string info, params object[] args) => Logger.Trace(info, args); - public static void Information(string info) { Logger.Info(info); } + /// + public static void Information(string info) => Logger.Info(info); - public static void Information(string info, params object[] args) { Logger.Info(info, args); } + /// + public static void Information(string info, params object[] args) => Logger.Info(info, args); - public static void Warning(string info) { Logger.Warn(info); } + /// + public static void Warning(string info) => Logger.Warn(info); - public static void Warning(string info, params object[] args) { Logger.Warn(info, args); } + /// + public static void Warning(string info, params object[] args) => Logger.Warn(info, args); - public static void Error(string info) { Logger.Error(info); } + /// + public static void Error(string info) => Logger.Error(info); - public static void Error(string info, params object[] args) { Logger.Error(info, args); } + /// + public static void Error(string info, params object[] args) => Logger.Error(info, args); - public static string EnvironmentVariable(string key) => Environment.GetEnvironmentVariable(key); + /// + public static string? EnvironmentVariable(string key) => Environment.GetEnvironmentVariable(key); } } diff --git a/src/Nuke/NuGetVerbosityMappingAttribute.cs b/src/Nuke/NuGetVerbosityMappingAttribute.cs index 68942919..13ff900a 100644 --- a/src/Nuke/NuGetVerbosityMappingAttribute.cs +++ b/src/Nuke/NuGetVerbosityMappingAttribute.cs @@ -12,6 +12,7 @@ namespace Rocket.Surgery.Nuke /// /// Mapping for nuget Verbosity /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] public class NuGetVerbosityMappingAttribute : VerbosityMappingAttribute { /// diff --git a/src/Nuke/PackageIconAttribute.cs b/src/Nuke/PackageIconAttribute.cs index 8be8df51..b83a44c1 100644 --- a/src/Nuke/PackageIconAttribute.cs +++ b/src/Nuke/PackageIconAttribute.cs @@ -17,7 +17,7 @@ public sealed class PackageIconAttribute : DownloadFileAttribute /// /// The Url to download /// The file path to download to, defaults to TemporaryDirectory / packageicon.[ext] - public PackageIconAttribute(string url, string filePath = null) + public PackageIconAttribute(string url, string? filePath = null) : base(url, filePath == null ? ("packageicon" + System.IO.Path.GetExtension(url)) : (AbsolutePath)filePath) { Type = "Package Icon"; diff --git a/src/Nuke/Readme/IMarkdownReferences.cs b/src/Nuke/Readme/IMarkdownReferences.cs index 09a5d4e4..0bf5b078 100644 --- a/src/Nuke/Readme/IMarkdownReferences.cs +++ b/src/Nuke/Readme/IMarkdownReferences.cs @@ -13,6 +13,6 @@ public interface IMarkdownReferences /// /// /// - string AddReference(string name, string value, string altText = null); + string AddReference(string name, string value, string? altText = null); } } diff --git a/src/Nuke/Readme/NugetPackagesSection.cs b/src/Nuke/Readme/NugetPackagesSection.cs index b8907900..0579a2e0 100644 --- a/src/Nuke/Readme/NugetPackagesSection.cs +++ b/src/Nuke/Readme/NugetPackagesSection.cs @@ -50,9 +50,9 @@ public string GetResult(IDictionary config, IMarkdownReferences var dcfg = config; var myget = dcfg["myget"] as IDictionary; - var mygetUrlReference = references.AddReference($"myget-{hash}", MyGetUrl(myget["account"].ToString(), packageName)); - var mygetVersionBadge = references.AddReference($"myget-version-{hash}-badge", MyGetPrereleaseVersionBadge(myget["account"].ToString(), packageName), "MyGet Pre-Release Version"); - var mygetDownloadsBadge = references.AddReference($"myget-downloads-{hash}-badge", MyGetDownloadsBadge(myget["account"].ToString(), packageName), "MyGet Downloads"); + var mygetUrlReference = references.AddReference($"myget-{hash}", MyGetUrl(myget!["account"].ToString()!, packageName)); + var mygetVersionBadge = references.AddReference($"myget-version-{hash}-badge", MyGetPrereleaseVersionBadge(myget["account"].ToString()!, packageName), "MyGet Pre-Release Version"); + var mygetDownloadsBadge = references.AddReference($"myget-downloads-{hash}-badge", MyGetDownloadsBadge(myget["account"].ToString()!, packageName), "MyGet Downloads"); return $"| {packageName} | [!{nugetVersionBadge}!{nugetDownloadsBadge}]{nugetUrlReference} | [!{mygetVersionBadge}!{mygetDownloadsBadge}]{mygetUrlReference} |"; } diff --git a/src/Nuke/Readme/References.cs b/src/Nuke/Readme/References.cs index 12eb0a54..718c5665 100644 --- a/src/Nuke/Readme/References.cs +++ b/src/Nuke/Readme/References.cs @@ -19,7 +19,7 @@ public class References : IMarkdownReferences, IReadmeSection public string ConfigKey { get; } = string.Empty; /// - public string AddReference(string name, string value, string altText = null) + public string AddReference(string name, string value, string? altText = null) { var key = $"[{name}]"; if (string.IsNullOrEmpty(altText)) diff --git a/src/Nuke/RocketBoosterBuild.cs b/src/Nuke/RocketBoosterBuild.cs index 0af2edf6..f19f11d4 100644 --- a/src/Nuke/RocketBoosterBuild.cs +++ b/src/Nuke/RocketBoosterBuild.cs @@ -49,22 +49,22 @@ public abstract class RocketBoosterBuild : NukeBuild, IRocketBoosterBuild /// /// The solution currently being build /// - [Solution] public Solution Solution { get; } + [Solution] public Solution Solution { get; } = null!; /// /// The Git Repository currently being built /// - [GitRepository] public GitRepository GitRepository { get; } + [GitRepository] public GitRepository GitRepository { get; } = null!; /// /// The Git Version information either computed by GitVersion itself, or as defined by environment variables of the format `GITVERSION_*` /// - [ComputedGitVersion] public GitVersion GitVersion { get; } + [ComputedGitVersion] public GitVersion GitVersion { get; } = null!; /// /// The readme updater that ensures that all the badges are in sync. /// - [Readme] public ReadmeUpdater Readme { get; } + [Readme] public ReadmeUpdater Readme { get; } = null!; /// /// The directory where samples will be placed diff --git a/src/Nuke/SyncPackages/PackageSync.cs b/src/Nuke/SyncPackages/PackageSync.cs index f60eb00e..238ecb55 100644 --- a/src/Nuke/SyncPackages/PackageSync.cs +++ b/src/Nuke/SyncPackages/PackageSync.cs @@ -17,7 +17,7 @@ namespace Rocket.Surgery.Nuke.SyncPackages { - public static class PackageSync + internal static class PackageSync { public static async Task AddMissingPackages( AbsolutePath solutionPath, @@ -84,10 +84,10 @@ CancellationToken cancellationToken OrderPackageReferences(itemGroups.ToArray()); RemoveDuplicatePackageReferences(document); - await UpdateXDocument(packagesProps, document, cancellationToken).ConfigureAwait(false); + UpdateXDocument(packagesProps, document); } - public static async Task RemoveExtraPackages( + public static Task RemoveExtraPackages( AbsolutePath solutionPath, AbsolutePath packagesProps, CancellationToken cancellationToken @@ -129,10 +129,11 @@ CancellationToken cancellationToken } } - await UpdateXDocument(packagesProps, document, cancellationToken).ConfigureAwait(false); + UpdateXDocument(packagesProps, document); + return Task.CompletedTask; } - public static async Task MoveVersions( + public static Task MoveVersions( AbsolutePath solutionPath, AbsolutePath packagesProps, CancellationToken cancellationToken) @@ -173,13 +174,14 @@ public static async Task MoveVersions( item.SetAttributeValue("Version", null); } - await UpdateXDocument(path, document, cancellationToken).ConfigureAwait(false); + UpdateXDocument(path, document); } OrderPackageReferences(itemGroups.ToArray()); RemoveDuplicatePackageReferences(packagesDocument); - await UpdateXDocument(packagesProps, packagesDocument, cancellationToken).ConfigureAwait(false); + UpdateXDocument(packagesProps, packagesDocument); + return Task.CompletedTask; } private static IEnumerable GetProjects(AbsolutePath solutionPath) @@ -191,7 +193,7 @@ private static IEnumerable GetProjects(AbsolutePath solutionPat } } - private static async Task UpdateXDocument(string path, XDocument document, CancellationToken cancellationToken) + private static void UpdateXDocument(string path, XDocument document) { using var fileWrite = File.Open(path, FileMode.Truncate); using var writer = XmlWriter.Create(fileWrite, new XmlWriterSettings { OmitXmlDeclaration = true, Async = true, Indent = true }); diff --git a/src/Rocket.Surgery.Nuke.AzureDevOps/AzureDevOpsTasks.cs b/src/Rocket.Surgery.Nuke.AzureDevOps/AzureDevOpsTasks.cs index 6dc7d1c1..7022c59f 100644 --- a/src/Rocket.Surgery.Nuke.AzureDevOps/AzureDevOpsTasks.cs +++ b/src/Rocket.Surgery.Nuke.AzureDevOps/AzureDevOpsTasks.cs @@ -6,10 +6,14 @@ using GlobExpressions; using Nuke.Common; using Nuke.Common.Tools.GitVersion; -using static Rocket.Surgery.Nuke.LoggingExtensions; +using static Nuke.Common.Logger; +using static Nuke.Common.EnvironmentInfo; namespace Rocket.Surgery.Nuke.AzurePipelines { + /// + /// Base pipeline build task + /// public class AzurePipelinesTasks { /// @@ -22,25 +26,25 @@ public class AzurePipelinesTasks .OnlyWhenStatic(IsRunningOnAzurePipelines) .Executes(() => { - Information("AGENT_ID: {0}", EnvironmentVariable("AGENT_ID")); - Information("AGENT_NAME: {0}", EnvironmentVariable("AGENT_NAME")); - Information("AGENT_VERSION: {0}", EnvironmentVariable("AGENT_VERSION")); - Information("AGENT_JOBNAME: {0}", EnvironmentVariable("AGENT_JOBNAME")); - Information("AGENT_JOBSTATUS: {0}", EnvironmentVariable("AGENT_JOBSTATUS")); - Information("AGENT_MACHINE_NAME: {0}", EnvironmentVariable("AGENT_MACHINE_NAME")); - Information("\n"); + Info("AGENT_ID: {0}", GetVariable("AGENT_ID")); + Info("AGENT_NAME: {0}", GetVariable("AGENT_NAME")); + Info("AGENT_VERSION: {0}", GetVariable("AGENT_VERSION")); + Info("AGENT_JOBNAME: {0}", GetVariable("AGENT_JOBNAME")); + Info("AGENT_JOBSTATUS: {0}", GetVariable("AGENT_JOBSTATUS")); + Info("AGENT_MACHINE_NAME: {0}", GetVariable("AGENT_MACHINE_NAME")); + Info("\n"); - Information("BUILD_BUILDID: {0}", EnvironmentVariable("BUILD_BUILDID")); - Information("BUILD_BUILDNUMBER: {0}", EnvironmentVariable("BUILD_BUILDNUMBER")); - Information("BUILD_DEFINITIONNAME: {0}", EnvironmentVariable("BUILD_DEFINITIONNAME")); - Information("BUILD_DEFINITIONVERSION: {0}", EnvironmentVariable("BUILD_DEFINITIONVERSION")); - Information("BUILD_QUEUEDBY: {0}", EnvironmentVariable("BUILD_QUEUEDBY")); - Information("\n"); + Info("BUILD_BUILDID: {0}", GetVariable("BUILD_BUILDID")); + Info("BUILD_BUILDNUMBER: {0}", GetVariable("BUILD_BUILDNUMBER")); + Info("BUILD_DEFINITIONNAME: {0}", GetVariable("BUILD_DEFINITIONNAME")); + Info("BUILD_DEFINITIONVERSION: {0}", GetVariable("BUILD_DEFINITIONVERSION")); + Info("BUILD_QUEUEDBY: {0}", GetVariable("BUILD_QUEUEDBY")); + Info("\n"); - Information("BUILD_SOURCEBRANCHNAME: {0}", EnvironmentVariable("BUILD_SOURCEBRANCHNAME")); - Information("BUILD_SOURCEVERSION: {0}", EnvironmentVariable("BUILD_SOURCEVERSION")); - Information("BUILD_REPOSITORY_NAME: {0}", EnvironmentVariable("BUILD_REPOSITORY_NAME")); - Information("BUILD_REPOSITORY_PROVIDER: {0}", EnvironmentVariable("BUILD_REPOSITORY_PROVIDER")); + Info("BUILD_SOURCEBRANCHNAME: {0}", GetVariable("BUILD_SOURCEBRANCHNAME")); + Info("BUILD_SOURCEVERSION: {0}", GetVariable("BUILD_SOURCEVERSION")); + Info("BUILD_REPOSITORY_NAME: {0}", GetVariable("BUILD_REPOSITORY_NAME")); + Info("BUILD_REPOSITORY_PROVIDER: {0}", GetVariable("BUILD_REPOSITORY_PROVIDER")); }); Target UploadAzurePipelinesArtifacts => _ => _