diff --git a/src/ModularPipelines.Build/ReleaseNotes.md b/src/ModularPipelines.Build/ReleaseNotes.md index e69de29bb2..ec747fa47d 100644 --- a/src/ModularPipelines.Build/ReleaseNotes.md +++ b/src/ModularPipelines.Build/ReleaseNotes.md @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/src/ModularPipelines.GitHub/GitHubRepositoryInfo.cs b/src/ModularPipelines.GitHub/GitHubRepositoryInfo.cs index 519183199a..d024c6e9b8 100644 --- a/src/ModularPipelines.GitHub/GitHubRepositoryInfo.cs +++ b/src/ModularPipelines.GitHub/GitHubRepositoryInfo.cs @@ -2,6 +2,8 @@ using System.Text.RegularExpressions; using Initialization.Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using ModularPipelines.Enums; using ModularPipelines.Git; using ModularPipelines.Git.Options; @@ -13,6 +15,7 @@ namespace ModularPipelines.GitHub; internal record GitHubRepositoryInfo : IGitHubRepositoryInfo, IInitializer { private readonly IServiceProvider _serviceProvider; + private readonly ILogger _logger; public bool IsInitialized { get; private set; } @@ -24,9 +27,10 @@ internal record GitHubRepositoryInfo : IGitHubRepositoryInfo, IInitializer public string? RepositoryName { get; private set; } - public GitHubRepositoryInfo(IServiceProvider serviceProvider) + public GitHubRepositoryInfo(IServiceProvider serviceProvider, ILogger logger) { _serviceProvider = serviceProvider; + _logger = logger; } public async Task InitializeAsync() @@ -38,12 +42,17 @@ public async Task InitializeAsync() await using var scope = _serviceProvider.CreateAsyncScope(); var git = scope.ServiceProvider.GetRequiredService(); - + var options = new GitRemoteOptions { Arguments = ["get-url", "origin"], ThrowOnNonZeroExitCode = false, - CommandLogging = CommandLogging.None, + CommandLogging = scope.ServiceProvider + .GetRequiredService>() + .Value + .MinLevel == LogLevel.Debug + ? CommandLogging.Default + : CommandLogging.None, }; var remote = await git.Commands.Remote(options); @@ -51,6 +60,8 @@ public async Task InitializeAsync() if (string.IsNullOrEmpty(remoteUrl)) { + _logger.LogWarning("Error when detecting GitHub git repository: {Error}", remote.StandardError); + // Will not initialize as git repo is not setup return; } @@ -58,7 +69,7 @@ public async Task InitializeAsync() // Parse owner and repository name from the remote URL var endpoint = "github"; var sshPattern = $@"git@{endpoint}\.com:(?.+)/(?.+)\.git"; - var httpsPattern = $@"https://{endpoint}\.com/(?.+)/(?.+)(\.git)?"; + var httpsPattern = $@"https://(.*@)?{endpoint}\.com/(?.+)/(?.+)(\.git)?"; var match = Regex.Match(remoteUrl, sshPattern); if (!match.Success) diff --git a/src/ModularPipelines/Engine/DependencyPrinter.cs b/src/ModularPipelines/Engine/DependencyPrinter.cs index 955840e6b7..46a0304adb 100644 --- a/src/ModularPipelines/Engine/DependencyPrinter.cs +++ b/src/ModularPipelines/Engine/DependencyPrinter.cs @@ -44,6 +44,11 @@ public void PrintDependencyChains() private void Print(string value) { + if (string.IsNullOrWhiteSpace(value)) + { + return; + } + Console.WriteLine(); _collapsableLogging.StartConsoleLogGroupDirectToConsole("Dependency Chains"); _logger.LogInformation("The following dependency chains have been detected:\r\n{Chain}", value); diff --git a/src/ModularPipelines/Engine/OptionsProvider.cs b/src/ModularPipelines/Engine/OptionsProvider.cs index db1a0a8045..46a9158fb3 100644 --- a/src/ModularPipelines/Engine/OptionsProvider.cs +++ b/src/ModularPipelines/Engine/OptionsProvider.cs @@ -20,11 +20,24 @@ public OptionsProvider(IPipelineServiceContainerWrapper pipelineServiceContainer var types = _pipelineServiceContainerWrapper.ServiceCollection .Select(sd => sd.ServiceType) .Where(t => t.IsGenericType) - .Where(t => t.GetGenericTypeDefinition().IsAssignableTo(typeof(IConfigureOptions<>)) || t.GetGenericTypeDefinition().IsAssignableTo(typeof(IPostConfigureOptions<>))) + .Where(x => x.IsConstructedGenericType) + .Where(t => + { + var genericTypeDefinition = t.GetGenericTypeDefinition(); + + return genericTypeDefinition.IsAssignableTo(typeof(IConfigureOptions<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IPostConfigureOptions<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IOptions<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IOptionsMonitor<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IOptionsSnapshot<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IValidateOptions<>)) + || genericTypeDefinition.IsAssignableTo(typeof(IConfigureNamedOptions<>)); + }) .Select(s => s.GetGenericArguments()[0]) + .Distinct() .ToList(); - foreach (var option in types.Select(t => _serviceProvider.GetService(typeof(IOptions<>).MakeGenericType([t])))) + foreach (var option in types.Select(t => _serviceProvider.GetService(typeof(IOptions<>).MakeGenericType(t)))) { yield return option!.GetType().GetProperty("Value", BindingFlags.Public | BindingFlags.Instance)!.GetValue(option); } diff --git a/test/Directory.Build.props b/test/Directory.Build.props index 6763d8b38a..4d002ab1fd 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -9,6 +9,6 @@ - + - \ No newline at end of file + diff --git a/test/ModularPipelines.TestHelpers/TestBase.cs b/test/ModularPipelines.TestHelpers/TestBase.cs index 591a81cd89..bd47396f42 100644 --- a/test/ModularPipelines.TestHelpers/TestBase.cs +++ b/test/ModularPipelines.TestHelpers/TestBase.cs @@ -24,10 +24,12 @@ private class DummyModule : Module } } - public async Task RunModule() + public Task RunModule() where T : ModuleBase => RunModule(new TestHostSettings()); + + public async Task RunModule(TestHostSettings testHostSettings) where T : ModuleBase { - var host = await TestPipelineHostBuilder.Create() + var host = await TestPipelineHostBuilder.Create(testHostSettings) .AddModule() .BuildHostAsync(); diff --git a/test/ModularPipelines.TestHelpers/TestHostSettings.cs b/test/ModularPipelines.TestHelpers/TestHostSettings.cs new file mode 100644 index 0000000000..2b33265f67 --- /dev/null +++ b/test/ModularPipelines.TestHelpers/TestHostSettings.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.Logging; +using ModularPipelines.Enums; + +namespace ModularPipelines.TestHelpers; + +public record TestHostSettings +{ + public CommandLogging CommandLogging { get; init; } = CommandLogging.Input | CommandLogging.Error; + public LogLevel LogLevel { get; init; } = LogLevel.Warning; + public bool ClearLogProviders { get; init; } = true; +} \ No newline at end of file diff --git a/test/ModularPipelines.TestHelpers/TestPipelineHostBuilder.cs b/test/ModularPipelines.TestHelpers/TestPipelineHostBuilder.cs index 17e386f48a..b38420e0ed 100644 --- a/test/ModularPipelines.TestHelpers/TestPipelineHostBuilder.cs +++ b/test/ModularPipelines.TestHelpers/TestPipelineHostBuilder.cs @@ -10,20 +10,26 @@ namespace ModularPipelines.TestHelpers; public static class TestPipelineHostBuilder { - public static PipelineHostBuilder Create() + public static PipelineHostBuilder Create() => Create(new TestHostSettings()); + + public static PipelineHostBuilder Create(TestHostSettings testHostSettings) { return new PipelineHostBuilder() - .SetLogLevel(LogLevel.Warning) + .SetLogLevel(testHostSettings.LogLevel) .ConfigureServices((_, collection) => { collection.AddSingleton(new ArmClient(new DefaultAzureCredential())); collection.Configure(opt => { - opt.DefaultCommandLogging = CommandLogging.Input | CommandLogging.Error; + opt.DefaultCommandLogging = testHostSettings.CommandLogging; opt.ShowProgressInConsole = false; opt.PrintResults = false; }); - collection.AddLogging(builder => builder.ClearProviders()); + + if(testHostSettings.ClearLogProviders) + { + collection.AddLogging(builder => builder.ClearProviders()); + } }); } } \ No newline at end of file diff --git a/test/ModularPipelines.UnitTests/Attributes/EnumValueAttributeTests.cs b/test/ModularPipelines.UnitTests/Attributes/EnumValueAttributeTests.cs index feb4f9d393..7124188dd7 100644 --- a/test/ModularPipelines.UnitTests/Attributes/EnumValueAttributeTests.cs +++ b/test/ModularPipelines.UnitTests/Attributes/EnumValueAttributeTests.cs @@ -1,6 +1,5 @@ -using ModularPipelines.Attributes; +using ModularPipelines.Attributes; using ModularPipelines.Helpers; -using TUnit.Assertions.Extensions; namespace ModularPipelines.UnitTests.Attributes; diff --git a/test/ModularPipelines.UnitTests/Attributes/LinuxOnlyTestAttribute.cs b/test/ModularPipelines.UnitTests/Attributes/LinuxOnlyTestAttribute.cs index 7677706ab5..b66ae78393 100644 --- a/test/ModularPipelines.UnitTests/Attributes/LinuxOnlyTestAttribute.cs +++ b/test/ModularPipelines.UnitTests/Attributes/LinuxOnlyTestAttribute.cs @@ -1,19 +1,9 @@ -using TUnit.Core.Exceptions; -using TUnit.Core.Interfaces; - namespace ModularPipelines.UnitTests.Attributes; -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] -public class LinuxOnlyTestAttribute : Attribute, IApplicableTestAttribute +public class LinuxOnlyTestAttribute() : SkipAttribute("Linux only test") { - /// - public Task Apply(TestContext testContext) + public override Task ShouldSkip(TestContext testContext) { - if (!OperatingSystem.IsLinux()) - { - throw new SkipTestException("Linux only test"); - } - - return Task.CompletedTask; + return Task.FromResult(!OperatingSystem.IsLinux()); } } \ No newline at end of file diff --git a/test/ModularPipelines.UnitTests/Attributes/WindowsOnlyTestAttribute.cs b/test/ModularPipelines.UnitTests/Attributes/WindowsOnlyTestAttribute.cs index 2bdd825a43..a67fe9b112 100644 --- a/test/ModularPipelines.UnitTests/Attributes/WindowsOnlyTestAttribute.cs +++ b/test/ModularPipelines.UnitTests/Attributes/WindowsOnlyTestAttribute.cs @@ -1,19 +1,9 @@ -using TUnit.Core.Exceptions; -using TUnit.Core.Interfaces; - namespace ModularPipelines.UnitTests.Attributes; -[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] -public class WindowsOnlyTestAttribute : Attribute, IApplicableTestAttribute +public class WindowsOnlyTestAttribute() : SkipAttribute("Windows only test") { - /// - public Task Apply(TestContext testContext) + public override Task ShouldSkip(TestContext testContext) { - if (!OperatingSystem.IsWindows()) - { - throw new SkipTestException("Windows only test"); - } - - return Task.CompletedTask; + return Task.FromResult(!OperatingSystem.IsWindows()); } } \ No newline at end of file diff --git a/test/ModularPipelines.UnitTests/Helpers/GitHubRepositoryInfoTests.cs b/test/ModularPipelines.UnitTests/Helpers/GitHubRepositoryInfoTests.cs index c311696a62..13e714aefa 100644 --- a/test/ModularPipelines.UnitTests/Helpers/GitHubRepositoryInfoTests.cs +++ b/test/ModularPipelines.UnitTests/Helpers/GitHubRepositoryInfoTests.cs @@ -1,4 +1,6 @@ -using ModularPipelines.Context; +using Microsoft.Extensions.Logging; +using ModularPipelines.Context; +using ModularPipelines.Enums; using ModularPipelines.GitHub; using ModularPipelines.GitHub.Extensions; using ModularPipelines.Modules; @@ -21,19 +23,30 @@ public class GitRepoModule : Module [Test] public async Task GitHub_Repository_Information_Is_Populated() { - var gitRepoModule = await RunModule(); + var gitRepoModule = await RunModule(new TestHostSettings + { + CommandLogging = CommandLogging.Default, + LogLevel = LogLevel.Debug, + ClearLogProviders = false + }); var gitHubRepositoryInfo = gitRepoModule.Result.Value!; - await Assert.That(gitHubRepositoryInfo.IsGitHub).Is.True(); - await Assert.That(gitHubRepositoryInfo.IsInitialized).Is.True(); - await Assert.That(gitHubRepositoryInfo.RepositoryName).Is.Not.Null() - .And.Is.Not.Empty(); - await Assert.That(gitHubRepositoryInfo.Owner).Is.Not.Null() - .And.Is.Not.Empty(); - await Assert.That(gitHubRepositoryInfo.Endpoint).Is.Not.Null() - .And.Is.Not.Empty(); - await Assert.That(gitHubRepositoryInfo.Identifier).Is.Not.Null() - .And.Is.Not.Empty(); + Console.WriteLine($"GitHub Repository Info is: {gitHubRepositoryInfo}"); + + await using (Assert.Multiple()) + { + await Assert.That(gitHubRepositoryInfo).Is.Not.Null(); + await Assert.That(gitHubRepositoryInfo.IsInitialized).Is.True(); + await Assert.That(gitHubRepositoryInfo.IsGitHub).Is.True(); + await Assert.That(gitHubRepositoryInfo.RepositoryName).Is.Not.Null() + .And.Is.Not.Empty(); + await Assert.That(gitHubRepositoryInfo.Owner).Is.Not.Null() + .And.Is.Not.Empty(); + await Assert.That(gitHubRepositoryInfo.Endpoint).Is.Not.Null() + .And.Is.Not.Empty(); + await Assert.That(gitHubRepositoryInfo.Identifier).Is.Not.Null() + .And.Is.Not.Empty(); + } } } \ No newline at end of file