diff --git a/src/RepoM.Api/Git/DefaultRepositoryWriter.cs b/src/RepoM.Api/Git/DefaultRepositoryWriter.cs index 333e0685..20524ab6 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryWriter.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryWriter.cs @@ -4,6 +4,7 @@ namespace RepoM.Api.Git; using System.Linq; using LibGit2Sharp; using RepoM.Api.Common; +using IRepository = RepoM.Core.Plugin.Repository.IRepository; public class DefaultRepositoryWriter : IRepositoryWriter { @@ -16,7 +17,7 @@ public DefaultRepositoryWriter(IGitCommander gitCommander, IAppSettingsService a _appSettingsService = appSettingsService ?? throw new ArgumentNullException(nameof(appSettingsService)); } - public bool Checkout(Repository repository, string branchName) + public bool Checkout(IRepository repository, string branchName) { using var repo = new LibGit2Sharp.Repository(repository.Path); Branch branch; @@ -45,33 +46,30 @@ public bool Checkout(Repository repository, string branchName) return branch.FriendlyName == branchName; } - public void Fetch(Repository repository) + public void Fetch(IRepository repository) { var arguments = _appSettingsService.PruneOnFetch - ? new string[] - { - "fetch", "--all", "--prune", - } - : new string[] { "fetch", "--all", }; + ? new[] { "fetch", "--all", "--prune", } + : new[] { "fetch", "--all", }; _gitCommander.Command(repository, arguments); } - public void Pull(Repository repository) + public void Pull(IRepository repository) { var arguments = _appSettingsService.PruneOnFetch - ? new string[] { "pull", "--prune", } - : new string[] { "pull", }; + ? new[] { "pull", "--prune", } + : new[] { "pull", }; _gitCommander.Command(repository, arguments); } - public void Push(Repository repository) + public void Push(IRepository repository) { _gitCommander.Command(repository, "push"); } - private void SetUpstream(Repository repository, string localBranchName, string upstreamBranchName) + private void SetUpstream(IRepository repository, string localBranchName, string upstreamBranchName) { _gitCommander.Command(repository, "branch", $"--set-upstream-to={upstreamBranchName}", localBranchName); } diff --git a/src/RepoM.Api/Git/IGitCommander.cs b/src/RepoM.Api/Git/IGitCommander.cs index 0577615f..a394bbff 100644 --- a/src/RepoM.Api/Git/IGitCommander.cs +++ b/src/RepoM.Api/Git/IGitCommander.cs @@ -1,14 +1,13 @@ namespace RepoM.Api.Git; using System; +using RepoM.Core.Plugin.Repository; public interface IGitCommander { - string Command(Repository repository, params string[] command); + string Command(IRepository repository, params string[] command); - string CommandOneline(Repository repository, params string[] command); + void CommandNoisy(IRepository repository, params string[] command); - void CommandNoisy(Repository repository, params string[] command); - - void CommandOutputPipe(Repository repository, Action handleOutput, params string[] command); + void CommandOutputPipe(IRepository repository, Action handleOutput, params string[] command); } \ No newline at end of file diff --git a/src/RepoM.Api/Git/IRepositoryActionProvider.cs b/src/RepoM.Api/Git/IRepositoryActionProvider.cs index 8b5d6ce6..2246026c 100644 --- a/src/RepoM.Api/Git/IRepositoryActionProvider.cs +++ b/src/RepoM.Api/Git/IRepositoryActionProvider.cs @@ -1,6 +1,10 @@ namespace RepoM.Api.Git; +using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using Microsoft.Extensions.Logging; public interface IRepositoryActionProvider { @@ -9,4 +13,94 @@ public interface IRepositoryActionProvider RepositoryActionBase? GetSecondaryAction(Repository repository); IEnumerable GetContextMenuActions(Repository repository); +} + +public sealed class LoggingRepositoryActionProviderDecorator : IRepositoryActionProvider +{ + private readonly IRepositoryActionProvider _provider; + + public LoggingRepositoryActionProviderDecorator(IRepositoryActionProvider provider, ILogger logger) + { + _provider = provider ?? throw new ArgumentNullException(nameof(provider)); + + _ = logger ?? throw new ArgumentNullException(nameof(logger)); + + if (logger.IsEnabled(LogLevel.Debug)) + { + logger.LogInformation("IRepositoryActionProvider logging enabled."); + _provider = new LoggingDecorator(provider, logger); + } + else + { + logger.LogInformation("IRepositoryActionProvider logging disabled."); + } + } + + public RepositoryActionBase? GetPrimaryAction(Repository repository) + { + return _provider.GetPrimaryAction(repository); + } + + public RepositoryActionBase? GetSecondaryAction(Repository repository) + { + return _provider.GetSecondaryAction(repository); + } + + public IEnumerable GetContextMenuActions(Repository repository) + { + return _provider.GetContextMenuActions(repository); + } + + private sealed class LoggingDecorator : IRepositoryActionProvider + { + private readonly IRepositoryActionProvider _provider; + private readonly ILogger _logger; + + public LoggingDecorator(IRepositoryActionProvider provider, ILogger logger) + { + _provider = provider ?? throw new ArgumentNullException(nameof(provider)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public RepositoryActionBase? GetPrimaryAction(Repository repository) + { + return _provider.GetPrimaryAction(repository); + } + + public RepositoryActionBase? GetSecondaryAction(Repository repository) + { + return _provider.GetSecondaryAction(repository); + } + + public IEnumerable GetContextMenuActions(Repository repository) + { + using IDisposable _ = Measure(repository); + return _provider.GetContextMenuActions(repository).ToArray(); + } + + private IDisposable Measure(Repository repository) + { + return new MeasureLog(_logger, repository); + } + + private sealed class MeasureLog : IDisposable + { + private readonly Stopwatch _sw; + private readonly ILogger _logger; + private readonly Repository _repo; + + public MeasureLog(ILogger logger, Repository repo) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _repo = repo ?? throw new ArgumentNullException(nameof(repo)); + _sw = Stopwatch.StartNew(); + } + + public void Dispose() + { + _sw.Stop(); + _logger.LogDebug("GetContextMenuActions {repository} took {time}", _repo.Name, _sw.Elapsed); + } + } + } } \ No newline at end of file diff --git a/src/RepoM.Api/Git/IRepositoryWriter.cs b/src/RepoM.Api/Git/IRepositoryWriter.cs index e44f4aab..11e05399 100644 --- a/src/RepoM.Api/Git/IRepositoryWriter.cs +++ b/src/RepoM.Api/Git/IRepositoryWriter.cs @@ -1,12 +1,14 @@ namespace RepoM.Api.Git; +using RepoM.Core.Plugin.Repository; + public interface IRepositoryWriter { - bool Checkout(Repository repository, string branchName); + bool Checkout(IRepository repository, string branchName); - void Fetch(Repository repository); + void Fetch(IRepository repository); - void Pull(Repository repository); + void Pull(IRepository repository); - void Push(Repository repository); + void Push(IRepository repository); } \ No newline at end of file diff --git a/src/RepoM.Api/Git/ProcessExecution/ProcessExecutingGitCommander.cs b/src/RepoM.Api/Git/ProcessExecution/ProcessExecutingGitCommander.cs index 104e11fa..73647238 100644 --- a/src/RepoM.Api/Git/ProcessExecution/ProcessExecutingGitCommander.cs +++ b/src/RepoM.Api/Git/ProcessExecution/ProcessExecutingGitCommander.cs @@ -7,9 +7,14 @@ namespace RepoM.Api.Git.ProcessExecution; using System.Text; using System.Text.RegularExpressions; using System.Threading; +using Microsoft.Extensions.Logging; +using RepoM.Core.Plugin.Repository; public partial class ProcessExecutingGitCommander : IGitCommander { + private readonly ILogger _logger; + private const string GIT_EXE = "git"; + /// /// Starting with version 1.7.10, Git uses UTF-8. /// Use this encoding for Git input and output. @@ -18,20 +23,15 @@ public partial class ProcessExecutingGitCommander : IGitCommander private static readonly Regex _validCommandName = ValidCommandNameRegex(); - /// - /// Runs the given git command, and returns the contents of its STDOUT. - /// - public string Command(Repository repository, params string[] command) + public ProcessExecutingGitCommander(ILogger logger) { - var retVal = string.Empty; - CommandOutputPipe(repository, output => retVal = output, command); - return retVal; + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// - /// Runs the given git command, and returns the first line of its STDOUT. + /// Runs the given git command, and returns the contents of its STDOUT. /// - public string CommandOneline(Repository repository, params string[] command) + public string Command(IRepository repository, params string[] command) { var retVal = string.Empty; CommandOutputPipe(repository, output => retVal = output, command); @@ -41,7 +41,7 @@ public string CommandOneline(Repository repository, params string[] command) /// /// Runs the given git command, and passes STDOUT through to the current process's STDOUT. /// - public void CommandNoisy(Repository repository, params string[] command) + public void CommandNoisy(IRepository repository, params string[] command) { CommandOutputPipe(repository, output => Trace.TraceInformation(output), command); } @@ -49,7 +49,7 @@ public void CommandNoisy(Repository repository, params string[] command) /// /// Runs the given git command, and redirects STDOUT to the provided action. /// - public void CommandOutputPipe(Repository repository, Action handleOutput, params string[] command) + public void CommandOutputPipe(IRepository repository, Action handleOutput, params string[] command) { Time(command, () => { @@ -81,7 +81,7 @@ public static StreamWriter NewStreamWithEncoding(StreamWriter stream, Encoding e return new StreamWriter(stream.BaseStream, encoding); } - private static void Time(string[] command, Action action) + private void Time(string[] command, Action action) { DateTime start = DateTime.Now; @@ -92,7 +92,7 @@ private static void Time(string[] command, Action action) finally { DateTime end = DateTime.Now; - Trace.WriteLine($"[{end - start}] {string.Join(" ", command)}", "git command time"); + _logger.LogTrace("git command '{command}' time took {duration}", string.Join(" ", command), end - start); } } @@ -108,13 +108,13 @@ private static void RedirectStderr(ProcessStartInfo startInfo) startInfo.StandardErrorEncoding = _encoding; } - private static string Start(Repository repository, string[] command, Action initialize) + private static string Start(IRepository repository, string[] command, Action initialize) { var timeout = (int)TimeSpan.FromSeconds(10).TotalMilliseconds; var psi = new ProcessStartInfo { - FileName = "git", + FileName = GIT_EXE, WorkingDirectory = repository.Path, }; diff --git a/src/RepoM.Api/Git/RepositoryViewModel.cs b/src/RepoM.Api/Git/RepositoryViewModel.cs index 358135e6..f9dba708 100644 --- a/src/RepoM.Api/Git/RepositoryViewModel.cs +++ b/src/RepoM.Api/Git/RepositoryViewModel.cs @@ -21,6 +21,7 @@ public RepositoryViewModel(Repository repository, IRepositoryMonitor monitor) _monitor = monitor ?? throw new ArgumentNullException(nameof(monitor)); Repository = repository ?? throw new ArgumentNullException(nameof(repository)); UpdateStampUtc = DateTime.UtcNow; + Tags = Repository.Tags.Select(tag => new TagViewModel(tag)).ToArray(); } public override bool Equals(object? obj) @@ -88,7 +89,7 @@ private void EnsureStatusCache() public bool HasUnpushedChanges => Repository.HasUnpushedChanges; - public TagViewModel[] Tags => Repository.Tags.Select(x => new TagViewModel(x)).ToArray() ?? Array.Empty(); + public TagViewModel[] Tags { get; } public override int GetHashCode() { diff --git a/src/RepoM.Api/IO/ExpressionEvaluator/RepositoryExpressionEvaluator.cs b/src/RepoM.Api/IO/ExpressionEvaluator/RepositoryExpressionEvaluator.cs index c8ed429c..03d3c8a8 100644 --- a/src/RepoM.Api/IO/ExpressionEvaluator/RepositoryExpressionEvaluator.cs +++ b/src/RepoM.Api/IO/ExpressionEvaluator/RepositoryExpressionEvaluator.cs @@ -36,7 +36,7 @@ public bool EvaluateBooleanExpression(string? value, IRepository? repository) try { - object? result = _expressionExecutor.Execute(RepositoryContext.Create(repository), value!); + var result = _expressionExecutor.Execute(RepositoryContext.Create(repository), value); if (result is null) { @@ -77,13 +77,7 @@ public string EvaluateStringExpression(string value, IRepository? repository) { try { - object? result = _expressionExecutor.Execute(RepositoryContext.Create(repository), value); - - // seems to be possible - if (result == null) - { - return string.Empty; - } + var result = _expressionExecutor.Execute(RepositoryContext.Create(repository), value); if (result is string s) { diff --git a/src/RepoM.Api/IO/Methods/IsNullMethod.cs b/src/RepoM.Api/IO/Methods/IsNullMethod.cs new file mode 100644 index 00000000..6529e021 --- /dev/null +++ b/src/RepoM.Api/IO/Methods/IsNullMethod.cs @@ -0,0 +1,19 @@ +namespace RepoM.Api.IO.Methods; + +using System; +using ExpressionStringEvaluator.Methods; +using JetBrains.Annotations; + +[UsedImplicitly] +public class IsNullMethod : IMethod +{ + public bool CanHandle(string method) + { + return "IsNull".Equals(method, StringComparison.CurrentCultureIgnoreCase); + } + + public object? Handle(string method, params object?[] args) + { + return args == null || Array.Exists(args, arg => arg is null); + } +} \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1Mapper.cs index 1fa6a7e1..c9e0d2a1 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1Mapper.cs @@ -28,14 +28,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionAssociateFileV1; } - public bool CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionAssociateFileV1, repository.First()); + return Map(action as RepositoryActionAssociateFileV1, repository); } private IEnumerable Map(RepositoryActionAssociateFileV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowseRepositoryV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowseRepositoryV1Mapper.cs index 64b11546..55b3ae4e 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowseRepositoryV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowseRepositoryV1Mapper.cs @@ -26,14 +26,9 @@ bool IActionToRepositoryActionMapper.CanMap(Data.RepositoryAction action) return action is RepositoryActionBrowseRepositoryV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionBrowseRepositoryV1, repository.First()); + return Map(action as RepositoryActionBrowseRepositoryV1, repository); } private IEnumerable Map(RepositoryActionBrowseRepositoryV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs index 2e8b02d5..ebc22001 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs @@ -26,14 +26,9 @@ bool IActionToRepositoryActionMapper.CanMap(Data.RepositoryAction action) return action is RepositoryActionBrowserV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionBrowserV1, repository.First()); + return Map(action as RepositoryActionBrowserV1, repository); } private IEnumerable Map(RepositoryActionBrowserV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionCommandV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionCommandV1Mapper.cs index 9bd68a08..d64ce081 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionCommandV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionCommandV1Mapper.cs @@ -26,14 +26,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionCommandV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionCommandV1, repository.First()); + return Map(action as RepositoryActionCommandV1, repository); } private IEnumerable Map(RepositoryActionCommandV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionExecutableV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionExecutableV1Mapper.cs index 75275fad..bbce34b8 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionExecutableV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionExecutableV1Mapper.cs @@ -29,14 +29,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionExecutableV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionExecutableV1, repository.First()); + return Map(action as RepositoryActionExecutableV1, repository); } private IEnumerable Map(RepositoryActionExecutableV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionFolderV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionFolderV1Mapper.cs index 9b98fa16..2b0929ca 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionFolderV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionFolderV1Mapper.cs @@ -25,14 +25,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionFolderV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionFolderV1, repository.First(), actionMapperComposition); + return Map(action as RepositoryActionFolderV1, repository, actionMapperComposition); } private IEnumerable Map(RepositoryActionFolderV1? action, Repository repository, ActionMapperComposition actionMapperComposition) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionForEachV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionForEachV1Mapper.cs index 8f93f97e..dbb02bca 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionForEachV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionForEachV1Mapper.cs @@ -26,14 +26,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionForEachV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionForEachV1, repository.First(), actionMapperComposition); + return Map(action as RepositoryActionForEachV1, repository, actionMapperComposition); } private object? Evaluate(object? input, IRepository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1Mapper.cs index 0861fc9e..c62c226a 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1Mapper.cs @@ -28,14 +28,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionGitCheckoutV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionGitCheckoutV1, repository.First()); + return Map(action as RepositoryActionGitCheckoutV1, repository); } private IEnumerable Map(RepositoryActionGitCheckoutV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitFetchV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitFetchV1Mapper.cs index 4a862a90..040c78d2 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitFetchV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitFetchV1Mapper.cs @@ -7,6 +7,7 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; using RepoM.Core.Plugin.Expressions; +using RepoM.Core.Plugin.RepositoryActions.Actions; using RepositoryAction = RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction; public class ActionGitFetchV1Mapper : IActionToRepositoryActionMapper @@ -27,23 +28,32 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionGitFetchV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } + if (action == null) + { + yield break; + } - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repositories, ActionMapperComposition actionMapperComposition) - { - Repository[] repos = repositories as Repository[] ?? repositories.ToArray(); - if (Array.Exists(repos, r => !_expressionEvaluator.EvaluateBooleanExpression(action.Active, r))) + if (!_expressionEvaluator.EvaluateBooleanExpression(action.Active, repository)) { yield break; } - yield return MultipleRepositoryActionHelper.CreateActionForMultipleRepositories( - _translationService.Translate("Fetch"), - repos, - _repositoryWriter.Fetch, - executionCausesSynchronizing: true); + yield return new Git.RepositoryAction(_translationService.Translate("Fetch"), repository) + { + Action = new DelegateAction((_, _) => + { + try + { + _repositoryWriter.Fetch(repository); + } + catch + { + // nothing to see here + } + }), + ExecutionCausesSynchronizing = true, + }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPullV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPullV1Mapper.cs index d3092eca..196c8215 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPullV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPullV1Mapper.cs @@ -2,11 +2,11 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using System; using System.Collections.Generic; -using System.Linq; using RepoM.Api.Common; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; using RepoM.Core.Plugin.Expressions; +using RepoM.Core.Plugin.RepositoryActions.Actions; using RepositoryAction = RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction; public class ActionGitPullV1Mapper : IActionToRepositoryActionMapper @@ -27,23 +27,32 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionGitPullV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } + if (action == null) + { + yield break; + } - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repositories, ActionMapperComposition actionMapperComposition) - { - Repository[] repos = repositories as Repository[] ?? repositories.ToArray(); - if (Array.Exists(repos, r => !_expressionEvaluator.EvaluateBooleanExpression(action.Active, r))) + if (!_expressionEvaluator.EvaluateBooleanExpression(action.Active, repository)) { yield break; } - yield return MultipleRepositoryActionHelper.CreateActionForMultipleRepositories( - _translationService.Translate("Pull"), - repos, - _repositoryWriter.Pull, - executionCausesSynchronizing: true); + yield return new Git.RepositoryAction(_translationService.Translate("Pull"), repository) + { + Action = new DelegateAction((_, _) => + { + try + { + _repositoryWriter.Pull(repository); + } + catch + { + // nothing to see here + } + }), + ExecutionCausesSynchronizing = true, + }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPushV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPushV1Mapper.cs index cd935750..0ea5370c 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPushV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitPushV1Mapper.cs @@ -2,11 +2,11 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using System; using System.Collections.Generic; -using System.Linq; using RepoM.Api.Common; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; using RepoM.Core.Plugin.Expressions; +using RepoM.Core.Plugin.RepositoryActions.Actions; using RepositoryAction = RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction; public class ActionGitPushV1Mapper : IActionToRepositoryActionMapper @@ -27,23 +27,32 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionGitPushV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } + if (action == null) + { + yield break; + } - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repositories, ActionMapperComposition actionMapperComposition) - { - Repository[] repos = repositories as Repository[] ?? repositories.ToArray(); - if (Array.Exists(repos, r => !_expressionEvaluator.EvaluateBooleanExpression(action.Active, r))) + if (!_expressionEvaluator.EvaluateBooleanExpression(action.Active, repository)) { yield break; } - yield return MultipleRepositoryActionHelper.CreateActionForMultipleRepositories( - _translationService.Translate("Push"), - repos, - _repositoryWriter.Push, - executionCausesSynchronizing: true); + yield return new Git.RepositoryAction(_translationService.Translate("Push"), repository) + { + Action = new DelegateAction((_, _) => + { + try + { + _repositoryWriter.Push(repository); + } + catch + { + // nothing to see here + } + }), + ExecutionCausesSynchronizing = true, + }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionIgnoreRepositoriesV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionIgnoreRepositoriesV1Mapper.cs index a1305c8e..72f33df2 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionIgnoreRepositoriesV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionIgnoreRepositoriesV1Mapper.cs @@ -2,11 +2,11 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using System; using System.Collections.Generic; -using System.Linq; using RepoM.Api.Common; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; using RepoM.Core.Plugin.Expressions; +using RepoM.Core.Plugin.RepositoryActions.Actions; public class ActionIgnoreRepositoriesV1Mapper : IActionToRepositoryActionMapper { @@ -29,22 +29,32 @@ bool IActionToRepositoryActionMapper.CanMap(Data.RepositoryAction action) return action is RepositoryActionIgnoreRepositoryV1; } - bool IActionToRepositoryActionMapper.CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } + if (action == null) + { + yield break; + } - IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, IEnumerable repositories, ActionMapperComposition actionMapperComposition) - { - Repository[] repos = repositories as Repository[] ?? repositories.ToArray(); - if (Array.Exists(repos, r => !_expressionEvaluator.EvaluateBooleanExpression(action.Active, r))) + if (!_expressionEvaluator.EvaluateBooleanExpression(action.Active, repository)) { yield break; } - - yield return MultipleRepositoryActionHelper.CreateActionForMultipleRepositories( - _translationService.Translate("Ignore"), - repos, - repository => _repositoryMonitor.IgnoreByPath(repository.Path)); + + yield return new RepositoryAction(_translationService.Translate("Ignore"), repository) + { + Action = new DelegateAction((_, _) => + { + try + { + _repositoryMonitor.IgnoreByPath(repository.Path); + } + catch + { + // nothing to see here + } + }), + ExecutionCausesSynchronizing = true, + }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionJustTextV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionJustTextV1Mapper.cs index f3b0846c..62e1aacc 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionJustTextV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionJustTextV1Mapper.cs @@ -26,14 +26,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionJustTextV1; } - public bool CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionJustTextV1, repository.First()); + return Map(action as RepositoryActionJustTextV1, repository); } private IEnumerable Map(RepositoryActionJustTextV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionMapperComposition.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionMapperComposition.cs index 9690013c..4b08ab5d 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionMapperComposition.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionMapperComposition.cs @@ -18,26 +18,24 @@ public class ActionMapperComposition public ActionMapperComposition(IEnumerable deserializers, IRepositoryExpressionEvaluator repoExpressionEvaluator) { _repoExpressionEvaluator = repoExpressionEvaluator ?? throw new ArgumentNullException(nameof(repoExpressionEvaluator)); - _deserializers = deserializers.ToArray() ?? throw new ArgumentNullException(nameof(deserializers)); + _deserializers = deserializers.ToArray(); } - public RepositoryActionBase[] Map(Data.RepositoryAction action, params Repository[] repositories) + public RepositoryActionBase[] Map(Data.RepositoryAction action, Repository repository) { - Repository? singleRepository = repositories.Length <= 1 ? repositories.SingleOrDefault() : null; - - List EvaluateVariables(IEnumerable vars) + if (repository == null) { - if (singleRepository == null) - { - return new List(0); - } + throw new ArgumentNullException(nameof(repository)); + } + List EvaluateVariables(IEnumerable vars) + { return vars - .Where(v => IsEnabled(v.Enabled, true, singleRepository)) + .Where(v => IsEnabled(v.Enabled, true, repository)) .Select(v => new EvaluatedVariable { Name = v.Name, - Value = Evaluate(v.Value, singleRepository), + Value = Evaluate(v.Value, repository), }) .ToList(); } @@ -46,7 +44,7 @@ List EvaluateVariables(IEnumerable vars) using IDisposable disposable = RepoMVariableProviderStore.Push(EvaluateVariables(action.Variables)); - IEnumerable result = deserializer?.Map(action, repositories, this) ?? Enumerable.Empty(); + IEnumerable result = deserializer?.Map(action, repository, this) ?? Enumerable.Empty(); return result.ToArray(); } diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionPinRepositoryV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionPinRepositoryV1Mapper.cs index c2c1c349..3645009e 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionPinRepositoryV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionPinRepositoryV1Mapper.cs @@ -2,7 +2,6 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using System; using System.Collections.Generic; -using System.Linq; using RepoM.Api.Common; using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; @@ -31,23 +30,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionPinRepositoryV1; } - public bool CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - foreach (Repository r in repository) - { - RepositoryActionBase[] result = Map(action as RepositoryActionPinRepositoryV1, r).ToArray(); - if (result.Any()) - { - return result; - } - } - - return Array.Empty(); + return Map(action as RepositoryActionPinRepositoryV1, repository); } private IEnumerable Map(RepositoryActionPinRepositoryV1? action, Repository repository) @@ -76,12 +61,12 @@ private IEnumerable Map(RepositoryActionPinRepositoryV1? a if (string.IsNullOrWhiteSpace(name)) { name = action.Mode switch - { - RepositoryActionPinRepositoryV1.PinMode.Toggle => currentlyPinned ? UNPIN : PIN, - RepositoryActionPinRepositoryV1.PinMode.Pin => PIN, - RepositoryActionPinRepositoryV1.PinMode.UnPin => UNPIN, - _ => throw new ArgumentOutOfRangeException("Unexpected value for mode."), - }; + { + RepositoryActionPinRepositoryV1.PinMode.Toggle => currentlyPinned ? UNPIN : PIN, + RepositoryActionPinRepositoryV1.PinMode.Pin => PIN, + RepositoryActionPinRepositoryV1.PinMode.UnPin => UNPIN, + _ => throw new NotImplementedException(), + }; } Git.RepositoryAction CreateAction(string name, Repository repository, bool newPinnedValue) @@ -97,7 +82,7 @@ Git.RepositoryAction CreateAction(string name, Repository repository, bool newPi RepositoryActionPinRepositoryV1.PinMode.Toggle => CreateAction(name, repository, !currentlyPinned), RepositoryActionPinRepositoryV1.PinMode.Pin => CreateAction(name, repository, true), RepositoryActionPinRepositoryV1.PinMode.UnPin => CreateAction(name, repository, false), - _ => throw new ArgumentOutOfRangeException(nameof(action.Mode), action.Mode, "Not expected"), + _ => throw new NotImplementedException(), }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionSeparatorV1Mapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionSeparatorV1Mapper.cs index 591f1c30..85b63f54 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionSeparatorV1Mapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionSeparatorV1Mapper.cs @@ -22,23 +22,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionSeparatorV1; } - public bool CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return true; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - foreach (Repository r in repository) - { - RepositoryActionBase[] result = Map(action as RepositoryActionSeparatorV1, r).ToArray(); - if (result.Any()) - { - return result; - } - } - - return Array.Empty(); + return Map(action as RepositoryActionSeparatorV1, repository).ToArray(); } private IEnumerable Map(RepositoryActionSeparatorV1? action, Repository repository) diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionPinRepositoryV1.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionPinRepositoryV1.cs index c9a8d5b6..66f35d9c 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionPinRepositoryV1.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionPinRepositoryV1.cs @@ -27,16 +27,13 @@ public sealed class RepositoryActionPinRepositoryV1 : RepositoryAction /// [Required] [PropertyType(typeof(PinMode))] - public PinMode Mode { get; set; } + public PinMode? Mode { get; set; } /// /// The PinModes /// public enum PinMode { - // when deserialization fails, this is the value. - Unknown, - /// /// Toggle /// diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/IActionToRepositoryActionMapper.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/IActionToRepositoryActionMapper.cs index 5126e84f..9e15d3c6 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/IActionToRepositoryActionMapper.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/IActionToRepositoryActionMapper.cs @@ -9,7 +9,5 @@ public interface IActionToRepositoryActionMapper { bool CanMap(RepositoryAction action); - bool CanHandleMultipleRepositories(); - - IEnumerable Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition); + IEnumerable Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition); } diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs index b81666a2..a80a5c91 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs @@ -223,11 +223,9 @@ List EvaluateVariables(IEnumerable? vars) continue; } - // todo redirect - try { - repoSpecificConfig = _repositoryActionsFileStore.TryGet(filename); + repoSpecificConfig = _repositoryActionsFileStore.TryGet(f); } catch (Exception) { @@ -435,7 +433,9 @@ public IEnumerable CreateActions(Repository repository) using IDisposable d2 = EnvironmentVariableStore.Set(repositoryEnvVars ?? new Dictionary()); // load variables global - foreach (ActionsCollection actionsCollection in ((IEnumerable?)actions) ?? Array.Empty()) + IEnumerable iterateOverActions = actions != null ? actions : Array.Empty(); + + foreach (ActionsCollection actionsCollection in iterateOverActions) { using IDisposable d3 = RepoMVariableProviderStore.Push(EvaluateVariables(actionsCollection.Variables, repository)); diff --git a/src/RepoM.Api/IO/MultipleRepositoryActionHelper.cs b/src/RepoM.Api/IO/MultipleRepositoryActionHelper.cs deleted file mode 100644 index 06260fce..00000000 --- a/src/RepoM.Api/IO/MultipleRepositoryActionHelper.cs +++ /dev/null @@ -1,47 +0,0 @@ -namespace RepoM.Api.IO; - -using System; -using System.Collections.Generic; -using System.Linq; -using RepoM.Api.Git; -using RepoM.Core.Plugin.RepositoryActions.Actions; - -public static class MultipleRepositoryActionHelper -{ - public static RepositoryAction CreateActionForMultipleRepositories( - string name, - IEnumerable repositories, - Action action, - bool executionCausesSynchronizing = false) - { - // todo coen, fix - return new RepositoryAction(name, repositories.First()) - { - Action = new DelegateAction((_, _) => - { - // copy over to an array to not get an exception - // once the enumerator changes (which can happen when a change - // is detected and a repository is renewed) while the loop is running - Repository[] repositoryArray = repositories.ToArray(); - - foreach (Repository repository in repositoryArray) - { - SafelyExecute(action, repository); // git/io-exceptions will break the loop, put in try/catch - } - }), - ExecutionCausesSynchronizing = executionCausesSynchronizing, - }; - } - - private static void SafelyExecute(Action action, Repository repository) - { - try - { - action(repository); - } - catch - { - // nothing to see here - } - } -} \ No newline at end of file diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index 31df4267..8f249321 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -11,10 +11,10 @@ - + - + diff --git a/src/RepoM.App/Bootstrapper.cs b/src/RepoM.App/Bootstrapper.cs index 4d864834..caac53dd 100644 --- a/src/RepoM.App/Bootstrapper.cs +++ b/src/RepoM.App/Bootstrapper.cs @@ -67,6 +67,7 @@ public static void RegisterServices(IFileSystem fileSystem) Container.Register(Lifestyle.Singleton); Container.RegisterInstance(DefaultAppDataPathProvider.Instance); Container.Register(Lifestyle.Singleton); + Container.RegisterDecorator(Lifestyle.Singleton); Container.Register(Lifestyle.Singleton); Container.Register(Lifestyle.Singleton); Container.Register(Lifestyle.Singleton); diff --git a/src/RepoM.App/MainWindow.xaml.cs b/src/RepoM.App/MainWindow.xaml.cs index 9b0e0e0a..4d63b62b 100644 --- a/src/RepoM.App/MainWindow.xaml.cs +++ b/src/RepoM.App/MainWindow.xaml.cs @@ -31,12 +31,12 @@ namespace RepoM.App; /// public partial class MainWindow { + private volatile bool _refreshDelayed; private readonly IRepositoryActionProvider _repositoryActionProvider; private readonly IRepositoryIgnoreStore _repositoryIgnoreStore; private readonly DefaultRepositoryMonitor? _monitor; private readonly ITranslationService _translationService; private bool _closeOnDeactivate = true; - private bool _refreshDelayed; private DateTime _timeOfLastRefresh = DateTime.MinValue; private readonly IFileSystem _fileSystem; private readonly ActionExecutor _executor; @@ -540,11 +540,11 @@ private void OnTxtFilterTextChanged(object? sender, TextChangedEventArgs e) // Text has changed, capture the timestamp if (sender != null) { - _timeOfLastRefresh = DateTime.Now; + _timeOfLastRefresh = DateTime.UtcNow; } // Spin while updates are in progress - if (DateTime.Now - _timeOfLastRefresh < TimeSpan.FromMilliseconds(100)) + if (DateTime.UtcNow - _timeOfLastRefresh < TimeSpan.FromMilliseconds(100)) { if (!_refreshDelayed) { diff --git a/src/RepoM.App/RepoM.App.csproj b/src/RepoM.App/RepoM.App.csproj index f7ab42fc..977e013d 100644 --- a/src/RepoM.App/RepoM.App.csproj +++ b/src/RepoM.App/RepoM.App.csproj @@ -42,10 +42,10 @@ - + - + diff --git a/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj b/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj index 430c4679..2667378b 100644 --- a/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj +++ b/src/RepoM.Core.Plugin/RepoM.Core.Plugin.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1Mapper.cs b/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1Mapper.cs index 2da5cf47..cc22f351 100644 --- a/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1Mapper.cs +++ b/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1Mapper.cs @@ -32,15 +32,10 @@ public bool CanMap(RepositoryAction action) { return action is RepositoryActionAzureDevOpsCreatePullRequestsV1; } - - public bool CanHandleMultipleRepositories() - { - return false; - } - - public IEnumerable Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) + + public IEnumerable Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return Map(action as RepositoryActionAzureDevOpsCreatePullRequestsV1, repository.First()); + return Map(action as RepositoryActionAzureDevOpsCreatePullRequestsV1, repository); } private IEnumerable Map(RepositoryActionAzureDevOpsCreatePullRequestsV1? action, Repository repository) diff --git a/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsGetPullRequestsV1Mapper.cs b/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsGetPullRequestsV1Mapper.cs index 10145379..4355fa40 100644 --- a/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsGetPullRequestsV1Mapper.cs +++ b/src/RepoM.Plugin.AzureDevOps/ActionProvider/ActionAzureDevOpsGetPullRequestsV1Mapper.cs @@ -34,14 +34,9 @@ public bool CanMap(RepositoryAction action) return action is RepositoryActionAzureDevOpsGetPullRequestsV1; } - public bool CanHandleMultipleRepositories() + public IEnumerable Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - public IEnumerable Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionAzureDevOpsGetPullRequestsV1, repository.First()); + return Map(action as RepositoryActionAzureDevOpsGetPullRequestsV1, repository); } private Api.Git.RepositoryAction[] Map(RepositoryActionAzureDevOpsGetPullRequestsV1? action, Repository repository) diff --git a/src/RepoM.Plugin.Clipboard/ActionProvider/ActionClipboardCopyV1Mapper.cs b/src/RepoM.Plugin.Clipboard/ActionProvider/ActionClipboardCopyV1Mapper.cs index 1ff8d6dc..76b1cb66 100644 --- a/src/RepoM.Plugin.Clipboard/ActionProvider/ActionClipboardCopyV1Mapper.cs +++ b/src/RepoM.Plugin.Clipboard/ActionProvider/ActionClipboardCopyV1Mapper.cs @@ -32,14 +32,9 @@ public bool CanMap(RepositoryAction action) return action is RepositoryActionClipboardCopyV1; } - public bool CanHandleMultipleRepositories() + public IEnumerable Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - public IEnumerable Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionClipboardCopyV1, repository.First()); + return Map(action as RepositoryActionClipboardCopyV1, repository); } private IEnumerable Map(RepositoryActionClipboardCopyV1? action, Repository repository) diff --git a/src/RepoM.Plugin.Heidi/ActionProvider/ActionHeidiDatabasesV1Mapper.cs b/src/RepoM.Plugin.Heidi/ActionProvider/ActionHeidiDatabasesV1Mapper.cs index 252d0163..b1acff0d 100644 --- a/src/RepoM.Plugin.Heidi/ActionProvider/ActionHeidiDatabasesV1Mapper.cs +++ b/src/RepoM.Plugin.Heidi/ActionProvider/ActionHeidiDatabasesV1Mapper.cs @@ -45,14 +45,9 @@ public bool CanMap(RepositoryAction action) return action is RepositoryActionHeidiDatabasesV1; } - public bool CanHandleMultipleRepositories() + public IEnumerable Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - public IEnumerable Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionHeidiDatabasesV1, repository.First()); + return Map(action as RepositoryActionHeidiDatabasesV1, repository); } private IEnumerable Map(RepositoryActionHeidiDatabasesV1? action, Repository repository) @@ -67,56 +62,51 @@ private IEnumerable Map(RepositoryActionHeidiDatabasesV1? yield break; } - var executable = string.IsNullOrWhiteSpace(action.Executable) - ? _settings.DefaultExe - : _expressionEvaluator.EvaluateStringExpression(action.Executable, repository); - + var executable = GetHeidiExecutable(action, repository); if (string.IsNullOrWhiteSpace(executable)) { _logger.LogWarning("HeidiSQL executable was empty"); yield break; } - RepositoryHeidiConfiguration[] databases = (string.IsNullOrWhiteSpace(action.Key) - ? _service.GetByRepository(repository) - : _service.GetByKey(action.Key)) - .ToArray(); + RepositoryHeidiConfiguration[] databases = GetHeidiDatabases(action, repository); string? name = action.Name; if (!string.IsNullOrWhiteSpace(name)) { name = NameHelper.EvaluateName(name, repository, _translationService, _expressionEvaluator); + } - if (!string.IsNullOrWhiteSpace(name)) + if (!string.IsNullOrWhiteSpace(name)) + { + if (databases.Length > 0) { - if (databases.Length > 0) - { - yield return new Api.Git.RepositoryAction(name, repository) - { - CanExecute = true, - SubActions = GetDbActions(repository, databases, executable), - }; - } - else - { - yield return new Api.Git.RepositoryAction(name, repository) - { - CanExecute = true, - SubActions = new[] - { - new Api.Git.RepositoryAction("NO databases found!", repository) - { - Action = NullAction.Instance, - CanExecute = false, - }, - }, - }; - } - - yield break; + yield return new Api.Git.RepositoryAction(name, repository) + { + CanExecute = true, + SubActions = GetDbActions(repository, databases, executable), + }; } + else + { + yield return new Api.Git.RepositoryAction(name, repository) + { + CanExecute = true, + SubActions = new[] + { + new Api.Git.RepositoryAction("NO databases found!", repository) + { + Action = NullAction.Instance, + CanExecute = false, + }, + }, + }; + } + + yield break; } + if (databases.Length > 0) { @@ -135,6 +125,21 @@ private IEnumerable Map(RepositoryActionHeidiDatabasesV1? } } + private RepositoryHeidiConfiguration[] GetHeidiDatabases(RepositoryActionHeidiDatabasesV1 action, IRepository repository) + { + return (string.IsNullOrWhiteSpace(action.Key) + ? _service.GetByRepository(repository) + : _service.GetByKey(action.Key)) + .ToArray(); + } + + private string GetHeidiExecutable(RepositoryActionHeidiDatabasesV1 action, IRepository repository) + { + return string.IsNullOrWhiteSpace(action.Executable) + ? _settings.DefaultExe + : _expressionEvaluator.EvaluateStringExpression(action.Executable, repository); + } + private static IEnumerable GetDbActions(IRepository repository, IEnumerable databases, string executable) { return databases.Select(database => new Api.Git.RepositoryAction(database.Name, repository) diff --git a/src/RepoM.Plugin.SonarCloud/ActionSonarCloudV1Mapper.cs b/src/RepoM.Plugin.SonarCloud/ActionSonarCloudV1Mapper.cs index 7b127040..d65e4d63 100644 --- a/src/RepoM.Plugin.SonarCloud/ActionSonarCloudV1Mapper.cs +++ b/src/RepoM.Plugin.SonarCloud/ActionSonarCloudV1Mapper.cs @@ -32,14 +32,9 @@ bool IActionToRepositoryActionMapper.CanMap(RepositoryAction action) return action is RepositoryActionSonarCloudSetFavoriteV1; } - public bool CanHandleMultipleRepositories() + IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { - return false; - } - - IEnumerable IActionToRepositoryActionMapper.Map(RepositoryAction action, IEnumerable repository, ActionMapperComposition actionMapperComposition) - { - return Map(action as RepositoryActionSonarCloudSetFavoriteV1, repository.First()); + return Map(action as RepositoryActionSonarCloudSetFavoriteV1, repository); } private IEnumerable Map(RepositoryActionSonarCloudSetFavoriteV1? action, Repository repository) diff --git a/tests/RepoM.Api.Tests/IO/Methods/IsNullMethodTests.cs b/tests/RepoM.Api.Tests/IO/Methods/IsNullMethodTests.cs new file mode 100644 index 00000000..20df376e --- /dev/null +++ b/tests/RepoM.Api.Tests/IO/Methods/IsNullMethodTests.cs @@ -0,0 +1,118 @@ +namespace RepoM.Api.Tests.IO.Methods; + +using RepoM.Api.IO.Methods; +using FluentAssertions; +using Xunit; + +public class IsNullMethodTests +{ + private readonly IsNullMethod _sut = new(); + + [Theory] + [InlineData("IsNull", true)] + [InlineData("isnull", true)] + [InlineData("IsNullx", false)] + [InlineData("", false)] + [InlineData(null, false)] + public void CanHandle_ShouldReturnExpected(string? method, bool expectedResult) + { + // arrange + + // act + var result = _sut.CanHandle(method!); + + // assert + _ = result.Should().Be(expectedResult); + } + + [Fact] + public void Handle_ShouldReturnTrue_WhenAnArgumentsIsNull1() + { + // arrange + + // act + var result = _sut.Handle("IsNull", null!); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(true); + } + + [Fact] + public void Handle_ShouldReturnTrue_WhenAnArgumentsIsNull2() + { + // arrange + + // act + var result = _sut.Handle("IsNull", new object?[] { null!, }); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(true); + } + + [Fact] + public void Handle_ShouldReturnTrue_WhenAnArgumentsIsNull3() + { + // arrange + + // act + var result = _sut.Handle("IsNull", null!, null!); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(true); + } + + [Theory] + [InlineData("string")] + [InlineData(12)] + [InlineData(true)] + [InlineData(false)] + public void Handle_ShouldReturnTrue_WhenAnArgumentsIsNull4(object notNullValue) + { + // arrange + + // act + var result = _sut.Handle("IsNull", null!, notNullValue, null!); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(true); + } + + + [Theory] + [InlineData("string")] + [InlineData(12)] + [InlineData(true)] + [InlineData(false)] + public void Handle_ShouldReturnFalse_WhenAllArgumentsAreNotNull1(object notNullValue) + { + // arrange + + // act + var result = _sut.Handle("IsNull", notNullValue); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(false); + } + + [Theory] + [InlineData("string")] + [InlineData(12)] + [InlineData(true)] + [InlineData(false)] + public void Handle_ShouldReturnFalse_WhenAllArgumentsAreNotNull2(object notNullValue) + { + // arrange + + // act + var result = _sut.Handle("IsNull", "first param", notNullValue); + + // assert + _ = result.Should().BeOfType(); + _ = result.Should().Be(false); + } +} \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1MapperTests.cs b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1MapperTests.cs index cd0689e1..a6716f7b 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1MapperTests.cs +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionAssociateFileV1MapperTests.cs @@ -42,20 +42,7 @@ public void Ctor_ShouldThrown_WhenArgumentIsNull() act2.Should().ThrowExactly(); } - [Fact] - public void CanHandleMultipleRepositories_ShouldReturnFalse() - { - // arrange - var sut = new ActionAssociateFileV1Mapper(_expressionEvaluator, _translationService) as IActionToRepositoryActionMapper; - - // act - var result = sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - } - - [Fact] + [Fact] public void CanMap_ShouldReturnFalse_WhenInputNull() { // arrange @@ -103,7 +90,7 @@ public void Map_ShouldReturnEmpty_WhenActionIsNotOfCorrectType() var sut = new ActionAssociateFileV1Mapper(_expressionEvaluator, _translationService) as IActionToRepositoryActionMapper; // act - RepositoryActionBase[] result = sut.Map(action, new [] { _repository, }, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); + RepositoryActionBase[] result = sut.Map(action, _repository, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); // assert result.Should().BeEmpty(); @@ -121,7 +108,7 @@ public void Map_ShouldReturnEmpty_WhenActionActiveIsEvaluatesToFalse() var sut = new ActionAssociateFileV1Mapper(_expressionEvaluator, _translationService) as IActionToRepositoryActionMapper; // act - RepositoryActionBase[] result = sut.Map(action, new [] { _repository, }, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); + RepositoryActionBase[] result = sut.Map(action, _repository, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); // assert result.Should().BeEmpty(); @@ -139,7 +126,7 @@ public void Map_ShouldReturnEmpty_WhenActionExtensionIsNull() var sut = new ActionAssociateFileV1Mapper(_expressionEvaluator, _translationService) as IActionToRepositoryActionMapper; // act - RepositoryActionBase[] result = sut.Map(action, new [] { _repository, }, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); + RepositoryActionBase[] result = sut.Map(action, _repository, ActionMapperCompositionFactory.CreateSmall(_expressionEvaluator, A.Dummy())).ToArray(); // assert result.Should().BeEmpty(); diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1MapperTests.cs b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1MapperTests.cs index 6172bc11..dd1c4fe4 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1MapperTests.cs +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionGitCheckoutV1MapperTests.cs @@ -40,19 +40,6 @@ public void Ctor_ShouldThrown_WhenArgumentIsNull() act3.Should().ThrowExactly(); } - [Fact] - public void CanHandleMultipleRepositories_ShouldReturnFalse() - { - // arrange - var sut = new ActionGitCheckoutV1Mapper(_expressionEvaluator, _translationService, _repositoryWriter) as IActionToRepositoryActionMapper; - - // act - var result = sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenInputNull() { diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/RepositorySpecificConfigurationTest.Create_ShouldProcessSeparator1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/RepositorySpecificConfigurationTest.Create_ShouldProcessSeparator1.verified.txt index 442ed10f..ad4f6223 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/RepositorySpecificConfigurationTest.Create_ShouldProcessSeparator1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/RepositorySpecificConfigurationTest.Create_ShouldProcessSeparator1.verified.txt @@ -6,7 +6,7 @@ $type: DelegateAction, Action: { Type: Action, - Target: ActionBrowserV1Mapper.<>c__DisplayClass6_0, + Target: ActionBrowserV1Mapper.<>c__DisplayClass5_0, Method: Void Map(System.Object, System.Object) } }, @@ -28,7 +28,7 @@ $type: DelegateAction, Action: { Type: Action, - Target: ActionBrowserV1Mapper.<>c__DisplayClass6_0, + Target: ActionBrowserV1Mapper.<>c__DisplayClass5_0, Method: Void Map(System.Object, System.Object) } }, diff --git a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj index fb7ffc32..0cf5227b 100644 --- a/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj +++ b/tests/RepoM.Api.Tests/RepoM.Api.Tests.csproj @@ -14,18 +14,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.App.Tests/RepoM.App.Tests.csproj b/tests/RepoM.App.Tests/RepoM.App.Tests.csproj index d04e35fa..1789b8db 100644 --- a/tests/RepoM.App.Tests/RepoM.App.Tests.csproj +++ b/tests/RepoM.App.Tests/RepoM.App.Tests.csproj @@ -14,18 +14,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1MapperTests.cs b/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1MapperTests.cs index b01c416c..fcf6631d 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1MapperTests.cs +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsCreatePullRequestsV1MapperTests.cs @@ -22,7 +22,6 @@ public class ActionAzureDevOpsCreatePullRequestsV1MapperTests private readonly IRepositoryExpressionEvaluator _evaluator; private readonly ActionAzureDevOpsCreatePullRequestsV1Mapper _sut; private readonly RepositoryActionAzureDevOpsCreatePullRequestsV1 _action; - private readonly IEnumerable _repositories; private readonly Repository _repository; private readonly ActionMapperComposition _composition; @@ -43,7 +42,6 @@ public ActionAzureDevOpsCreatePullRequestsV1MapperTests() "main", }, }; - _repositories = new [] { _repository, }; _composition = new ActionMapperComposition(Array.Empty(), _evaluator); // default test behavior. @@ -53,19 +51,6 @@ public ActionAzureDevOpsCreatePullRequestsV1MapperTests() A.CallTo(() => _evaluator.EvaluateStringExpression("dummy-project-id", A._)).Returns("real-project-id"); } - [Fact] - public void CanHandleMultipleRepositories_ShouldReturnFalse() - { - // arrange - - // act - var result = _sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - A.CallTo(_service).MustNotHaveHappened(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenInputIsNotValidType() { @@ -100,7 +85,7 @@ public void Map_ShouldReturnEmptySet_WhenWrongActionType() // arrange // act - IEnumerable result = _sut.Map(new DummyRepositoryAction(), _repositories, _composition); + IEnumerable result = _sut.Map(new DummyRepositoryAction(), _repository, _composition); // assert result.Should().BeEmpty(); @@ -115,7 +100,7 @@ public void Map_ShouldReturnEmptySet_WhenActionNotActive() A.CallTo(() => _evaluator.EvaluateBooleanExpression("dummy", _repository)).Returns(false); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -132,7 +117,7 @@ public void Map_ShouldReturnEmptySet_WhenProjectIdNotSet(string? projectId) _action.ProjectId = projectId; // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -150,7 +135,7 @@ public void Map_ShouldReturnEmptySet_WhenProjectIdIsNotValidAfterEvaluation(stri A.CallTo(() => _evaluator.EvaluateStringExpression("dummy-project-id", A._)).Returns(projectId!); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -163,7 +148,7 @@ public void Map_ShouldReturnRepositoryActions() // arrange // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().HaveCount(1).And.AllBeOfType(); @@ -175,7 +160,7 @@ public void Map_ShouldReturnRepositoryActions_WithAutoComplete() // arrange // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().HaveCount(1).And.AllBeOfType(); diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsGetPullRequestsV1MapperTests.cs b/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsGetPullRequestsV1MapperTests.cs index ceff4142..36ca0ba0 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsGetPullRequestsV1MapperTests.cs +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/ActionProvider/ActionAzureDevOpsGetPullRequestsV1MapperTests.cs @@ -22,7 +22,6 @@ public class ActionAzureDevOpsGetPullRequestsV1MapperTests private readonly IRepositoryExpressionEvaluator _evaluator; private readonly ActionAzureDevOpsGetPullRequestsV1Mapper _sut; private readonly RepositoryActionAzureDevOpsGetPullRequestsV1 _action; - private readonly IEnumerable _repositories; private readonly Repository _repository; private readonly ActionMapperComposition _composition; @@ -34,7 +33,6 @@ public ActionAzureDevOpsGetPullRequestsV1MapperTests() _action = new RepositoryActionAzureDevOpsGetPullRequestsV1(); _repository = new Repository(""); - _repositories = new [] { _repository, }; _composition = new ActionMapperComposition(Array.Empty(), _evaluator); // default test behavior. @@ -45,19 +43,6 @@ public ActionAzureDevOpsGetPullRequestsV1MapperTests() A.CallTo(() => _evaluator.EvaluateStringExpression("dummy-project-id", A._)).Returns("real-project-id"); } - [Fact] - public void CanHandleMultipleRepositories_ShouldReturnFalse() - { - // arrange - - // act - var result = _sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - A.CallTo(_service).MustNotHaveHappened(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenInputIsNotValidType() { @@ -92,7 +77,7 @@ public void Map_ShouldReturnEmptySet_WhenWrongActionType() // arrange // act - IEnumerable result = _sut.Map(new DummyRepositoryAction(), _repositories, _composition); + IEnumerable result = _sut.Map(new DummyRepositoryAction(), _repository, _composition); // assert result.Should().BeEmpty(); @@ -107,7 +92,7 @@ public void Map_ShouldReturnEmptySet_WhenActionNotActive() A.CallTo(() => _evaluator.EvaluateBooleanExpression("dummy", _repository)).Returns(false); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -124,7 +109,7 @@ public void Map_ShouldReturnEmptySet_WhenProjectIdNotSet(string? projectId) _action.ProjectId = projectId; // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -142,7 +127,7 @@ public void Map_ShouldReturnEmptySet_WhenProjectIdIsNotValidAfterEvaluation(stri A.CallTo(() => _evaluator.EvaluateStringExpression("dummy-project-id", A._)).Returns(projectId!); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -157,7 +142,7 @@ public void Map_ShouldReturnEmptySet_WhenServiceReturnsNoPullRequests() .Returns(new List(0)); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().BeEmpty(); @@ -177,7 +162,7 @@ public void Map_ShouldReturnRepositoryActions_WhenServiceReturnsPullRequests() }); // act - IEnumerable result = _sut.Map(_action, _repositories, _composition); + IEnumerable result = _sut.Map(_action, _repository, _composition); // assert result.Should().HaveCount(2).And.AllBeOfType(); diff --git a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj index 6a43daa3..b50f61e1 100644 --- a/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj +++ b/tests/RepoM.Plugin.AzureDevOps.Tests/RepoM.Plugin.AzureDevOps.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.Clipboard.Tests/ActionProvider/ActionClipboardCopyV1MapperTests.cs b/tests/RepoM.Plugin.Clipboard.Tests/ActionProvider/ActionClipboardCopyV1MapperTests.cs index bf876b36..10ca468f 100644 --- a/tests/RepoM.Plugin.Clipboard.Tests/ActionProvider/ActionClipboardCopyV1MapperTests.cs +++ b/tests/RepoM.Plugin.Clipboard.Tests/ActionProvider/ActionClipboardCopyV1MapperTests.cs @@ -83,18 +83,6 @@ public void Ctor_ShouldThrowArgumentNullException_WhenAnArgumentIsNull() } } - [Fact] - public void CanHandleMultipleRepositories_ShouldBeFalse() - { - // arrange - - // act - var result = _sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenWrongType() { @@ -139,7 +127,7 @@ public void Map_ShouldReturnEmpty_WhenActionIsNull() // arrange // act - var result = _sut.Map(null!, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(null!, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -152,7 +140,7 @@ public void Map_ShouldReturnEmpty_WhenActionActiveIsFalse() _action.Active = "false"; // act - var result = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -170,7 +158,7 @@ public async Task Map_ShouldMap_WhenTextSet(string? text) _action.Text = text; // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert var paramText = text ?? "null"; @@ -193,7 +181,7 @@ public async Task Map_ShouldMap_WhenNameSet(string? name) _action.Name = name; // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert var paramText = name ?? "null"; diff --git a/tests/RepoM.Plugin.Clipboard.Tests/RepoM.Plugin.Clipboard.Tests.csproj b/tests/RepoM.Plugin.Clipboard.Tests/RepoM.Plugin.Clipboard.Tests.csproj index 01a99239..d64f9c77 100644 --- a/tests/RepoM.Plugin.Clipboard.Tests/RepoM.Plugin.Clipboard.Tests.csproj +++ b/tests/RepoM.Plugin.Clipboard.Tests/RepoM.Plugin.Clipboard.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.EverythingFileSearch.Tests/RepoM.Plugin.EverythingFileSearch.Tests.csproj b/tests/RepoM.Plugin.EverythingFileSearch.Tests/RepoM.Plugin.EverythingFileSearch.Tests.csproj index eb49c5f9..4c1b306f 100644 --- a/tests/RepoM.Plugin.EverythingFileSearch.Tests/RepoM.Plugin.EverythingFileSearch.Tests.csproj +++ b/tests/RepoM.Plugin.EverythingFileSearch.Tests/RepoM.Plugin.EverythingFileSearch.Tests.csproj @@ -14,17 +14,17 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -34,5 +34,6 @@ + diff --git a/tests/RepoM.Plugin.Heidi.Tests/ActionProvider/ActionHeidiDatabasesV1MapperTests.cs b/tests/RepoM.Plugin.Heidi.Tests/ActionProvider/ActionHeidiDatabasesV1MapperTests.cs index 31638e35..908f21dc 100644 --- a/tests/RepoM.Plugin.Heidi.Tests/ActionProvider/ActionHeidiDatabasesV1MapperTests.cs +++ b/tests/RepoM.Plugin.Heidi.Tests/ActionProvider/ActionHeidiDatabasesV1MapperTests.cs @@ -105,18 +105,6 @@ public void Ctor_ShouldThrowArgumentNullException_WhenAnArgumentIsNull() } } - [Fact] - public void CanHandleMultipleRepositories_ShouldBeFalse() - { - // arrange - - // act - var result = _sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenWrongType() { @@ -161,7 +149,7 @@ public void Map_ShouldReturnEmpty_WhenActionIsNull() // arrange // act - var result = _sut.Map(null!, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(null!, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -175,7 +163,7 @@ public void Map_ShouldReturnEmpty_WhenActionActiveIsFalse() _action.Active = "false"; // act - var result = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -189,7 +177,7 @@ public void Map_ShouldUseDefaultExe_WhenActionExecutableIsEmpty() _action.Executable = string.Empty; // act - _ = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + _ = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert A.CallTo(() => _settings.DefaultExe).MustHaveHappenedOnceExactly(); @@ -202,7 +190,7 @@ public void Map_ShouldUseActionExeAndNotDefaultExe_WhenActionExecutableIsNotEmpt _action.Executable = "heidi123.exe"; // act - _ = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + _ = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert A.CallTo(() => _expressionEvaluator.EvaluateStringExpression("heidi123.exe", _repository)).MustHaveHappenedOnceExactly(); @@ -217,7 +205,7 @@ public void Map_ShouldReturnEmpty_WhenExecutableIsEmpty() A.CallTo(() => _settings.DefaultExe).Returns(string.Empty); // act - var result = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -233,7 +221,7 @@ public void Map_ShouldReturnEmpty_WhenExecutableIsEmptyAfterStringEvaluation() .Returns(string.Empty); // act - var result = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert result.Should().BeEmpty(); @@ -247,7 +235,7 @@ public void Map_ShouldQueryUsingKey_WhenKeyProvidedInAction() _action.Key = "key1"; // act - _ = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + _ = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert A.CallTo(() => _service.GetByKey("key1")).MustHaveHappenedOnceExactly(); @@ -264,7 +252,7 @@ public void Map_ShouldQueryUsingRepository_WhenKeyNotProvidedInAction(string? ke _action.Key = keyValue; // act - _ = _sut.Map(_action, new []{ _repository, }, _actionMapperComposition).ToArray(); + _ = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert A.CallTo(() => _service.GetByRepository(_repository)).MustHaveHappenedOnceExactly(); @@ -278,7 +266,7 @@ public async Task Map_ShouldReturnNoDatabasesFoundAction_WhenNameIsNullOrEmptyAn _action.Name = string.Empty; // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert await Verifier.Verify(result, _verifySettings); @@ -297,7 +285,7 @@ public async Task Map_ShouldReturnActions_WhenNameIsNullOrEmptyAndDatabasesFound }); // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert await Verifier.Verify(result, _verifySettings); @@ -310,7 +298,7 @@ public async Task Map_ShouldReturnFolderWithNoDatabasesFoundAction_WhenNameIsSet _action.Name = "Databases"; // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert await Verifier.Verify(result, _verifySettings); @@ -329,7 +317,7 @@ public async Task Map_ShouldReturnFolderWithDatabaseActions_WhenNameIsSetAndData }); // act - var result = _sut.Map(_action, new[] { _repository, }, _actionMapperComposition).ToArray(); + var result = _sut.Map(_action, _repository, _actionMapperComposition).ToArray(); // assert await Verifier.Verify(result, _verifySettings); diff --git a/tests/RepoM.Plugin.Heidi.Tests/RepoM.Plugin.Heidi.Tests.csproj b/tests/RepoM.Plugin.Heidi.Tests/RepoM.Plugin.Heidi.Tests.csproj index 74076db4..65968aff 100644 --- a/tests/RepoM.Plugin.Heidi.Tests/RepoM.Plugin.Heidi.Tests.csproj +++ b/tests/RepoM.Plugin.Heidi.Tests/RepoM.Plugin.Heidi.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.LuceneQueryParser.Tests/RepoM.Plugin.LuceneQueryParser.Tests.csproj b/tests/RepoM.Plugin.LuceneQueryParser.Tests/RepoM.Plugin.LuceneQueryParser.Tests.csproj index cdd5ee96..a791a1fc 100644 --- a/tests/RepoM.Plugin.LuceneQueryParser.Tests/RepoM.Plugin.LuceneQueryParser.Tests.csproj +++ b/tests/RepoM.Plugin.LuceneQueryParser.Tests/RepoM.Plugin.LuceneQueryParser.Tests.csproj @@ -14,18 +14,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj b/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj index 8e636b44..5852eff4 100644 --- a/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj +++ b/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.SonarCloud.Tests/ActionSonarCloudV1MapperTests.cs b/tests/RepoM.Plugin.SonarCloud.Tests/ActionSonarCloudV1MapperTests.cs index b0e56581..0f962656 100644 --- a/tests/RepoM.Plugin.SonarCloud.Tests/ActionSonarCloudV1MapperTests.cs +++ b/tests/RepoM.Plugin.SonarCloud.Tests/ActionSonarCloudV1MapperTests.cs @@ -43,18 +43,6 @@ public void Ctor_ShouldThrow_WhenArgumentNull() act3.Should().Throw(); } - [Fact] - public void CanHandleMultipleRepositories_ShouldReturnFalse() - { - // arrange - - // act - var result = _sut.CanHandleMultipleRepositories(); - - // assert - result.Should().BeFalse(); - } - [Fact] public void CanMap_ShouldReturnFalse_WhenWrongType() { diff --git a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj index 306c09b2..19608bfb 100644 --- a/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj +++ b/tests/RepoM.Plugin.SonarCloud.Tests/RepoM.Plugin.SonarCloud.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.Statistics.Tests/RepoM.Plugin.Statistics.Tests.csproj b/tests/RepoM.Plugin.Statistics.Tests/RepoM.Plugin.Statistics.Tests.csproj index ecb213b4..b91c727a 100644 --- a/tests/RepoM.Plugin.Statistics.Tests/RepoM.Plugin.Statistics.Tests.csproj +++ b/tests/RepoM.Plugin.Statistics.Tests/RepoM.Plugin.Statistics.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests.csproj b/tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests.csproj index aca46131..afbc30b4 100644 --- a/tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests.csproj +++ b/tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests/RepoM.Plugin.WindowsExplorerGitInfo.Tests.csproj @@ -15,18 +15,18 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - + + + + + diff --git a/tests/SystemTests/SystemTests.csproj b/tests/SystemTests/SystemTests.csproj index 68ae4869..813d197d 100644 --- a/tests/SystemTests/SystemTests.csproj +++ b/tests/SystemTests/SystemTests.csproj @@ -17,20 +17,20 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - + - - + +