From 3a339049150e51708939cb87ec515d4f408c8eba Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 08:42:42 +0200 Subject: [PATCH 01/14] Implement --- README.source.md | 2 + RepoM.sln | 46 +++++++++ docs/mdsource/ActionList.source.md | 12 +-- .../RepoM.Plugin.WebBrowser.source.md | 9 ++ .../_plugins.webbrowser.action.include.md | 7 ++ .../RepositorySpecificConfiguration.cs | 52 +++++----- src/RepoM.Api/IO/ProcessHelper.cs | 1 - .../Executors/BrowseActionExecutor.cs | 16 --- src/RepoM.App/Bootstrapper.cs | 2 +- src/RepoM.App/RepoM.App.csproj | 1 + .../RepositoryActions/Actions/BrowseAction.cs | 7 -- .../ClipboardPackage.cs | 1 - .../ActionProvider}/ActionBrowserV1Mapper.cs | 22 +++-- .../RepositoryActionBrowserV1.cs | 11 ++- .../PersistentConfiguration/CurrentVersion.cs | 6 ++ .../StatisticsConfigV1.cs | 14 +++ .../WebBrowserConfigV1.cs | 18 ++++ .../PluginInformation.cs | 5 + .../RepoM.Plugin.WebBrowser.csproj | 22 +++++ .../RepositoryActions/Actions/BrowseAction.cs | 16 +++ .../RepositoryActions/BrowseActionExecutor.cs | 31 ++++++ .../Services/IWebBrowserService.cs | 10 ++ .../Services/WebBrowserConfiguration.cs | 17 ++++ .../Services/WebBrowserService.cs | 59 +++++++++++ .../WebBrowserPackage.cs | 92 +++++++++++++++++ ...amicRepositoryActionDeserializerFactory.cs | 1 - ...V1Test.Deserialize_CommandV1.testfile.yaml | 4 +- ...est.Deserialize_ExecutableV1.testfile.yaml | 8 +- ...V1Test.Deserialize_ForEachV1.testfile.yaml | 5 +- ...dV1Test.Deserialize_CommandV1.verified.txt | 4 +- ...Test.Deserialize_ExecutableV1.verified.txt | 8 +- .../ActionMapperCompositionFactory.cs | 1 - .../Foreach01.testfile.yaml | 5 +- ...alize_Documentation_Foreach01.verified.txt | 7 +- .../DocumentationTests.cs | 1 - .../RepositorySpecificConfigurationTest.cs | 1 + .../TestFiles/ForEach1.testfile.yaml | 5 +- .../TestFiles/ForEach2.testfile.yaml | 5 +- .../TestFiles/ForEach3.testfile.yaml | 5 +- .../RepositoryActions1.testfile.yaml | 8 +- .../RepositoryActions2.testfile.yaml | 8 +- .../RepositoryActions3.testfile.yaml | 9 +- ...ositoryActionsWithSeparator1.testfile.yaml | 13 +-- .../TestFiles/Sample2.testfile.yaml | 8 +- .../TestFiles/Sample3.testfile.yaml | 8 +- ...izerTest.Deserialize_ForEach1.verified.txt | 7 +- ...izerTest.Deserialize_ForEach2.verified.txt | 7 +- ...izerTest.Deserialize_ForEach3.verified.txt | 7 +- ...lizerTest.Deserialize_Sample2.verified.txt | 12 +-- ...lizerTest.Deserialize_Sample3.verified.txt | 12 +-- ...enContentIsRepositoryActions1.verified.txt | 12 +-- ...enContentIsRepositoryActions3.verified.txt | 13 ++- ...reate_ShouldProcessSeparator1.verified.txt | 18 +--- ...ettings_WebBrowserPackage#desc.verified.md | 20 ++++ ...leSettings_WebBrowserPackage.verified.json | 7 ++ ...leSettingsTests.VerifyChanges.verified.txt | 3 + ...ings_RepositoryActionBrowserV1.verified.md | 1 + ...oryActionsTests.VerifyChanges.verified.txt | 4 +- tests/RepoM.Plugin.Misc.Tests/PluginStore.cs | 2 + .../RepoM.Plugin.Misc.Tests.csproj | 1 + .../ActionProvider}/BrowserV1Test.cs | 10 +- ....Deserialize_ActionBrowserV1.testfile.yaml | 0 ...t.Deserialize_ActionBrowserV1.verified.txt | 0 .../Browser01.testfile.yaml | 1 + ...alize_Documentation_Browser01.verified.txt | 1 + .../DocumentationTests.cs | 47 +++++++++ .../RepoM.Plugin.WebBrowser.Tests.csproj | 42 ++++++++ ...amicRepositoryActionDeserializerFactory.cs | 28 ++++++ .../TestFramework/VerifierInitializer.cs | 15 +++ .../WebBrowserPackageTest.cs | 99 +++++++++++++++++++ .../WebBrowserServiceTest.cs | 23 +++++ 71 files changed, 801 insertions(+), 184 deletions(-) create mode 100644 docs/mdsource/RepoM.Plugin.WebBrowser.source.md create mode 100644 docs/mdsource/_plugins.webbrowser.action.include.md delete mode 100644 src/RepoM.Api/RepositoryActions/Executors/BrowseActionExecutor.cs delete mode 100644 src/RepoM.Core.Plugin/RepositoryActions/Actions/BrowseAction.cs rename src/{RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers => RepoM.Plugin.WebBrowser/ActionProvider}/ActionBrowserV1Mapper.cs (61%) rename src/{RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions => RepoM.Plugin.WebBrowser/ActionProvider}/RepositoryActionBrowserV1.cs (62%) create mode 100644 src/RepoM.Plugin.WebBrowser/PersistentConfiguration/CurrentVersion.cs create mode 100644 src/RepoM.Plugin.WebBrowser/PersistentConfiguration/StatisticsConfigV1.cs create mode 100644 src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs create mode 100644 src/RepoM.Plugin.WebBrowser/PluginInformation.cs create mode 100644 src/RepoM.Plugin.WebBrowser/RepoM.Plugin.WebBrowser.csproj create mode 100644 src/RepoM.Plugin.WebBrowser/RepositoryActions/Actions/BrowseAction.cs create mode 100644 src/RepoM.Plugin.WebBrowser/RepositoryActions/BrowseActionExecutor.cs create mode 100644 src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs create mode 100644 src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs create mode 100644 src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs create mode 100644 src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs create mode 100644 tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md create mode 100644 tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json rename tests/{RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action => RepoM.Plugin.WebBrowser.Tests/ActionProvider}/BrowserV1Test.cs (74%) rename tests/{RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action => RepoM.Plugin.WebBrowser.Tests/ActionProvider}/TestFiles/BrowserV1Test.Deserialize_ActionBrowserV1.testfile.yaml (100%) rename tests/{RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action => RepoM.Plugin.WebBrowser.Tests/ActionProvider}/Verified/BrowserV1Test.Deserialize_ActionBrowserV1.verified.txt (100%) rename tests/{RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider => RepoM.Plugin.WebBrowser.Tests}/DocumentationFiles/Browser01.testfile.yaml (94%) rename tests/{RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider => RepoM.Plugin.WebBrowser.Tests}/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt (94%) create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/DocumentationTests.cs create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/RepoM.Plugin.WebBrowser.Tests.csproj create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/DynamicRepositoryActionDeserializerFactory.cs create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/VerifierInitializer.cs create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserPackageTest.cs create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs diff --git a/README.source.md b/README.source.md index cad34c74..5a040b6d 100644 --- a/README.source.md +++ b/README.source.md @@ -74,4 +74,6 @@ RepoM uses plugins to extend functionality. At this moment, when a plugin is ava - [LuceneQueryParser](docs/RepoM.Plugin.LuceneQueryParser.md) - [SonarCloud](docs/RepoM.Plugin.SonarCloud.md) - [Statistics](docs/RepoM.Plugin.Statistics.md) + - [WebBrowser](docs/RepoM.Plugin.WebBrowser.md) - [WindowsExplorerGitInfo](docs/RepoM.Plugin.WindowsExplorerGitInfo.md) + \ No newline at end of file diff --git a/RepoM.sln b/RepoM.sln index 8141252d..87aa8f73 100644 --- a/RepoM.sln +++ b/RepoM.sln @@ -51,6 +51,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.App.Tests", "tests\Re EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.Misc.Tests", "tests\RepoM.Plugin.Misc.Tests\RepoM.Plugin.Misc.Tests.csproj", "{A2264CB6-39DE-4EA2-8C1D-BA28115351E7}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.WebBrowser", "src\RepoM.Plugin.WebBrowser\RepoM.Plugin.WebBrowser.csproj", "{23D796D1-1902-4357-9C95-4FB120A24A6E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.WebBrowser.Tests", "tests\RepoM.Plugin.WebBrowser.Tests\RepoM.Plugin.WebBrowser.Tests.csproj", "{E976587E-F48E-4647-A307-91EFEC8F571C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -525,6 +529,46 @@ Global {A2264CB6-39DE-4EA2-8C1D-BA28115351E7}.Release|x64.Build.0 = Release|Any CPU {A2264CB6-39DE-4EA2-8C1D-BA28115351E7}.Release|x86.ActiveCfg = Release|Any CPU {A2264CB6-39DE-4EA2-8C1D-BA28115351E7}.Release|x86.Build.0 = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|ARM.ActiveCfg = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|ARM.Build.0 = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|ARM64.Build.0 = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|x64.ActiveCfg = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|x64.Build.0 = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|x86.ActiveCfg = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Debug|x86.Build.0 = Debug|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|Any CPU.Build.0 = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|ARM.ActiveCfg = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|ARM.Build.0 = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|ARM64.ActiveCfg = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|ARM64.Build.0 = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|x64.ActiveCfg = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|x64.Build.0 = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|x86.ActiveCfg = Release|Any CPU + {23D796D1-1902-4357-9C95-4FB120A24A6E}.Release|x86.Build.0 = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|ARM.ActiveCfg = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|ARM.Build.0 = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|ARM64.Build.0 = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|x64.ActiveCfg = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|x64.Build.0 = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|x86.ActiveCfg = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Debug|x86.Build.0 = Debug|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|Any CPU.Build.0 = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|ARM.ActiveCfg = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|ARM.Build.0 = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|ARM64.ActiveCfg = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|ARM64.Build.0 = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|x64.ActiveCfg = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|x64.Build.0 = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|x86.ActiveCfg = Release|Any CPU + {E976587E-F48E-4647-A307-91EFEC8F571C}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -547,6 +591,8 @@ Global {ED155806-81AD-49CC-B150-2C17F4902A1D} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {85BA3DD7-8589-4020-A7DF-7E9F5D1A9C1A} = {D6E372DC-10D3-4997-9DFC-568B4666635A} {A2264CB6-39DE-4EA2-8C1D-BA28115351E7} = {D6E372DC-10D3-4997-9DFC-568B4666635A} + {23D796D1-1902-4357-9C95-4FB120A24A6E} = {D6E372DC-10D3-4997-9DFC-568B4666635A} + {E976587E-F48E-4647-A307-91EFEC8F571C} = {D6E372DC-10D3-4997-9DFC-568B4666635A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1765ABAA-0652-4DA5-ABBF-05396F2957D7} diff --git a/docs/mdsource/ActionList.source.md b/docs/mdsource/ActionList.source.md index df645d5d..da28b788 100644 --- a/docs/mdsource/ActionList.source.md +++ b/docs/mdsource/ActionList.source.md @@ -30,14 +30,6 @@ Example: snippet: RepositoryActionsBrowseRepository01 -## browser@1 - -include: DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md - -Example: - -snippet: RepositoryActionsBrowser01 - ## command@1 include: DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionCommandV1.verified.md @@ -150,6 +142,10 @@ include: _plugins.heidi.action See the [Heidi](RepoM.Plugin.Heidi.md) plugin for more information. +include _plugins.webbrowser.action + +See the [WebBrowser](RepoM.Plugin.WebBrowser.md) plugin for more information. + # Repository Actions These actions are part of the Repository Actions config file described in [Repository Actions](RepositoryActions.md). diff --git a/docs/mdsource/RepoM.Plugin.WebBrowser.source.md b/docs/mdsource/RepoM.Plugin.WebBrowser.source.md new file mode 100644 index 00000000..94d655ac --- /dev/null +++ b/docs/mdsource/RepoM.Plugin.WebBrowser.source.md @@ -0,0 +1,9 @@ +# WebBrowser + +The WebBrowser module provides a repository action to open an URL in a given webbrowser. + +include: _plugin_enable + +include: DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md + +include: _plugins.webbrowser.action diff --git a/docs/mdsource/_plugins.webbrowser.action.include.md b/docs/mdsource/_plugins.webbrowser.action.include.md new file mode 100644 index 00000000..1fa7e570 --- /dev/null +++ b/docs/mdsource/_plugins.webbrowser.action.include.md @@ -0,0 +1,7 @@ +## browser@1 + +include: DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md + +Example: + +snippet: RepositoryActionsBrowser01 \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs index 10905dfd..cb8b081d 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs +++ b/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfiguration.cs @@ -9,7 +9,6 @@ namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider; using DotNetEnv; using Microsoft.Extensions.Logging; using RepoM.Api.Common; -using RepoM.Api.Git; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Deserialization; @@ -93,7 +92,7 @@ private string GetRepositoryActionsFilename(string basePath) var tags = new List(); // load default file - RepositoryActionConfiguration? rootFile = null; + RepositoryActionConfiguration? rootFile; RepositoryActionConfiguration? repoSpecificConfig = null; var filename = GetRepositoryActionsFilename(_appDataPathProvider.AppDataPath); @@ -273,7 +272,7 @@ private bool IsEnabled(string? booleanExpression, bool defaultWhenNullOrEmpty, I { return string.IsNullOrWhiteSpace(booleanExpression) ? defaultWhenNullOrEmpty - : _repoExpressionEvaluator.EvaluateBooleanExpression(booleanExpression!, repository); + : _repoExpressionEvaluator.EvaluateBooleanExpression(booleanExpression, repository); } } @@ -281,13 +280,16 @@ public class RepositoryTagsConfigurationFactory : IRepositoryTagsFactory { private readonly IRepositoryExpressionEvaluator _repoExpressionEvaluator; private readonly RepositoryConfigurationReader _repoConfigReader; + private readonly ILogger _logger; public RepositoryTagsConfigurationFactory( IRepositoryExpressionEvaluator repoExpressionEvaluator, - RepositoryConfigurationReader repoConfigReader) + RepositoryConfigurationReader repoConfigReader, + ILogger logger) { _repoExpressionEvaluator = repoExpressionEvaluator ?? throw new ArgumentNullException(nameof(repoExpressionEvaluator)); _repoConfigReader = repoConfigReader ?? throw new ArgumentNullException(nameof(repoConfigReader)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } public IEnumerable GetTags(Repository repository) @@ -297,23 +299,6 @@ public IEnumerable GetTags(Repository repository) private IEnumerable GetTagsInner(IRepository repository) { - List EvaluateVariables(IEnumerable? vars) - { - if (vars == null) - { - return new List(0); - } - - return vars - .Where(v => IsEnabled(v.Enabled, true, repository)) - .Select(v => new EvaluatedVariable - { - Name = v.Name, - Value = Evaluate(v.Value, repository), - }) - .ToList(); - } - Dictionary? repositoryEnvVars; List? variables; List? tags; @@ -322,10 +307,10 @@ List EvaluateVariables(IEnumerable? vars) { (repositoryEnvVars, variables, _, tags) = _repoConfigReader.Get(repository); } - catch (Exception) + catch (Exception e) { - // todo, log - yield break; + _logger.LogError(e, "Could not get the configuration for repository {repository} {message}.", repository.Name, e.Message); + yield break; } using IDisposable d1 = RepoMVariableProviderStore.Push(variables ?? new List(0)); @@ -333,7 +318,7 @@ List EvaluateVariables(IEnumerable? vars) foreach (TagsCollection tagsCollection in ((IEnumerable?)tags) ?? Array.Empty()) { - using IDisposable d3 = RepoMVariableProviderStore.Push(EvaluateVariables(tagsCollection.Variables)); + using IDisposable d3 = RepoMVariableProviderStore.Push(EvaluateVariables(tagsCollection.Variables, repository)); foreach (RepositoryActionTag action in tagsCollection.Tags) { @@ -350,6 +335,23 @@ List EvaluateVariables(IEnumerable? vars) } } + private List EvaluateVariables(IEnumerable? vars, IRepository repository) + { + if (vars == null) + { + return new List(0); + } + + return vars + .Where(v => IsEnabled(v.Enabled, true, repository)) + .Select(v => new EvaluatedVariable + { + Name = v.Name, + Value = Evaluate(v.Value, repository), + }) + .ToList(); + } + private object? Evaluate(object? input, IRepository repository) { if (input is string s) diff --git a/src/RepoM.Api/IO/ProcessHelper.cs b/src/RepoM.Api/IO/ProcessHelper.cs index 1a188b6a..5cf0550c 100644 --- a/src/RepoM.Api/IO/ProcessHelper.cs +++ b/src/RepoM.Api/IO/ProcessHelper.cs @@ -9,7 +9,6 @@ public static void StartProcess(string process, string arguments) { try { - Debug.WriteLine("Starting: " + process + arguments); Process.Start(process, arguments); return; } diff --git a/src/RepoM.Api/RepositoryActions/Executors/BrowseActionExecutor.cs b/src/RepoM.Api/RepositoryActions/Executors/BrowseActionExecutor.cs deleted file mode 100644 index f7a31326..00000000 --- a/src/RepoM.Api/RepositoryActions/Executors/BrowseActionExecutor.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace RepoM.Api.RepositoryActions.Executors; - -using System; -using JetBrains.Annotations; -using RepoM.Core.Plugin.Repository; -using RepoM.Core.Plugin.RepositoryActions; -using RepoM.Core.Plugin.RepositoryActions.Actions; - -[UsedImplicitly] -public class BrowseActionExecutor : IActionExecutor -{ - public void Execute(IRepository repository, BrowseAction action) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/src/RepoM.App/Bootstrapper.cs b/src/RepoM.App/Bootstrapper.cs index 1590cd82..4a545c1d 100644 --- a/src/RepoM.App/Bootstrapper.cs +++ b/src/RepoM.App/Bootstrapper.cs @@ -181,7 +181,7 @@ static IEnumerable GetExportedTypesFrom(Assembly assembly) Container.Register, SumRepositoryComparerFactory>(Lifestyle.Singleton); Container.RegisterSingleton(); - Container.Register(typeof(IActionExecutor<>), new[] { typeof(BrowseActionExecutor).Assembly, }, Lifestyle.Singleton); + Container.Register(typeof(IActionExecutor<>), new[] { typeof(DelegateActionExecutor).Assembly, }, Lifestyle.Singleton); Container.RegisterDecorator( typeof(IActionExecutor<>), typeof(LoggerActionExecutorDecorator<>), diff --git a/src/RepoM.App/RepoM.App.csproj b/src/RepoM.App/RepoM.App.csproj index 977e013d..19677793 100644 --- a/src/RepoM.App/RepoM.App.csproj +++ b/src/RepoM.App/RepoM.App.csproj @@ -29,6 +29,7 @@ + diff --git a/src/RepoM.Core.Plugin/RepositoryActions/Actions/BrowseAction.cs b/src/RepoM.Core.Plugin/RepositoryActions/Actions/BrowseAction.cs deleted file mode 100644 index 48920f0c..00000000 --- a/src/RepoM.Core.Plugin/RepositoryActions/Actions/BrowseAction.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace RepoM.Core.Plugin.RepositoryActions.Actions; - -using RepoM.Core.Plugin.RepositoryActions; - -public sealed class BrowseAction : IAction -{ -} \ No newline at end of file diff --git a/src/RepoM.Plugin.Clipboard/ClipboardPackage.cs b/src/RepoM.Plugin.Clipboard/ClipboardPackage.cs index 5f4b0b78..50eede7e 100644 --- a/src/RepoM.Plugin.Clipboard/ClipboardPackage.cs +++ b/src/RepoM.Plugin.Clipboard/ClipboardPackage.cs @@ -26,7 +26,6 @@ private static void RegisterPluginHooks(Container container) { // repository actions container.RegisterDefaultRepositoryActionDeserializerForType(); - // container.Collection.Append(Lifestyle.Singleton); container.Collection.Append(Lifestyle.Singleton); // ordering diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs b/src/RepoM.Plugin.WebBrowser/ActionProvider/ActionBrowserV1Mapper.cs similarity index 61% rename from src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs rename to src/RepoM.Plugin.WebBrowser/ActionProvider/ActionBrowserV1Mapper.cs index c56da6bb..b823ca97 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/ActionMappers/ActionBrowserV1Mapper.cs +++ b/src/RepoM.Plugin.WebBrowser/ActionProvider/ActionBrowserV1Mapper.cs @@ -1,15 +1,19 @@ -namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; +namespace RepoM.Plugin.WebBrowser.ActionProvider; using System; using System.Collections.Generic; +using JetBrains.Annotations; using RepoM.Api.Git; -using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionMappers; using RepoM.Api.RepositoryActions; using RepoM.Core.Plugin.Expressions; -using RepoM.Core.Plugin.RepositoryActions.Actions; +using RepoM.Core.Plugin.Repository; +using RepoM.Plugin.WebBrowser.RepositoryActions.Actions; using RepositoryAction = RepoM.Api.RepositoryActions.RepositoryAction; -public class ActionBrowserV1Mapper : IActionToRepositoryActionMapper +[UsedImplicitly] +internal class ActionBrowserV1Mapper : IActionToRepositoryActionMapper { private readonly IRepositoryExpressionEvaluator _expressionEvaluator; @@ -18,17 +22,17 @@ public ActionBrowserV1Mapper(IRepositoryExpressionEvaluator expressionEvaluator) _expressionEvaluator = expressionEvaluator ?? throw new ArgumentNullException(nameof(expressionEvaluator)); } - bool IActionToRepositoryActionMapper.CanMap(Data.RepositoryAction action) + bool IActionToRepositoryActionMapper.CanMap(Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction action) { return action is RepositoryActionBrowserV1; } - IEnumerable IActionToRepositoryActionMapper.Map(Data.RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) + IEnumerable IActionToRepositoryActionMapper.Map(Api.IO.ModuleBasedRepositoryActionProvider.Data.RepositoryAction action, Repository repository, ActionMapperComposition actionMapperComposition) { return Map(action as RepositoryActionBrowserV1, repository); } - private IEnumerable Map(RepositoryActionBrowserV1? action, Repository repository) + private IEnumerable Map(RepositoryActionBrowserV1? action, IRepository repository) { if (action == null) { @@ -47,9 +51,11 @@ private IEnumerable Map(RepositoryActionBrowserV1? action, Rep var name = _expressionEvaluator.EvaluateNullStringExpression(action.Name, repository); var url = _expressionEvaluator.EvaluateStringExpression(action.Url, repository); + var profile = _expressionEvaluator.EvaluateNullStringExpression(action.Profile, repository); + yield return new RepositoryAction(name, repository) { - Action = new DelegateAction((_, _) => ProcessHelper.StartProcess(url, string.Empty)), + Action = new BrowseAction(url, profile), }; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionBrowserV1.cs b/src/RepoM.Plugin.WebBrowser/ActionProvider/RepositoryActionBrowserV1.cs similarity index 62% rename from src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionBrowserV1.cs rename to src/RepoM.Plugin.WebBrowser/ActionProvider/RepositoryActionBrowserV1.cs index b05310bb..95f110a9 100644 --- a/src/RepoM.Api/IO/ModuleBasedRepositoryActionProvider/Data/Actions/RepositoryActionBrowserV1.cs +++ b/src/RepoM.Plugin.WebBrowser/ActionProvider/RepositoryActionBrowserV1.cs @@ -1,6 +1,7 @@ -namespace RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; +namespace RepoM.Plugin.WebBrowser.ActionProvider; using System.ComponentModel.DataAnnotations; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; /// /// Action opening a webbrowser with the provided url. @@ -21,4 +22,12 @@ public sealed class RepositoryActionBrowserV1 : RepositoryAction [Required] [PropertyType(typeof(string))] public string? Url { get; set; } + + + /// + /// profile name used to select browser and browser profile + /// + [EvaluatedProperty] + [PropertyType(typeof(string))] + public string? Profile { get; set; } } \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/CurrentVersion.cs b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/CurrentVersion.cs new file mode 100644 index 00000000..d72390b4 --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/CurrentVersion.cs @@ -0,0 +1,6 @@ +namespace RepoM.Plugin.WebBrowser.PersistentConfiguration; + +internal static class CurrentConfigVersion +{ + public const int VERSION = 1; +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/StatisticsConfigV1.cs b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/StatisticsConfigV1.cs new file mode 100644 index 00000000..79b5367f --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/StatisticsConfigV1.cs @@ -0,0 +1,14 @@ +namespace RepoM.Plugin.WebBrowser.PersistentConfiguration; + +public class ProfileConfig +{ + /// + /// Name of the browser. Should be listed in the Browsers dictionary. + /// + public string? BrowserName { get; set; } + + /// + /// Command line arguments + /// + public string? CommandLineArguments { get; set; } +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs new file mode 100644 index 00000000..4946b7df --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs @@ -0,0 +1,18 @@ +namespace RepoM.Plugin.WebBrowser.PersistentConfiguration; + +using System.Collections.Generic; + +/// DO NOT CHANGE PROPERTYNAMES, TYPES, or VISIBILITIES +/// Module configuration (version 1) +public class WebBrowserConfigV1 +{ + /// + /// Dictionary of known browsers and their path to use for opening urls. + /// + public Dictionary? Browsers { get; set; } = new(); + + /// + /// Profiles to use. + /// + public Dictionary? Profiles { get; set; } = new(); +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/PluginInformation.cs b/src/RepoM.Plugin.WebBrowser/PluginInformation.cs new file mode 100644 index 00000000..62f5a308 --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/PluginInformation.cs @@ -0,0 +1,5 @@ +using RepoM.Core.Plugin.AssemblyInformation; + +[assembly: Package( + "WebBrowser", + "Provides functionality to start a web browser from an action with profile information.")] \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/RepoM.Plugin.WebBrowser.csproj b/src/RepoM.Plugin.WebBrowser/RepoM.Plugin.WebBrowser.csproj new file mode 100644 index 00000000..6f096259 --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/RepoM.Plugin.WebBrowser.csproj @@ -0,0 +1,22 @@ + + + + net7.0 + + + + + + + + + + + + + + + + + + diff --git a/src/RepoM.Plugin.WebBrowser/RepositoryActions/Actions/BrowseAction.cs b/src/RepoM.Plugin.WebBrowser/RepositoryActions/Actions/BrowseAction.cs new file mode 100644 index 00000000..417dfa82 --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/RepositoryActions/Actions/BrowseAction.cs @@ -0,0 +1,16 @@ +namespace RepoM.Plugin.WebBrowser.RepositoryActions.Actions; + +using RepoM.Core.Plugin.RepositoryActions; + +public sealed class BrowseAction : IAction +{ + public BrowseAction(string url, string? profileName) + { + Url = url; + ProfileName = profileName; + } + + public string Url { get; } + + public string? ProfileName { get; } +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/RepositoryActions/BrowseActionExecutor.cs b/src/RepoM.Plugin.WebBrowser/RepositoryActions/BrowseActionExecutor.cs new file mode 100644 index 00000000..0473bfe2 --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/RepositoryActions/BrowseActionExecutor.cs @@ -0,0 +1,31 @@ +namespace RepoM.Plugin.WebBrowser.RepositoryActions; + +using System; +using JetBrains.Annotations; +using RepoM.Core.Plugin.Repository; +using RepoM.Core.Plugin.RepositoryActions; +using RepoM.Plugin.WebBrowser.RepositoryActions.Actions; +using RepoM.Plugin.WebBrowser.Services; + +[UsedImplicitly] +internal class BrowseActionExecutor : IActionExecutor +{ + private readonly IWebBrowserService _webBrowserService; + + public BrowseActionExecutor(IWebBrowserService webBrowserService) + { + _webBrowserService = webBrowserService ?? throw new ArgumentNullException(nameof(webBrowserService)); + } + + public void Execute(IRepository repository, BrowseAction action) + { + if (action.ProfileName == null) + { + _webBrowserService.OpenUrl(action.Url); + } + else + { + _webBrowserService.OpenUrl(action.Url, action.ProfileName); + } + } +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs b/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs new file mode 100644 index 00000000..1e68fe2e --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs @@ -0,0 +1,10 @@ +namespace RepoM.Plugin.WebBrowser.Services; + +internal interface IWebBrowserService +{ + bool ProfileExist(string name); + + void OpenUrl(string url); + + void OpenUrl(string url, string profile); +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs new file mode 100644 index 00000000..eb9c10cb --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs @@ -0,0 +1,17 @@ +namespace RepoM.Plugin.WebBrowser.Services; + +using System.Collections.Generic; + +internal class WebBrowserConfiguration +{ + public Dictionary Browsers { get; init; } + + public Dictionary Profiles { get; init; } +} + +internal class BrowserProfileConfig +{ + public string? BrowserName { get; set; } + + public string? CommandLineArguments { get; set; } +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs new file mode 100644 index 00000000..f38951ad --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs @@ -0,0 +1,59 @@ +namespace RepoM.Plugin.WebBrowser.Services; + +using System; +using RepoM.Api.IO; + +internal class WebBrowserService : IWebBrowserService +{ + private readonly WebBrowserConfiguration _configuration; + + public WebBrowserService(WebBrowserConfiguration configuration) + { + _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + } + + public bool ProfileExist(string name) + { + return _configuration.Profiles.ContainsKey(name); + } + + public void OpenUrl(string url) + { + ProcessHelper.StartProcess(url, string.Empty); + } + + public void OpenUrl(string url, string profile) + { + + if (!_configuration.Profiles.TryGetValue(profile, out BrowserProfileConfig? profileConfig)) + { + OpenUrl(url); + return; + } + + if (!_configuration.Browsers.TryGetValue(profileConfig.BrowserName!, out string? browser)) + { + OpenUrl(url); + return; + } + + + if (string.IsNullOrWhiteSpace(profileConfig.CommandLineArguments)) + { + ProcessHelper.StartProcess(browser, url); + return; + } + + var commandLinesArgs = profileConfig.CommandLineArguments; + if (commandLinesArgs.Contains("{url}")) + { + commandLinesArgs = commandLinesArgs.Replace("{url}", url); + } + else + { + commandLinesArgs += " " + url; + } + + ProcessHelper.StartProcess(browser, commandLinesArgs); + } +} \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs b/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs new file mode 100644 index 00000000..f4fca63d --- /dev/null +++ b/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs @@ -0,0 +1,92 @@ +namespace RepoM.Plugin.WebBrowser; + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using JetBrains.Annotations; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; +using RepoM.Core.Plugin; +using RepoM.Core.Plugin.RepositoryActions; +using RepoM.Plugin.WebBrowser.ActionProvider; +using RepoM.Plugin.WebBrowser.PersistentConfiguration; +using RepoM.Plugin.WebBrowser.Services; +using SimpleInjector; + +[UsedImplicitly] +public class WebBrowserPackage : IPackage +{ + public string Name => "WebBrowserPackage"; // do not change this name, it is part of the persistant filename + + public async Task RegisterServicesAsync(Container container, IPackageConfiguration packageConfiguration) + { + await ExtractAndRegisterConfiguration(container, packageConfiguration).ConfigureAwait(false); + RegisterPluginHooks(container); + RegisterInternals(container); + } + + private static async Task ExtractAndRegisterConfiguration(Container container, IPackageConfiguration packageConfiguration) + { + var version = await packageConfiguration.GetConfigurationVersionAsync().ConfigureAwait(false); + + WebBrowserConfigV1 config; + + if (version == CurrentConfigVersion.VERSION) + { + WebBrowserConfigV1? result = await packageConfiguration.LoadConfigurationAsync().ConfigureAwait(false); + if (result == null) + { + config = await PersistDefaultConfigAsync(packageConfiguration).ConfigureAwait(false); + } + else + { + config = result; + } + } + else + { + config = await PersistDefaultConfigAsync(packageConfiguration).ConfigureAwait(false); + } + + container.RegisterInstance( + new WebBrowserConfiguration + { + Browsers = config.Browsers?.ToDictionary(x => x.Key, x => x.Value) ?? new Dictionary(0), + Profiles = config.Profiles?.ToDictionary( + x => x.Key, + x => new BrowserProfileConfig + { + BrowserName = x.Value.BrowserName, + CommandLineArguments = x.Value.CommandLineArguments, + }) ?? new Dictionary(0), + }); + } + + private static void RegisterPluginHooks(Container container) + { + // repository actions + container.RegisterDefaultRepositoryActionDeserializerForType(); + container.Collection.Append(Lifestyle.Singleton); + + // action executor + container.Register(typeof(IActionExecutor<>), new[] { typeof(WebBrowserPackage).Assembly, }, Lifestyle.Singleton); + } + + private static void RegisterInternals(Container container) + { + container.Register(Lifestyle.Singleton); + } + + /// This method is used by reflection to generate documentation file> + private static async Task PersistDefaultConfigAsync(IPackageConfiguration packageConfiguration) + { + var config = new WebBrowserConfigV1 + { + Browsers = new Dictionary(), + Profiles = new Dictionary(), + }; + + await packageConfiguration.PersistConfigurationAsync(config, CurrentConfigVersion.VERSION).ConfigureAwait(false); + return config; + } +} \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/DynamicRepositoryActionDeserializerFactory.cs b/tests/RepoM.Api.Tests/DynamicRepositoryActionDeserializerFactory.cs index 403e4e69..c4f07cf1 100644 --- a/tests/RepoM.Api.Tests/DynamicRepositoryActionDeserializerFactory.cs +++ b/tests/RepoM.Api.Tests/DynamicRepositoryActionDeserializerFactory.cs @@ -28,7 +28,6 @@ private static ActionDeserializerComposition CreateActionDeserializerComposition { new ActionExecutableV1Deserializer(), new DefaultActionDeserializer(), - new DefaultActionDeserializer(), new ActionFolderV1Deserializer(), new DefaultActionDeserializer(), new DefaultActionDeserializer(), diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/CommandV1Test.Deserialize_CommandV1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/CommandV1Test.Deserialize_CommandV1.testfile.yaml index 96996882..566d49fd 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/CommandV1Test.Deserialize_CommandV1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/CommandV1Test.Deserialize_CommandV1.testfile.yaml @@ -1,11 +1,11 @@ repository-actions: actions: - type: command@1 - name: '{OpenIn} Windows Terminal' + name: 'Open in Windows Terminal' command: wt arguments: -d "{Repository.SafePath}" - type: command@1 - name: '{OpenIn} Windows Command Shell' + name: 'Open in Windows Command Shell' command: cmd arguments: /K "cd /d {Repository.SafePath}" active: false diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ExecutableV1Test.Deserialize_ExecutableV1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ExecutableV1Test.Deserialize_ExecutableV1.testfile.yaml index 7a7efb81..86b437ec 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ExecutableV1Test.Deserialize_ExecutableV1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ExecutableV1Test.Deserialize_ExecutableV1.testfile.yaml @@ -1,21 +1,21 @@ repository-actions: actions: - type: executable@1 - name: '{OpenIn} Sourcetree' + name: 'Open in Sourcetree' executables: - '%LocalAppData%/SourceTree/SourceTree.exe' - '%PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe' arguments: -f "{Repository.Location}{backslash}{Repository.Name}" active: true - type: executable@1 - name: '{OpenIn} Sourcetree 1' + name: 'Open in Sourcetree 1' executable: '%PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe' - type: executable@1 - name: '{OpenIn} Sourcetree 1.1' + name: 'Open in Sourcetree 1.1' executables: [] executable: '%PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe' - type: executable@1 - name: '{OpenIn} Sourcetree 2' + name: 'Open in Sourcetree 2' executables: - '%LocalAppData%/SourceTree/SourceTree.exe' - '%PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe' diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ForEachV1Test.Deserialize_ForEachV1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ForEachV1Test.Deserialize_ForEachV1.testfile.yaml index 7d9c1c76..ce86792b 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ForEachV1Test.Deserialize_ForEachV1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/ForEachV1Test.Deserialize_ForEachV1.testfile.yaml @@ -4,6 +4,5 @@ repository-actions: enumerable: '{var.DTAP}' variable: environment actions: - - type: browser@1 - name: '{var.environment}' - url: '{var.url}' + - type: just-text@1 + name: '{var.environment} {var.url}' diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/CommandV1Test.Deserialize_CommandV1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/CommandV1Test.Deserialize_CommandV1.verified.txt index 56d90fa1..a714a566 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/CommandV1Test.Deserialize_CommandV1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/CommandV1Test.Deserialize_CommandV1.verified.txt @@ -7,14 +7,14 @@ Command: wt, Arguments: -d "{Repository.SafePath}", Type: command@1, - Name: {OpenIn} Windows Terminal + Name: Open in Windows Terminal }, { $type: RepositoryActionCommandV1, Command: cmd, Arguments: /K "cd /d {Repository.SafePath}", Type: command@1, - Name: {OpenIn} Windows Command Shell, + Name: Open in Windows Command Shell, Active: false } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/ExecutableV1Test.Deserialize_ExecutableV1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/ExecutableV1Test.Deserialize_ExecutableV1.verified.txt index 7b477bf8..aab8d9fa 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/ExecutableV1Test.Deserialize_ExecutableV1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/ExecutableV1Test.Deserialize_ExecutableV1.verified.txt @@ -10,7 +10,7 @@ ], Arguments: -f "{Repository.Location}{backslash}{Repository.Name}", Type: executable@1, - Name: {OpenIn} Sourcetree, + Name: Open in Sourcetree, Active: true }, { @@ -19,7 +19,7 @@ %PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe ], Type: executable@1, - Name: {OpenIn} Sourcetree 1 + Name: Open in Sourcetree 1 }, { $type: RepositoryActionExecutableV1, @@ -27,7 +27,7 @@ %PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe ], Type: executable@1, - Name: {OpenIn} Sourcetree 1.1 + Name: Open in Sourcetree 1.1 }, { $type: RepositoryActionExecutableV1, @@ -36,7 +36,7 @@ %PROGRAMFILES(X86)%/Atlassian/SourceTree/SourceTree.exe ], Type: executable@1, - Name: {OpenIn} Sourcetree 2 + Name: Open in Sourcetree 2 } ] } diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMapperCompositionFactory.cs b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMapperCompositionFactory.cs index cb172580..3992931c 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMapperCompositionFactory.cs +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/ActionMapperCompositionFactory.cs @@ -19,7 +19,6 @@ public static ActionMapperComposition Create( var mappers = new IActionToRepositoryActionMapper[] { new ActionBrowseRepositoryV1Mapper(expressionEvaluator, translationService), - new ActionBrowserV1Mapper(expressionEvaluator), new ActionCommandV1Mapper(expressionEvaluator), new ActionExecutableV1Mapper(expressionEvaluator, fileSystem), new ActionFolderV1Mapper(expressionEvaluator), diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Foreach01.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Foreach01.testfile.yaml index f5f504ea..e3fb37d4 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Foreach01.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Foreach01.testfile.yaml @@ -20,8 +20,7 @@ repository-actions: variable: environment skip: '' actions: - - type: browser@1 - name: '{var.environment.key}' - url: '{var.environment.url}' + - type: just-text@1 + name: '{var.environment.key} - {var.environment.url}' # end-snippet \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Foreach01.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Foreach01.verified.txt index d4fc8dc2..4b34671b 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Foreach01.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Foreach01.verified.txt @@ -39,10 +39,9 @@ Skip: , Actions: [ { - $type: RepositoryActionBrowserV1, - Url: {var.environment.url}, - Type: browser@1, - Name: {var.environment.key} + $type: RepositoryActionJustTextV1, + Type: just-text@1, + Name: {var.environment.key} - {var.environment.url} } ], Type: foreach@1 diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationTests.cs b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationTests.cs index 3f53509e..280cb08d 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationTests.cs +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationTests.cs @@ -38,7 +38,6 @@ public DocumentationTests() [InlineData("GitPush01")] [InlineData("BrowseRepository01")] [InlineData("Separator01")] - [InlineData("Browser01")] [InlineData("Folder01")] [InlineData("AssociateFile01")] [InlineData("Command01")] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfigurationTest.cs b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfigurationTest.cs index 167ba882..2e84a50b 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfigurationTest.cs +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/RepositorySpecificConfigurationTest.cs @@ -4,6 +4,7 @@ namespace RepoM.Api.Tests.IO.ModuleBasedRepositoryActionProvider; using System.Collections.Generic; using System.IO; using System.IO.Abstractions.TestingHelpers; +using System.Linq; using System.Runtime.Caching; using System.Text; using System.Threading.Tasks; diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach1.testfile.yaml index f91b6d89..20ffaa19 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach1.testfile.yaml @@ -16,6 +16,5 @@ repository-actions: enumerable: '{var.DTAP}' variable: environment actions: - - type: browser@1 - name: '{var.environment.key}' - url: '{var.environment.url}' \ No newline at end of file + - type: just-text@1 + name: '{var.key} - {var.environment.url}' \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach2.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach2.testfile.yaml index 6c603714..30a62afb 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach2.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach2.testfile.yaml @@ -15,6 +15,5 @@ repository-actions: enumerable: '{var.DTAP}' variable: environment actions: - - type: browser@1 - name: '{var.environment.key}' - url: '{var.environment.url}' \ No newline at end of file + - type: just-text@1 + name: '{var.key} - {var.environment.url}' \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach3.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach3.testfile.yaml index 2377e227..118b3618 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach3.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/ForEach3.testfile.yaml @@ -16,6 +16,5 @@ repository-actions: variable: environment skip: '{IsNull({var.environment.x})}' actions: - - type: browser@1 - name: '{var.environment.key}' - url: '{var.environment.url}' \ No newline at end of file + - type: just-text@1 + name: '{var.key} - {var.environment.url}' \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions1.testfile.yaml index a3707bc2..4c48d6f9 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions1.testfile.yaml @@ -1,10 +1,10 @@ repository-actions: -- type: browser@1 - name: '{OpenIn} Windows File Explorer' +- type: command@1 + name: 'Open in Windows File Explorer' active: false variables: - name: name value: '{StringContains({Repository.SafePath}, "abc")}' -- type: browser@1 - name: '{OpenIn} Windows File Explorer' +- type: command@1 + name: 'Open in Windows File Explorer' active: false \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions2.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions2.testfile.yaml index da1b7144..4acd8cb4 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions2.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions2.testfile.yaml @@ -1,11 +1,11 @@ repository-actions: actions: - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false variables: - name: name value: '{StringContains({Repository.SafePath}, "abc")}' - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions3.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions3.testfile.yaml index fe359830..f99bb999 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions3.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActions3.testfile.yaml @@ -7,13 +7,12 @@ repository-actions: value: true enabled: false actions: - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false variables: - name: name value: '{StringContains({Repository.SafePath}, "abc")}' - url: https://google.com - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActionsWithSeparator1.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActionsWithSeparator1.testfile.yaml index 72865cbb..6ea61fdb 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActionsWithSeparator1.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/RepositoryActionsWithSeparator1.testfile.yaml @@ -1,8 +1,9 @@ repository-actions: -- type: browser@1 - name: Google 1 - url: https://google.com +- type: just-text@1 + name: 'Open in Windows File Explorer' + active: true + - type: separator@1 -- type: browser@1 - name: Google 2 - url: https://google.com \ No newline at end of file + +- type: just-text@1 + name: 'Open in Windows File Explorer 2' \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample2.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample2.testfile.yaml index 3983ec0a..c3880ed4 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample2.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample2.testfile.yaml @@ -36,12 +36,12 @@ repository-actions: value: true enabled: false actions: - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false variables: - name: name value: '{StringContains({Repository.SafePath}, "abc")}' - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample3.testfile.yaml b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample3.testfile.yaml index c862f665..e06dafc7 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample3.testfile.yaml +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/TestFiles/Sample3.testfile.yaml @@ -45,12 +45,12 @@ repository-actions: value: true enabled: false actions: - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false variables: - name: name value: '{StringContains({Repository.SafePath}, "abc")}' - - type: browser@1 - name: '{OpenIn} Windows File Explorer' + - type: command@1 + name: 'Open in Windows File Explorer' active: false diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach1.verified.txt index 8ae10178..3cd3cfab 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach1.verified.txt @@ -38,10 +38,9 @@ Variable: environment, Actions: [ { - $type: RepositoryActionBrowserV1, - Url: {var.environment.url}, - Type: browser@1, - Name: {var.environment.key} + $type: RepositoryActionJustTextV1, + Type: just-text@1, + Name: {var.key} - {var.environment.url} } ], Type: foreach@1 diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach2.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach2.verified.txt index 3a4edbae..96b2b9f8 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach2.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach2.verified.txt @@ -38,10 +38,9 @@ Variable: environment, Actions: [ { - $type: RepositoryActionBrowserV1, - Url: {var.environment.url}, - Type: browser@1, - Name: {var.environment.key} + $type: RepositoryActionJustTextV1, + Type: just-text@1, + Name: {var.key} - {var.environment.url} } ], Type: foreach@1 diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach3.verified.txt index 601cccad..bf465427 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ForEach3.verified.txt @@ -39,10 +39,9 @@ Skip: {IsNull({var.environment.x})}, Actions: [ { - $type: RepositoryActionBrowserV1, - Url: {var.environment.url}, - Type: browser@1, - Name: {var.environment.key} + $type: RepositoryActionJustTextV1, + Type: just-text@1, + Name: {var.key} - {var.environment.url} } ], Type: foreach@1 diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt index 0036fa21..bdeb29eb 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample2.verified.txt @@ -66,9 +66,9 @@ ], Actions: [ { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false, Variables: [ { @@ -78,9 +78,9 @@ ] }, { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt index ffe78fed..43963572 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_Sample3.verified.txt @@ -84,9 +84,9 @@ ], Actions: [ { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false, Variables: [ { @@ -96,9 +96,9 @@ ] }, { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt index 9277d29c..ee7c2c9a 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions1.verified.txt @@ -3,9 +3,9 @@ ActionsCollection: { Actions: [ { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false, Variables: [ { @@ -15,9 +15,9 @@ ] }, { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false } ] diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt index 32d94bfb..5feb71e1 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt +++ b/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Verified/DynamicRepositoryActionDeserializerTest.Deserialize_ShouldReturnObjectWithRepositoryActions_WhenContentIsRepositoryActions3.verified.txt @@ -15,10 +15,9 @@ ], Actions: [ { - $type: RepositoryActionBrowserV1, - Url: https://google.com, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false, Variables: [ { @@ -28,9 +27,9 @@ ] }, { - $type: RepositoryActionBrowserV1, - Type: browser@1, - Name: {OpenIn} Windows File Explorer, + $type: RepositoryActionCommandV1, + Type: command@1, + Name: Open in Windows File Explorer, Active: false } ] 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 1fe689a1..e840496e 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 @@ -1,14 +1,9 @@ [ { $type: RepositoryAction, - Name: Google 1, + Name: Open in Windows File Explorer, Action: { - $type: DelegateAction, - Action: { - Type: Action, - Target: ActionBrowserV1Mapper.<>c__DisplayClass4_0, - Method: Void Map(System.Object, System.Object) - } + $type: NullAction }, ExecutionCausesSynchronizing: false, CanExecute: true @@ -23,14 +18,9 @@ }, { $type: RepositoryAction, - Name: Google 2, + Name: Open in Windows File Explorer 2, Action: { - $type: DelegateAction, - Action: { - Type: Action, - Target: ActionBrowserV1Mapper.<>c__DisplayClass4_0, - Method: Void Map(System.Object, System.Object) - } + $type: NullAction }, ExecutionCausesSynchronizing: false, CanExecute: true diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md new file mode 100644 index 00000000..f0a324e2 --- /dev/null +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md @@ -0,0 +1,20 @@ +## Configuration + +This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. + +The following default configuration is used: + +```json +{ + "Version": 1, + "Settings": { + "Browsers": {}, + "Profiles": {} + } +} +``` + +Properties: + +- `Browsers`: Dictionary of known browsers and their path to use for opening urls. +- `Profiles`: Profiles to use. diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json new file mode 100644 index 00000000..1fcd3075 --- /dev/null +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json @@ -0,0 +1,7 @@ +{ + "Version": 1, + "Settings": { + "Browsers": {}, + "Profiles": {} + } +} \ No newline at end of file diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt index 2552127b..49a39cd7 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt @@ -17,5 +17,8 @@ PersistenceBuffer: 00:05:00, RetentionDays: 30 }, + WebBrowserPackage: { + $type: WebBrowserConfigV1 + }, WindowsExplorerGitInfoPackage: null } \ No newline at end of file diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md b/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md index 20a27168..935dae51 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.DocsRepositoryActionsSettings_RepositoryActionBrowserV1.verified.md @@ -3,3 +3,4 @@ Action specific properties: - `url`: The url to browse to. (required, evaluated, string) +- `profile`: profile name used to select browser and browser profile (optional, evaluated, string) diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.VerifyChanges.verified.txt b/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.VerifyChanges.verified.txt index 5daa5e1f..395138f9 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.VerifyChanges.verified.txt +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/RepositoryActionsDocs/DocsRepositoryActionsTests.VerifyChanges.verified.txt @@ -3,7 +3,6 @@ RepositoryAction, RepositoryActionAssociateFileV1, RepositoryActionBrowseRepositoryV1, - RepositoryActionBrowserV1, RepositoryActionCommandV1, RepositoryActionExecutableV1, RepositoryActionFolderV1, @@ -29,5 +28,8 @@ ], RepoM.Plugin.SonarCloud: [ RepositoryActionSonarCloudSetFavoriteV1 + ], + RepoM.Plugin.WebBrowser: [ + RepositoryActionBrowserV1 ] } \ No newline at end of file diff --git a/tests/RepoM.Plugin.Misc.Tests/PluginStore.cs b/tests/RepoM.Plugin.Misc.Tests/PluginStore.cs index 42a6f90f..8feeb26e 100644 --- a/tests/RepoM.Plugin.Misc.Tests/PluginStore.cs +++ b/tests/RepoM.Plugin.Misc.Tests/PluginStore.cs @@ -11,6 +11,7 @@ namespace RepoM.Plugin.Misc.Tests; using RepoM.Plugin.LuceneQueryParser; using RepoM.Plugin.SonarCloud; using RepoM.Plugin.Statistics; +using RepoM.Plugin.WebBrowser; using RepoM.Plugin.WindowsExplorerGitInfo; internal static class PluginStore @@ -27,6 +28,7 @@ public static IEnumerable Packages yield return new SonarCloudPackage(); yield return new StatisticsPackage(); yield return new WindowsExplorerGitInfoPackage(); + yield return new WebBrowserPackage(); } } 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 5852eff4..791cf277 100644 --- a/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj +++ b/tests/RepoM.Plugin.Misc.Tests/RepoM.Plugin.Misc.Tests.csproj @@ -47,6 +47,7 @@ + diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/BrowserV1Test.cs b/tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/BrowserV1Test.cs similarity index 74% rename from tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/BrowserV1Test.cs rename to tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/BrowserV1Test.cs index 4134af7c..0c0f3a28 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/BrowserV1Test.cs +++ b/tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/BrowserV1Test.cs @@ -1,12 +1,15 @@ -namespace RepoM.Api.Tests.IO.ModuleBasedRepositoryActionProvider.Action; +namespace RepoM.Plugin.WebBrowser.Tests.ActionProvider; +using System; using System.Threading.Tasks; using EasyTestFile; using EasyTestFileXunit; using FluentAssertions; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionDeserializers; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; -using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data.Actions; using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Deserialization; +using RepoM.Core.Plugin.RepositoryOrdering.Configuration; +using RepoM.Plugin.WebBrowser.ActionProvider; using VerifyTests; using VerifyXunit; using Xunit; @@ -21,7 +24,8 @@ public class BrowserV1Test public BrowserV1Test() { - _sut = DynamicRepositoryActionDeserializerFactory.CreateWithDeserializer(new DefaultActionDeserializer()); + var actionDeserializerComposition = new ActionDeserializerComposition(new[] { new DefaultActionDeserializer(), }, Array.Empty>()); + _sut = new YamlDynamicRepositoryActionDeserializer(actionDeserializerComposition); _testFileSettings = new EasyTestFileSettings(); _testFileSettings.UseDirectory("TestFiles"); diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/BrowserV1Test.Deserialize_ActionBrowserV1.testfile.yaml b/tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/TestFiles/BrowserV1Test.Deserialize_ActionBrowserV1.testfile.yaml similarity index 100% rename from tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/TestFiles/BrowserV1Test.Deserialize_ActionBrowserV1.testfile.yaml rename to tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/TestFiles/BrowserV1Test.Deserialize_ActionBrowserV1.testfile.yaml diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/BrowserV1Test.Deserialize_ActionBrowserV1.verified.txt b/tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/Verified/BrowserV1Test.Deserialize_ActionBrowserV1.verified.txt similarity index 100% rename from tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/Action/Verified/BrowserV1Test.Deserialize_ActionBrowserV1.verified.txt rename to tests/RepoM.Plugin.WebBrowser.Tests/ActionProvider/Verified/BrowserV1Test.Deserialize_ActionBrowserV1.verified.txt diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Browser01.testfile.yaml b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml similarity index 94% rename from tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Browser01.testfile.yaml rename to tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml index defd0474..351f5e77 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFiles/Browser01.testfile.yaml +++ b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml @@ -13,5 +13,6 @@ repository-actions: - type: browser@1 name: 'My Github' url: 'https://github.com/coenm' + profile: edge # end-snippet \ No newline at end of file diff --git a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt similarity index 94% rename from tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt rename to tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt index 52d84955..f57ff865 100644 --- a/tests/RepoM.Api.Tests/IO/ModuleBasedRepositoryActionProvider/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt +++ b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFilesVerified/DocumentationTests.Deserialize_Documentation_Browser01.verified.txt @@ -12,6 +12,7 @@ { $type: RepositoryActionBrowserV1, Url: https://github.com/coenm, + Profile: edge, Type: browser@1, Name: My Github } diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationTests.cs b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationTests.cs new file mode 100644 index 00000000..6d8bc92d --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationTests.cs @@ -0,0 +1,47 @@ +namespace RepoM.Plugin.WebBrowser.Tests; + +using System.Threading.Tasks; +using EasyTestFile; +using EasyTestFileXunit; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Deserialization; +using RepoM.Plugin.WebBrowser.Tests.TestFramework; +using VerifyTests; +using VerifyXunit; +using Xunit; + +[UsesEasyTestFile] +[UsesVerify] +public class DocumentationTests +{ + private readonly EasyTestFileSettings _testFileSettings; + private readonly VerifySettings _verifySettings; + private readonly YamlDynamicRepositoryActionDeserializer _sut; + + public DocumentationTests() + { + _sut = DynamicRepositoryActionDeserializerFactory.Create(); + + _testFileSettings = new EasyTestFileSettings(); + _testFileSettings.UseDirectory("DocumentationFiles"); + _testFileSettings.UseExtension("yaml"); + + _verifySettings = new VerifySettings(); + _verifySettings.UseDirectory("DocumentationFilesVerified"); + } + + [Theory] + [InlineData("Browser01")] + public async Task Deserialize_Documentation(string filename) + { + // arrange + _testFileSettings.UseFileName(filename); + var content = await EasyTestFile.LoadAsText(_testFileSettings); + + // act + RepositoryActionConfiguration result = _sut.Deserialize(content); + + // assert + await Verifier.Verify(result, _verifySettings).UseTextForParameters(filename); + } +} \ No newline at end of file diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/RepoM.Plugin.WebBrowser.Tests.csproj b/tests/RepoM.Plugin.WebBrowser.Tests/RepoM.Plugin.WebBrowser.Tests.csproj new file mode 100644 index 00000000..d16fe9b5 --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/RepoM.Plugin.WebBrowser.Tests.csproj @@ -0,0 +1,42 @@ + + + + net7.0 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/DynamicRepositoryActionDeserializerFactory.cs b/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/DynamicRepositoryActionDeserializerFactory.cs new file mode 100644 index 00000000..be3b8da3 --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/DynamicRepositoryActionDeserializerFactory.cs @@ -0,0 +1,28 @@ +namespace RepoM.Plugin.WebBrowser.Tests.TestFramework; + +using System; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.ActionDeserializers; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Data; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider.Deserialization; +using RepoM.Core.Plugin.RepositoryOrdering.Configuration; +using RepoM.Plugin.WebBrowser.ActionProvider; + +internal static class DynamicRepositoryActionDeserializerFactory +{ + public static YamlDynamicRepositoryActionDeserializer Create() + { + return new YamlDynamicRepositoryActionDeserializer( + new ActionDeserializerComposition( + new IActionDeserializer[] + { + new DefaultActionDeserializer(), + }, + Array.Empty>())); + } + + public static YamlDynamicRepositoryActionDeserializer CreateWithDeserializer(IActionDeserializer actionDeserializer) + { + return new YamlDynamicRepositoryActionDeserializer(new ActionDeserializerComposition(new[] { actionDeserializer, }, Array.Empty>())); + } +} \ No newline at end of file diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/VerifierInitializer.cs b/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/VerifierInitializer.cs new file mode 100644 index 00000000..6ba48f5e --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/TestFramework/VerifierInitializer.cs @@ -0,0 +1,15 @@ +namespace RepoM.Plugin.Statistics.Tests.TestFramework; + +using System.Runtime.CompilerServices; +using Argon; +using VerifyTests; + +public static class VerifierInitializer +{ + [ModuleInitializer] + public static void Initialize() + { + VerifierSettings.DisableRequireUniquePrefix(); + VerifierSettings.AddExtraSettings(serializerSettings => serializerSettings.TypeNameHandling = TypeNameHandling.Auto); + } +} \ No newline at end of file diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserPackageTest.cs b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserPackageTest.cs new file mode 100644 index 00000000..c014bc2e --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserPackageTest.cs @@ -0,0 +1,99 @@ +namespace RepoM.Plugin.WebBrowser.Tests; + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using FakeItEasy; +using Microsoft.Extensions.Logging; +using RepoM.Api.IO.ModuleBasedRepositoryActionProvider; +using RepoM.Core.Plugin; +using RepoM.Core.Plugin.Expressions; +using RepoM.Plugin.WebBrowser; +using RepoM.Plugin.WebBrowser.PersistentConfiguration; +using SimpleInjector; +using Xunit; + +public class WebBrowserPackageTest +{ + private readonly Container _container; + private readonly IPackageConfiguration _packageConfiguration; + + public WebBrowserPackageTest() + { + _packageConfiguration = A.Fake(); + _container = new Container(); + + var webBrowserConfigV1 = new WebBrowserConfigV1 + { + Browsers = new Dictionary + { + { "Edge", "msedge.exe" }, + }, + Profiles = new Dictionary + { + { + "incognito", + new ProfileConfig { BrowserName = "Edge", CommandLineArguments = "--incognito", } + }, + }, + }; + A.CallTo(() => _packageConfiguration.GetConfigurationVersionAsync()).Returns(Task.FromResult(1 as int?)); + A.CallTo(() => _packageConfiguration.LoadConfigurationAsync()).ReturnsLazily(() => webBrowserConfigV1); + A.CallTo(() => _packageConfiguration.PersistConfigurationAsync(A._, 1)).Returns(Task.CompletedTask); + } + + [Fact] + public async Task RegisterServices_ShouldBeSuccessful_WhenExternalDependenciesAreRegistered() + { + // arrange + RegisterExternals(_container); + var sut = new WebBrowserPackage(); + + // act + await sut.RegisterServicesAsync(_container, _packageConfiguration); + + // assert + // implicit, Verify throws when container is not valid. + _container.Verify(VerificationOption.VerifyAndDiagnose); + } + + [Theory] + [InlineData(null)] + [InlineData(2)] + [InlineData(10)] + public async Task RegisterServices_ShouldPersistNewConfig_WhenVersionIsNotCorrect(int? version) + { + // arrange + A.CallTo(() => _packageConfiguration.GetConfigurationVersionAsync()).Returns(Task.FromResult(version)); + RegisterExternals(_container); + var sut = new WebBrowserPackage(); + + // act + await sut.RegisterServicesAsync(_container, _packageConfiguration); + + // assert + A.CallTo(() => _packageConfiguration.PersistConfigurationAsync(A._, 1)).MustHaveHappenedOnceExactly(); + + // implicit, Verify throws when container is not valid. + _container.Verify(VerificationOption.VerifyAndDiagnose); + } + + [Fact] + public async Task RegisterServices_ShouldFail_WhenExternalDependenciesAreNotRegistered() + { + // arrange + var sut = new WebBrowserPackage(); + + // act + await sut.RegisterServicesAsync(_container, _packageConfiguration); + + // assert + Assert.Throws(() => _container.Verify(VerificationOption.VerifyAndDiagnose)); + } + + private static void RegisterExternals(Container container) + { + container.RegisterSingleton(A.Dummy); + container.RegisterSingleton(A.Dummy); + } +} \ No newline at end of file diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs new file mode 100644 index 00000000..c19abe0b --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs @@ -0,0 +1,23 @@ +namespace RepoM.Plugin.WebBrowser.Tests; + +using System; +using FluentAssertions; +using RepoM.Plugin.WebBrowser.Services; +using VerifyXunit; +using Xunit; + +[UsesVerify] +public class WebBrowserServiceTest +{ + [Fact] + public void Ctor_ShouldThrow_WhenArgumentNull() + { + // arrange + + // act + Func act1 = () => new WebBrowserService(null!); + + // assert + act1.Should().Throw(); + } +} \ No newline at end of file From 4798fa4a735f26b4542e4fdc89c3cf76ed197868 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 13 Sep 2023 06:44:06 +0000 Subject: [PATCH 02/14] Docs changes --- README.md | 2 ++ docs/ActionList.md | 39 +++++++-------------------------------- 2 files changed, 9 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index cad34c74..a043cd57 100644 --- a/README.md +++ b/README.md @@ -74,4 +74,6 @@ RepoM uses plugins to extend functionality. At this moment, when a plugin is ava - [LuceneQueryParser](docs/RepoM.Plugin.LuceneQueryParser.md) - [SonarCloud](docs/RepoM.Plugin.SonarCloud.md) - [Statistics](docs/RepoM.Plugin.Statistics.md) + - [WebBrowser](docs/RepoM.Plugin.WebBrowser.md) - [WindowsExplorerGitInfo](docs/RepoM.Plugin.WindowsExplorerGitInfo.md) + diff --git a/docs/ActionList.md b/docs/ActionList.md index 2e45fab2..27fe2fdd 100644 --- a/docs/ActionList.md +++ b/docs/ActionList.md @@ -91,34 +91,6 @@ repository-actions: snippet source | anchor -## browser@1 - -Action opening a webbrowser with the provided url. - -Action specific properties: - -- `url`: The url to browse to. (required, evaluated, string) - -Example: - - - -```yaml -repository-actions: - actions: - - type: browser@1 - active: true - variables: [] - name: 'My Github' - url: 'https://github.com/coenm' - - - type: browser@1 - name: 'My Github' - url: 'https://github.com/coenm' -``` -snippet source | anchor - - ## command@1 Action to excute a command (related the the repository) @@ -276,11 +248,10 @@ repository-actions: variable: environment skip: '' actions: - - type: browser@1 - name: '{var.environment.key}' - url: '{var.environment.url}' + - type: just-text@1 + name: '{var.environment.key} - {var.environment.url}' ``` -snippet source | anchor +snippet source | anchor ## git-checkout@1 @@ -652,6 +623,10 @@ repository-actions: See the [Heidi](RepoM.Plugin.Heidi.md) plugin for more information. +include _plugins.webbrowser.action + +See the [WebBrowser](RepoM.Plugin.WebBrowser.md) plugin for more information. + # Repository Actions These actions are part of the Repository Actions config file described in [Repository Actions](RepositoryActions.md). From c8e28bddda4ecb5ef999f14fedf6a08d532cb7c2 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 08:54:52 +0200 Subject: [PATCH 03/14] docs --- docs/ActionList.md | 88 ++++++++++----------- docs/Ordering.md | 40 +++++----- docs/RepoM.Plugin.AzureDevOps.md | 16 ++-- docs/RepoM.Plugin.Clipboard.md | 12 +-- docs/RepoM.Plugin.EverythingFileSearch.md | 6 +- docs/RepoM.Plugin.Heidi.md | 12 +-- docs/RepoM.Plugin.LuceneQueryParser.md | 6 +- docs/RepoM.Plugin.SonarCloud.md | 12 +-- docs/RepoM.Plugin.Statistics.md | 6 +- docs/RepoM.Plugin.WebBrowser.md | 57 +++++++++++++ docs/RepoM.Plugin.WindowsExplorerGitInfo.md | 6 +- docs/Settings.md | 6 +- 12 files changed, 162 insertions(+), 105 deletions(-) create mode 100644 docs/RepoM.Plugin.WebBrowser.md diff --git a/docs/ActionList.md b/docs/ActionList.md index 27fe2fdd..20c03cda 100644 --- a/docs/ActionList.md +++ b/docs/ActionList.md @@ -2,22 +2,22 @@ Most of the repository actions are part of the core of RepoM and some are part of external plugins. All these repository actions have the same base: -Properties: +Properties: - `type`: RepositoryAction type. Should be a fixed value used to determine the action type. (required, string) - `name`: Name of the action. This is shown in the UI of RepoM. (required, evaluated, string) - `active`: Is the action active (ie. visible) or not. (optional, evaluated, boolean, default: `true`) -- `variables`: A set of variables to be availabe within this action. (optional, list`1) +- `variables`: A set of variables to be availabe within this action. (optional, list`1) The following actions are part of the core of RepoM and can always be used in your RepositoryActions. ## just-text@1 -Textual action to display some text in the action menu. +Textual action to display some text in the action menu. Action specific properties: -- `enabled`: Show the menu as enabled (clickable) or disabled. (optional, evaluated, boolean, default: `true`) +- `enabled`: Show the menu as enabled (clickable) or disabled. (optional, evaluated, boolean, default: `true`) Example: @@ -40,12 +40,12 @@ repository-actions: ## associate-file@1 -Action menu for opening files with a given extension. If files within the repository are found matching the extension, a submenu will be created with all matched files. +Action menu for opening files with a given extension. If files within the repository are found matching the extension, a submenu will be created with all matched files. Action specific properties: - `extension`: The file extension to look for. This parameter can contain a combination of valid literal path and wildcard (`*` and `?`) characters, but it doesnt support regular expressions. -For example `*.sln`. (required, string) +For example `*.sln`. (required, string) Example: @@ -69,11 +69,11 @@ repository-actions: ## browse-repository@1 -Action to open the default webbrowser and go to the origin remote webinterface. When multple remotes are available a sub menu is created for each remote. +Action to open the default webbrowser and go to the origin remote webinterface. When multple remotes are available a sub menu is created for each remote. Action specific properties: -- `first-only`: Property specifying only a menu item for the first remote is created. (optional, evaluated, boolean) +- `first-only`: Property specifying only a menu item for the first remote is created. (optional, evaluated, boolean) Example: @@ -93,12 +93,12 @@ repository-actions: ## command@1 -Action to excute a command (related the the repository) +Action to excute a command (related the the repository) Action specific properties: - `command`: The command to execute. (required, evaluated, string) -- `arguments`: Arguments for the command. (optional, evaluated, string) +- `arguments`: Arguments for the command. (optional, evaluated, string) Example: @@ -124,12 +124,12 @@ repository-actions: ## executable@1 -Action to excute an application with additional arguments. This action is almost identical to the `command@1` action. When no existing executables are provided, the action will not show. +Action to excute an application with additional arguments. This action is almost identical to the `command@1` action. When no existing executables are provided, the action will not show. Action specific properties: - `executables`: Set of possible executables. The first executable that exists will be used. The paths should absolute. (required, evaluated, string) -- `arguments`: Arguments for the executable. (optional, evaluated, string) +- `arguments`: Arguments for the executable. (optional, evaluated, string) When you want to specify exacly one executable, you can replace the required property `Executables` with the following property: @@ -179,12 +179,12 @@ repository-actions: ## folder@1 -Action to create a folder (sub menu) in the context menu of the repository allowing you to order actions. +Action to create a folder (sub menu) in the context menu of the repository allowing you to order actions. Action specific properties: - `items`: Menu items. (required, evaluated, list`1) -- `is-deferred`: Menu is deferred. This will speed up visualisation. (optional, evaluated, boolean, default: `false`) +- `is-deferred`: Menu is deferred. This will speed up visualisation. (optional, evaluated, boolean, default: `false`) Example: @@ -216,14 +216,14 @@ repository-actions: ## foreach@1 -Action to create repeated actions based on a variable. +Action to create repeated actions based on a variable. Action specific properties: - `enumerable`: The list of items to enumerate on. (required, evaluated, string) - `variable`: The name of the variable to access to current enumeration of the items. For each iteration, the variable `{var.name}` has the value of the current iteration. (required, evaluated, string) - `skip`: Predicate to skip the current item. (optional, evaluated, string) -- `actions`: List of repeated actions. (required, evaluated, ienumerable`1) +- `actions`: List of repeated actions. (required, evaluated, ienumerable`1) Example: @@ -256,9 +256,9 @@ repository-actions: ## git-checkout@1 -This action will create a menu and sub menus with all local and remote branches for an easy checkout. +This action will create a menu and sub menus with all local and remote branches for an easy checkout. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -278,9 +278,9 @@ repository-actions: ## git-fetch@1 -Action to execute a `git fetch` command. +Action to execute a `git fetch` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -300,9 +300,9 @@ repository-actions: ## git-pull@1 -Action to execute a `git pull` command. +Action to execute a `git pull` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -322,9 +322,9 @@ repository-actions: ## git-push@1 -Action to execute a `git push` command. +Action to execute a `git push` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -344,10 +344,10 @@ repository-actions: ## ignore-repository@1 -Action to ignore the current repository. This repository will be added to the list of ignored repositories and will never show in RepoM. +Action to ignore the current repository. This repository will be added to the list of ignored repositories and will never show in RepoM. To undo this action, clear all ignored repositories or manually edit the ignored repositories file (when RepoM is not running). -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -367,13 +367,13 @@ repository-actions: ## pin-repository@1 -Action to pin (or unpin) the current repository. Pinning is not persistant and all pinned repositories will be cleared when RepoM exits. +Action to pin (or unpin) the current repository. Pinning is not persistant and all pinned repositories will be cleared when RepoM exits. Pinning a repository allowed custom filtering, ordering and searching. Action specific properties: - `name`: Name of the action. This is shown in the UI of RepoM. When no value is provided, the name will be a default value based on the mode. (optional, evaluated, string) -- `mode`: The pin mode `[Toggle, Pin, UnPin]`. (required, pinmode) +- `mode`: The pin mode `[Toggle, Pin, UnPin]`. (required, pinmode) Example: @@ -402,9 +402,9 @@ repository-actions: ## separator@1 -Creates a visual separator in the action menu. +Creates a visual separator in the action menu. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -426,13 +426,13 @@ repository-actions: These actions are available though the use of plugins. -## clipboard-copy@1 +## clipboard-copy@1 -This action makes it possible to copy text to the clipboard. +This action makes it possible to copy text to the clipboard. Action specific properties: -- `text`: The text to copy to the clipboard. (required, evaluated, string) +- `text`: The text to copy to the clipboard. (required, evaluated, string) Example: @@ -457,13 +457,13 @@ repository-actions: See the [Clipboard](RepoM.Plugin.Clipboard.md) plugin for more information. -## sonarcloud-set-favorite@1 +## sonarcloud-set-favorite@1 -Action to mark a repository as favorite within SonarCloud. +Action to mark a repository as favorite within SonarCloud. Action specific properties: -- `project`: The SonarCloud project key. (required, evaluated, string) +- `project`: The SonarCloud project key. (required, evaluated, string) Example: @@ -488,9 +488,9 @@ repository-actions: See the [SonarCloud](RepoM.Plugin.SonarCloud.md) plugin for more information. -## azure-devops-create-prs@1 +## azure-devops-create-prs@1 -Action menu item to create a pull request in Azure Devops. +Action menu item to create a pull request in Azure Devops. Action specific properties: @@ -504,7 +504,7 @@ Title will be the last part of the branchname split on `/`, so `feature/123-test - `draft-pr`: Boolean specifying if th PR should be marked as draft. (required, boolean, default: `false`) - `include-work-items`: Boolean specifying if workitems should be included in the PR. The workitems will be found by using the commit messages. (required, boolean, default: `true`) - `open-in-browser`: Boolean specifying if the Pull request should be opened in the browser after creation. (required, boolean, default: `false`) -- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) +- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) Example: @@ -555,13 +555,13 @@ repository-actions: ## azure-devops-get-prs@1 -This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. +This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. Action specific properties: - `project-id`: The azure devops project id. (required, evaluated, string) - `repository-id`: The repository Id. If not provided, the repository id is located using the remote url. (optional, evaluated, string) -- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) +- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) Example: @@ -586,16 +586,16 @@ repository-actions: See the [AzureDevOps](RepoM.Plugin.AzureDevOps.md) plugin for more information. -## heidi-databases@1 +## heidi-databases@1 -Action to list heidi databases and show action menus for them. +Action to list heidi databases and show action menus for them. Action specific properties: - `key`: Repository key. If not provided, the repository `Remote.Origin.Name` is used as selector. (optional, string) -- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) +- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) Example: diff --git a/docs/Ordering.md b/docs/Ordering.md index 3e852a7f..0fcce5aa 100644 --- a/docs/Ordering.md +++ b/docs/Ordering.md @@ -12,7 +12,7 @@ A [`comparer`](#comparers) compares two repositories resulting in an order betwe ## Comparers -- [`az-comparer@1`](#az-comparer1) +- [`az-comparer@1`](#az-comparer1) - [`composition-comparer@1`](#composition-comparer1) - [`score-comparer@1`](#score-comparer1) - [`sum-comparer@1`](#sum-comparer1) @@ -22,49 +22,49 @@ These comparers are available by using the corresponding plugin. ### `az-comparer@1` -Compares two repositories by a given property alphabetically in ascending order. +Compares two repositories by a given property alphabetically in ascending order. Properties: - `property`: Repository property. Currently, only `Name`, and `Location` are supported. Otherwise, comparison will always result in `0`. (optional) -- `weight`: The weight of this comparer. The higher the weight, the higher the impact. +- `weight`: The weight of this comparer. The higher the weight, the higher the impact. ### `composition-comparer@1` -Compares two repositories by a composition of comparers. +Compares two repositories by a composition of comparers. Properties: -- `comparers`: List of comparers. The first comparer not resulting in `0` will be used as final result. +- `comparers`: List of comparers. The first comparer not resulting in `0` will be used as final result. ### `score-comparer@1` -Compares two repositories by a repository score. The calculation of the repository score is defined in the score provider. +Compares two repositories by a repository score. The calculation of the repository score is defined in the score provider. Properties: -- `score-provider`: The score provider to calculate a score for a repository. (optional) +- `score-provider`: The score provider to calculate a score for a repository. (optional) ### `sum-comparer@1` -Compares two repositories by the sum of the results of the comparers. +Compares two repositories by the sum of the results of the comparers. Properties: -- `comparers`: A list of comparers. The sum of the results of the comparers will be used as final result. +- `comparers`: A list of comparers. The sum of the results of the comparers will be used as final result. ### `last-opened-comparer@1` -Compares two repositories by the timestamp of the last action RepoM performed on the repository. +Compares two repositories by the timestamp of the last action RepoM performed on the repository. Properties: -- `weight`: The weight of this comparer. The higher the weight, the higher the impact. - +- `weight`: The weight of this comparer. The higher the weight, the higher the impact. + ## Scorers -- [`is-pinned-scorer@1`](#is-pinned-scorer1) +- [`is-pinned-scorer@1`](#is-pinned-scorer1) - [`tag-scorer@1`](#tag-scorer1) These scorers are available by using the corresponding plugin. @@ -72,27 +72,27 @@ These scorers are available by using the corresponding plugin. ### `is-pinned-scorer@1` -Repository scorer based on the pinned state of a repository. +Repository scorer based on the pinned state of a repository. Properties: -- `weight`: The weight of this scorer. The higher the weight, the higher the impact. +- `weight`: The weight of this scorer. The higher the weight, the higher the impact. ### `tag-scorer@1` -Repository scorer based on the tags of a repository. +Repository scorer based on the tags of a repository. Properties: - `weight`: The weight of this scorer. The higher the weight, the higher the impact. -- `tag`: The tag to match on. If the repository has this tag, the score will return the weight, otherwise, `0`. (optional) +- `tag`: The tag to match on. If the repository has this tag, the score will return the weight, otherwise, `0`. (optional) ### `usage-scorer@1` -Repository scorer based on it's usage by RepoM. The more it's used, the higher the score. +Repository scorer based on it's usage by RepoM. The more it's used, the higher the score. Properties: - `windows`: Specific 'windows' to calculate the score for. -- `max-score`: The maximum score a repository can get. - +- `max-score`: The maximum score a repository can get. + diff --git a/docs/RepoM.Plugin.AzureDevOps.md b/docs/RepoM.Plugin.AzureDevOps.md index f5b66ca2..37eb52d7 100644 --- a/docs/RepoM.Plugin.AzureDevOps.md +++ b/docs/RepoM.Plugin.AzureDevOps.md @@ -2,9 +2,9 @@ The AzureDevops module enables integration with one azure devops environment. The integration currently focusses on Pull Requests. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -24,11 +24,11 @@ Properties: - `PersonalAccessToken`: Personal access token (PAT) to access Azure Devops. The PAT should be granted access to `todo` rights. To create a PAT, goto `https://dev.azure.com/[my-organisation]/_usersSettings/tokens`. -- `BaseUrl`: The base url of azure devops for your organisation (ie. `https://dev.azure.com/[my-organisation]/`). +- `BaseUrl`: The base url of azure devops for your organisation (ie. `https://dev.azure.com/[my-organisation]/`). -## azure-devops-create-prs@1 +## azure-devops-create-prs@1 -Action menu item to create a pull request in Azure Devops. +Action menu item to create a pull request in Azure Devops. Action specific properties: @@ -42,7 +42,7 @@ Title will be the last part of the branchname split on `/`, so `feature/123-test - `draft-pr`: Boolean specifying if th PR should be marked as draft. (required, boolean, default: `false`) - `include-work-items`: Boolean specifying if workitems should be included in the PR. The workitems will be found by using the commit messages. (required, boolean, default: `true`) - `open-in-browser`: Boolean specifying if the Pull request should be opened in the browser after creation. (required, boolean, default: `false`) -- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) +- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) Example: @@ -93,13 +93,13 @@ repository-actions: ## azure-devops-get-prs@1 -This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. +This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. Action specific properties: - `project-id`: The azure devops project id. (required, evaluated, string) - `repository-id`: The repository Id. If not provided, the repository id is located using the remote url. (optional, evaluated, string) -- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) +- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) Example: diff --git a/docs/RepoM.Plugin.Clipboard.md b/docs/RepoM.Plugin.Clipboard.md index b5aa54d6..6e97cdaa 100644 --- a/docs/RepoM.Plugin.Clipboard.md +++ b/docs/RepoM.Plugin.Clipboard.md @@ -2,19 +2,19 @@ This module provides a repository actions to copy specific (evaluated) text to the clipboard using the action provider type `clipboard-copy`. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. -## clipboard-copy@1 +## clipboard-copy@1 -This action makes it possible to copy text to the clipboard. +This action makes it possible to copy text to the clipboard. Action specific properties: -- `text`: The text to copy to the clipboard. (required, evaluated, string) +- `text`: The text to copy to the clipboard. (required, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.EverythingFileSearch.md b/docs/RepoM.Plugin.EverythingFileSearch.md index cf114d06..39e43cdd 100644 --- a/docs/RepoM.Plugin.EverythingFileSearch.md +++ b/docs/RepoM.Plugin.EverythingFileSearch.md @@ -2,8 +2,8 @@ This module integrates with VoidTool Everything in order to locate git repositories on your system. Using Everythings cache, this process will be much faster then locating git repositories the default way. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. diff --git a/docs/RepoM.Plugin.Heidi.md b/docs/RepoM.Plugin.Heidi.md index fc212f7d..cac2d44f 100644 --- a/docs/RepoM.Plugin.Heidi.md +++ b/docs/RepoM.Plugin.Heidi.md @@ -3,9 +3,9 @@ This module integrates with a portable [HeidiSQL](https://www.heidisql.com/) installation. The portable Heidi DB saves its database configuration in a portable configuration file. This module monitors this file and provides an action menu and a variable provider to access this information. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -26,7 +26,7 @@ Properties: - `ConfigPath`: The full directory where the portable configuration file is stored. - `ConfigFilename`: The portable-configurration filename (without path). Most likely `portable_settings.txt` -- `ExecutableFilename`: The full executable of Heidi. +- `ExecutableFilename`: The full executable of Heidi. In order to let RepoM know what database configuration should be linked to what git repository the following should be added in the comment section when editing a database configuration in the Heidi's session manager. @@ -45,16 +45,16 @@ Example: ![Screenshot](HeidiSQL.png) ![Screenshot](HeidiInRepoM.png) -## heidi-databases@1 +## heidi-databases@1 -Action to list heidi databases and show action menus for them. +Action to list heidi databases and show action menus for them. Action specific properties: - `key`: Repository key. If not provided, the repository `Remote.Origin.Name` is used as selector. (optional, string) -- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) +- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.LuceneQueryParser.md b/docs/RepoM.Plugin.LuceneQueryParser.md index 56713f43..2db98493 100644 --- a/docs/RepoM.Plugin.LuceneQueryParser.md +++ b/docs/RepoM.Plugin.LuceneQueryParser.md @@ -1,10 +1,10 @@ # Lucene Query Parser -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. To search for repositories, you can use a repom-dialect of Lucene query syntax. diff --git a/docs/RepoM.Plugin.SonarCloud.md b/docs/RepoM.Plugin.SonarCloud.md index c3d49718..6e5610e8 100644 --- a/docs/RepoM.Plugin.SonarCloud.md +++ b/docs/RepoM.Plugin.SonarCloud.md @@ -2,9 +2,9 @@ This module integrates with SonarCloud. Currently, the only functionality is to star a given repository in SonarCloud using the repository action. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -23,15 +23,15 @@ The following default configuration is used: Properties: - `PersonalAccessToken`: Personal Access Token to access SonarCloud. -- `BaseUrl`: SonarCloud url. Most likely `https//sonarcloud.io`. +- `BaseUrl`: SonarCloud url. Most likely `https//sonarcloud.io`. -## sonarcloud-set-favorite@1 +## sonarcloud-set-favorite@1 -Action to mark a repository as favorite within SonarCloud. +Action to mark a repository as favorite within SonarCloud. Action specific properties: -- `project`: The SonarCloud project key. (required, evaluated, string) +- `project`: The SonarCloud project key. (required, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.Statistics.md b/docs/RepoM.Plugin.Statistics.md index 2e22ddf9..a3b8f984 100644 --- a/docs/RepoM.Plugin.Statistics.md +++ b/docs/RepoM.Plugin.Statistics.md @@ -2,9 +2,9 @@ This module add functionality to keep track of actions performed on repositories. This can be used in orderings (and mabye later on in filtering) of repositories. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -23,4 +23,4 @@ The following default configuration is used: Properties: - `PersistenceBuffer`: Timespan for buffered events before making them persistant (ie. `00:05:00` for five minutes). Must be greater then or equal to `00:00:10` (10 seconds). -- `RetentionDays`: Number of days to keep statical information before deleting them. +- `RetentionDays`: Number of days to keep statical information before deleting them. diff --git a/docs/RepoM.Plugin.WebBrowser.md b/docs/RepoM.Plugin.WebBrowser.md new file mode 100644 index 00000000..4bf444ba --- /dev/null +++ b/docs/RepoM.Plugin.WebBrowser.md @@ -0,0 +1,57 @@ +# WebBrowser + +The WebBrowser module provides a repository action to open an URL in a given webbrowser. + +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. + +## Configuration + +This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. + +The following default configuration is used: + +```json +{ + "Version": 1, + "Settings": { + "Browsers": {}, + "Profiles": {} + } +} +``` + +Properties: + +- `Browsers`: Dictionary of known browsers and their path to use for opening urls. +- `Profiles`: Profiles to use. + +## browser@1 + +Action opening a webbrowser with the provided url. + +Action specific properties: + +- `url`: The url to browse to. (required, evaluated, string) +- `profile`: profile name used to select browser and browser profile (optional, evaluated, string) + +Example: + + + +```yaml +repository-actions: + actions: + - type: browser@1 + active: true + variables: [] + name: 'My Github' + url: 'https://github.com/coenm' + + - type: browser@1 + name: 'My Github' + url: 'https://github.com/coenm' + profile: edge +``` +snippet source | anchor + + diff --git a/docs/RepoM.Plugin.WindowsExplorerGitInfo.md b/docs/RepoM.Plugin.WindowsExplorerGitInfo.md index f46d93d3..dc8a1ea0 100644 --- a/docs/RepoM.Plugin.WindowsExplorerGitInfo.md +++ b/docs/RepoM.Plugin.WindowsExplorerGitInfo.md @@ -6,8 +6,8 @@ As an extra goodie for Windows users, RepoM automatically detects open File Expl Note that for Windows 11 users, the title will not be updated but in the taskbar the additional git information is still visible. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. diff --git a/docs/Settings.md b/docs/Settings.md index 291937d5..f4cf5df0 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -4,7 +4,7 @@ When RepoM starts for the first time, a configuration file wil be created. Most To do this, make sure RepoM is not running. -## Configuration +## Configuration This is the default configuration. @@ -26,7 +26,7 @@ This is the default configuration. ``` -Properties: +Properties: - `SortKey`: The selected sorting strategy. Sorting strategies can be configured manually in `RepoM.Ordering.yaml`. (optional, UI configured) - `SelectedQueryParser`: The selected query parser. Query parsers can be added by plugins. (optional, UI configured) @@ -36,4 +36,4 @@ Properties: +- `Plugins`: List of plugins. (optional, UI configured) From a71dff3cddfab91ddab634d991603c038bf83a74 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 13 Sep 2023 06:56:21 +0000 Subject: [PATCH 04/14] Docs changes --- docs/ActionList.md | 88 ++++++++++----------- docs/Ordering.md | 40 +++++----- docs/RepoM.Plugin.AzureDevOps.md | 16 ++-- docs/RepoM.Plugin.Clipboard.md | 12 +-- docs/RepoM.Plugin.EverythingFileSearch.md | 6 +- docs/RepoM.Plugin.Heidi.md | 12 +-- docs/RepoM.Plugin.LuceneQueryParser.md | 6 +- docs/RepoM.Plugin.SonarCloud.md | 12 +-- docs/RepoM.Plugin.Statistics.md | 6 +- docs/RepoM.Plugin.WebBrowser.md | 12 +-- docs/RepoM.Plugin.WindowsExplorerGitInfo.md | 6 +- docs/Settings.md | 6 +- 12 files changed, 111 insertions(+), 111 deletions(-) diff --git a/docs/ActionList.md b/docs/ActionList.md index 20c03cda..27fe2fdd 100644 --- a/docs/ActionList.md +++ b/docs/ActionList.md @@ -2,22 +2,22 @@ Most of the repository actions are part of the core of RepoM and some are part of external plugins. All these repository actions have the same base: -Properties: +Properties: - `type`: RepositoryAction type. Should be a fixed value used to determine the action type. (required, string) - `name`: Name of the action. This is shown in the UI of RepoM. (required, evaluated, string) - `active`: Is the action active (ie. visible) or not. (optional, evaluated, boolean, default: `true`) -- `variables`: A set of variables to be availabe within this action. (optional, list`1) +- `variables`: A set of variables to be availabe within this action. (optional, list`1) The following actions are part of the core of RepoM and can always be used in your RepositoryActions. ## just-text@1 -Textual action to display some text in the action menu. +Textual action to display some text in the action menu. Action specific properties: -- `enabled`: Show the menu as enabled (clickable) or disabled. (optional, evaluated, boolean, default: `true`) +- `enabled`: Show the menu as enabled (clickable) or disabled. (optional, evaluated, boolean, default: `true`) Example: @@ -40,12 +40,12 @@ repository-actions: ## associate-file@1 -Action menu for opening files with a given extension. If files within the repository are found matching the extension, a submenu will be created with all matched files. +Action menu for opening files with a given extension. If files within the repository are found matching the extension, a submenu will be created with all matched files. Action specific properties: - `extension`: The file extension to look for. This parameter can contain a combination of valid literal path and wildcard (`*` and `?`) characters, but it doesnt support regular expressions. -For example `*.sln`. (required, string) +For example `*.sln`. (required, string) Example: @@ -69,11 +69,11 @@ repository-actions: ## browse-repository@1 -Action to open the default webbrowser and go to the origin remote webinterface. When multple remotes are available a sub menu is created for each remote. +Action to open the default webbrowser and go to the origin remote webinterface. When multple remotes are available a sub menu is created for each remote. Action specific properties: -- `first-only`: Property specifying only a menu item for the first remote is created. (optional, evaluated, boolean) +- `first-only`: Property specifying only a menu item for the first remote is created. (optional, evaluated, boolean) Example: @@ -93,12 +93,12 @@ repository-actions: ## command@1 -Action to excute a command (related the the repository) +Action to excute a command (related the the repository) Action specific properties: - `command`: The command to execute. (required, evaluated, string) -- `arguments`: Arguments for the command. (optional, evaluated, string) +- `arguments`: Arguments for the command. (optional, evaluated, string) Example: @@ -124,12 +124,12 @@ repository-actions: ## executable@1 -Action to excute an application with additional arguments. This action is almost identical to the `command@1` action. When no existing executables are provided, the action will not show. +Action to excute an application with additional arguments. This action is almost identical to the `command@1` action. When no existing executables are provided, the action will not show. Action specific properties: - `executables`: Set of possible executables. The first executable that exists will be used. The paths should absolute. (required, evaluated, string) -- `arguments`: Arguments for the executable. (optional, evaluated, string) +- `arguments`: Arguments for the executable. (optional, evaluated, string) When you want to specify exacly one executable, you can replace the required property `Executables` with the following property: @@ -179,12 +179,12 @@ repository-actions: ## folder@1 -Action to create a folder (sub menu) in the context menu of the repository allowing you to order actions. +Action to create a folder (sub menu) in the context menu of the repository allowing you to order actions. Action specific properties: - `items`: Menu items. (required, evaluated, list`1) -- `is-deferred`: Menu is deferred. This will speed up visualisation. (optional, evaluated, boolean, default: `false`) +- `is-deferred`: Menu is deferred. This will speed up visualisation. (optional, evaluated, boolean, default: `false`) Example: @@ -216,14 +216,14 @@ repository-actions: ## foreach@1 -Action to create repeated actions based on a variable. +Action to create repeated actions based on a variable. Action specific properties: - `enumerable`: The list of items to enumerate on. (required, evaluated, string) - `variable`: The name of the variable to access to current enumeration of the items. For each iteration, the variable `{var.name}` has the value of the current iteration. (required, evaluated, string) - `skip`: Predicate to skip the current item. (optional, evaluated, string) -- `actions`: List of repeated actions. (required, evaluated, ienumerable`1) +- `actions`: List of repeated actions. (required, evaluated, ienumerable`1) Example: @@ -256,9 +256,9 @@ repository-actions: ## git-checkout@1 -This action will create a menu and sub menus with all local and remote branches for an easy checkout. +This action will create a menu and sub menus with all local and remote branches for an easy checkout. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -278,9 +278,9 @@ repository-actions: ## git-fetch@1 -Action to execute a `git fetch` command. +Action to execute a `git fetch` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -300,9 +300,9 @@ repository-actions: ## git-pull@1 -Action to execute a `git pull` command. +Action to execute a `git pull` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -322,9 +322,9 @@ repository-actions: ## git-push@1 -Action to execute a `git push` command. +Action to execute a `git push` command. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -344,10 +344,10 @@ repository-actions: ## ignore-repository@1 -Action to ignore the current repository. This repository will be added to the list of ignored repositories and will never show in RepoM. +Action to ignore the current repository. This repository will be added to the list of ignored repositories and will never show in RepoM. To undo this action, clear all ignored repositories or manually edit the ignored repositories file (when RepoM is not running). -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -367,13 +367,13 @@ repository-actions: ## pin-repository@1 -Action to pin (or unpin) the current repository. Pinning is not persistant and all pinned repositories will be cleared when RepoM exits. +Action to pin (or unpin) the current repository. Pinning is not persistant and all pinned repositories will be cleared when RepoM exits. Pinning a repository allowed custom filtering, ordering and searching. Action specific properties: - `name`: Name of the action. This is shown in the UI of RepoM. When no value is provided, the name will be a default value based on the mode. (optional, evaluated, string) -- `mode`: The pin mode `[Toggle, Pin, UnPin]`. (required, pinmode) +- `mode`: The pin mode `[Toggle, Pin, UnPin]`. (required, pinmode) Example: @@ -402,9 +402,9 @@ repository-actions: ## separator@1 -Creates a visual separator in the action menu. +Creates a visual separator in the action menu. -This action does not have any specific properties. +This action does not have any specific properties. Example: @@ -426,13 +426,13 @@ repository-actions: These actions are available though the use of plugins. -## clipboard-copy@1 +## clipboard-copy@1 -This action makes it possible to copy text to the clipboard. +This action makes it possible to copy text to the clipboard. Action specific properties: -- `text`: The text to copy to the clipboard. (required, evaluated, string) +- `text`: The text to copy to the clipboard. (required, evaluated, string) Example: @@ -457,13 +457,13 @@ repository-actions: See the [Clipboard](RepoM.Plugin.Clipboard.md) plugin for more information. -## sonarcloud-set-favorite@1 +## sonarcloud-set-favorite@1 -Action to mark a repository as favorite within SonarCloud. +Action to mark a repository as favorite within SonarCloud. Action specific properties: -- `project`: The SonarCloud project key. (required, evaluated, string) +- `project`: The SonarCloud project key. (required, evaluated, string) Example: @@ -488,9 +488,9 @@ repository-actions: See the [SonarCloud](RepoM.Plugin.SonarCloud.md) plugin for more information. -## azure-devops-create-prs@1 +## azure-devops-create-prs@1 -Action menu item to create a pull request in Azure Devops. +Action menu item to create a pull request in Azure Devops. Action specific properties: @@ -504,7 +504,7 @@ Title will be the last part of the branchname split on `/`, so `feature/123-test - `draft-pr`: Boolean specifying if th PR should be marked as draft. (required, boolean, default: `false`) - `include-work-items`: Boolean specifying if workitems should be included in the PR. The workitems will be found by using the commit messages. (required, boolean, default: `true`) - `open-in-browser`: Boolean specifying if the Pull request should be opened in the browser after creation. (required, boolean, default: `false`) -- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) +- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) Example: @@ -555,13 +555,13 @@ repository-actions: ## azure-devops-get-prs@1 -This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. +This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. Action specific properties: - `project-id`: The azure devops project id. (required, evaluated, string) - `repository-id`: The repository Id. If not provided, the repository id is located using the remote url. (optional, evaluated, string) -- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) +- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) Example: @@ -586,16 +586,16 @@ repository-actions: See the [AzureDevOps](RepoM.Plugin.AzureDevOps.md) plugin for more information. -## heidi-databases@1 +## heidi-databases@1 -Action to list heidi databases and show action menus for them. +Action to list heidi databases and show action menus for them. Action specific properties: - `key`: Repository key. If not provided, the repository `Remote.Origin.Name` is used as selector. (optional, string) -- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) +- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) Example: diff --git a/docs/Ordering.md b/docs/Ordering.md index 0fcce5aa..3e852a7f 100644 --- a/docs/Ordering.md +++ b/docs/Ordering.md @@ -12,7 +12,7 @@ A [`comparer`](#comparers) compares two repositories resulting in an order betwe ## Comparers -- [`az-comparer@1`](#az-comparer1) +- [`az-comparer@1`](#az-comparer1) - [`composition-comparer@1`](#composition-comparer1) - [`score-comparer@1`](#score-comparer1) - [`sum-comparer@1`](#sum-comparer1) @@ -22,49 +22,49 @@ These comparers are available by using the corresponding plugin. ### `az-comparer@1` -Compares two repositories by a given property alphabetically in ascending order. +Compares two repositories by a given property alphabetically in ascending order. Properties: - `property`: Repository property. Currently, only `Name`, and `Location` are supported. Otherwise, comparison will always result in `0`. (optional) -- `weight`: The weight of this comparer. The higher the weight, the higher the impact. +- `weight`: The weight of this comparer. The higher the weight, the higher the impact. ### `composition-comparer@1` -Compares two repositories by a composition of comparers. +Compares two repositories by a composition of comparers. Properties: -- `comparers`: List of comparers. The first comparer not resulting in `0` will be used as final result. +- `comparers`: List of comparers. The first comparer not resulting in `0` will be used as final result. ### `score-comparer@1` -Compares two repositories by a repository score. The calculation of the repository score is defined in the score provider. +Compares two repositories by a repository score. The calculation of the repository score is defined in the score provider. Properties: -- `score-provider`: The score provider to calculate a score for a repository. (optional) +- `score-provider`: The score provider to calculate a score for a repository. (optional) ### `sum-comparer@1` -Compares two repositories by the sum of the results of the comparers. +Compares two repositories by the sum of the results of the comparers. Properties: -- `comparers`: A list of comparers. The sum of the results of the comparers will be used as final result. +- `comparers`: A list of comparers. The sum of the results of the comparers will be used as final result. ### `last-opened-comparer@1` -Compares two repositories by the timestamp of the last action RepoM performed on the repository. +Compares two repositories by the timestamp of the last action RepoM performed on the repository. Properties: -- `weight`: The weight of this comparer. The higher the weight, the higher the impact. - +- `weight`: The weight of this comparer. The higher the weight, the higher the impact. + ## Scorers -- [`is-pinned-scorer@1`](#is-pinned-scorer1) +- [`is-pinned-scorer@1`](#is-pinned-scorer1) - [`tag-scorer@1`](#tag-scorer1) These scorers are available by using the corresponding plugin. @@ -72,27 +72,27 @@ These scorers are available by using the corresponding plugin. ### `is-pinned-scorer@1` -Repository scorer based on the pinned state of a repository. +Repository scorer based on the pinned state of a repository. Properties: -- `weight`: The weight of this scorer. The higher the weight, the higher the impact. +- `weight`: The weight of this scorer. The higher the weight, the higher the impact. ### `tag-scorer@1` -Repository scorer based on the tags of a repository. +Repository scorer based on the tags of a repository. Properties: - `weight`: The weight of this scorer. The higher the weight, the higher the impact. -- `tag`: The tag to match on. If the repository has this tag, the score will return the weight, otherwise, `0`. (optional) +- `tag`: The tag to match on. If the repository has this tag, the score will return the weight, otherwise, `0`. (optional) ### `usage-scorer@1` -Repository scorer based on it's usage by RepoM. The more it's used, the higher the score. +Repository scorer based on it's usage by RepoM. The more it's used, the higher the score. Properties: - `windows`: Specific 'windows' to calculate the score for. -- `max-score`: The maximum score a repository can get. - +- `max-score`: The maximum score a repository can get. + diff --git a/docs/RepoM.Plugin.AzureDevOps.md b/docs/RepoM.Plugin.AzureDevOps.md index 37eb52d7..f5b66ca2 100644 --- a/docs/RepoM.Plugin.AzureDevOps.md +++ b/docs/RepoM.Plugin.AzureDevOps.md @@ -2,9 +2,9 @@ The AzureDevops module enables integration with one azure devops environment. The integration currently focusses on Pull Requests. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -24,11 +24,11 @@ Properties: - `PersonalAccessToken`: Personal access token (PAT) to access Azure Devops. The PAT should be granted access to `todo` rights. To create a PAT, goto `https://dev.azure.com/[my-organisation]/_usersSettings/tokens`. -- `BaseUrl`: The base url of azure devops for your organisation (ie. `https://dev.azure.com/[my-organisation]/`). +- `BaseUrl`: The base url of azure devops for your organisation (ie. `https://dev.azure.com/[my-organisation]/`). -## azure-devops-create-prs@1 +## azure-devops-create-prs@1 -Action menu item to create a pull request in Azure Devops. +Action menu item to create a pull request in Azure Devops. Action specific properties: @@ -42,7 +42,7 @@ Title will be the last part of the branchname split on `/`, so `feature/123-test - `draft-pr`: Boolean specifying if th PR should be marked as draft. (required, boolean, default: `false`) - `include-work-items`: Boolean specifying if workitems should be included in the PR. The workitems will be found by using the commit messages. (required, boolean, default: `true`) - `open-in-browser`: Boolean specifying if the Pull request should be opened in the browser after creation. (required, boolean, default: `false`) -- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) +- `auto-complete`: Auto complete options. Please take a look at the same for more information (required, repositoryactionazuredevopscreatepullrequestsautocompleteoptionsv1) Example: @@ -93,13 +93,13 @@ repository-actions: ## azure-devops-get-prs@1 -This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. +This action results in zero or more items in the contextmenu. For each open pullrequest for the given repository, it will show an action to go to the specific PullRequest in your favorite webbrowser. Action specific properties: - `project-id`: The azure devops project id. (required, evaluated, string) - `repository-id`: The repository Id. If not provided, the repository id is located using the remote url. (optional, evaluated, string) -- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) +- `show-when-empty`: When no pull requests are available, this property is used to determine if no or a message item is showed. (optional, evaluated, string, default: `true`) Example: diff --git a/docs/RepoM.Plugin.Clipboard.md b/docs/RepoM.Plugin.Clipboard.md index 6e97cdaa..b5aa54d6 100644 --- a/docs/RepoM.Plugin.Clipboard.md +++ b/docs/RepoM.Plugin.Clipboard.md @@ -2,19 +2,19 @@ This module provides a repository actions to copy specific (evaluated) text to the clipboard using the action provider type `clipboard-copy`. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. -## clipboard-copy@1 +## clipboard-copy@1 -This action makes it possible to copy text to the clipboard. +This action makes it possible to copy text to the clipboard. Action specific properties: -- `text`: The text to copy to the clipboard. (required, evaluated, string) +- `text`: The text to copy to the clipboard. (required, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.EverythingFileSearch.md b/docs/RepoM.Plugin.EverythingFileSearch.md index 39e43cdd..cf114d06 100644 --- a/docs/RepoM.Plugin.EverythingFileSearch.md +++ b/docs/RepoM.Plugin.EverythingFileSearch.md @@ -2,8 +2,8 @@ This module integrates with VoidTool Everything in order to locate git repositories on your system. Using Everythings cache, this process will be much faster then locating git repositories the default way. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. diff --git a/docs/RepoM.Plugin.Heidi.md b/docs/RepoM.Plugin.Heidi.md index cac2d44f..fc212f7d 100644 --- a/docs/RepoM.Plugin.Heidi.md +++ b/docs/RepoM.Plugin.Heidi.md @@ -3,9 +3,9 @@ This module integrates with a portable [HeidiSQL](https://www.heidisql.com/) installation. The portable Heidi DB saves its database configuration in a portable configuration file. This module monitors this file and provides an action menu and a variable provider to access this information. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -26,7 +26,7 @@ Properties: - `ConfigPath`: The full directory where the portable configuration file is stored. - `ConfigFilename`: The portable-configurration filename (without path). Most likely `portable_settings.txt` -- `ExecutableFilename`: The full executable of Heidi. +- `ExecutableFilename`: The full executable of Heidi. In order to let RepoM know what database configuration should be linked to what git repository the following should be added in the comment section when editing a database configuration in the Heidi's session manager. @@ -45,16 +45,16 @@ Example: ![Screenshot](HeidiSQL.png) ![Screenshot](HeidiInRepoM.png) -## heidi-databases@1 +## heidi-databases@1 -Action to list heidi databases and show action menus for them. +Action to list heidi databases and show action menus for them. Action specific properties: - `key`: Repository key. If not provided, the repository `Remote.Origin.Name` is used as selector. (optional, string) -- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) +- `executable`: The absolute path of the Heidi executable. If not provided, the default value from the plugin settings is used. (optional, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.LuceneQueryParser.md b/docs/RepoM.Plugin.LuceneQueryParser.md index 2db98493..56713f43 100644 --- a/docs/RepoM.Plugin.LuceneQueryParser.md +++ b/docs/RepoM.Plugin.LuceneQueryParser.md @@ -1,10 +1,10 @@ # Lucene Query Parser -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. To search for repositories, you can use a repom-dialect of Lucene query syntax. diff --git a/docs/RepoM.Plugin.SonarCloud.md b/docs/RepoM.Plugin.SonarCloud.md index 6e5610e8..c3d49718 100644 --- a/docs/RepoM.Plugin.SonarCloud.md +++ b/docs/RepoM.Plugin.SonarCloud.md @@ -2,9 +2,9 @@ This module integrates with SonarCloud. Currently, the only functionality is to star a given repository in SonarCloud using the repository action. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -23,15 +23,15 @@ The following default configuration is used: Properties: - `PersonalAccessToken`: Personal Access Token to access SonarCloud. -- `BaseUrl`: SonarCloud url. Most likely `https//sonarcloud.io`. +- `BaseUrl`: SonarCloud url. Most likely `https//sonarcloud.io`. -## sonarcloud-set-favorite@1 +## sonarcloud-set-favorite@1 -Action to mark a repository as favorite within SonarCloud. +Action to mark a repository as favorite within SonarCloud. Action specific properties: -- `project`: The SonarCloud project key. (required, evaluated, string) +- `project`: The SonarCloud project key. (required, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.Statistics.md b/docs/RepoM.Plugin.Statistics.md index a3b8f984..2e22ddf9 100644 --- a/docs/RepoM.Plugin.Statistics.md +++ b/docs/RepoM.Plugin.Statistics.md @@ -2,9 +2,9 @@ This module add functionality to keep track of actions performed on repositories. This can be used in orderings (and mabye later on in filtering) of repositories. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -23,4 +23,4 @@ The following default configuration is used: Properties: - `PersistenceBuffer`: Timespan for buffered events before making them persistant (ie. `00:05:00` for five minutes). Must be greater then or equal to `00:00:10` (10 seconds). -- `RetentionDays`: Number of days to keep statical information before deleting them. +- `RetentionDays`: Number of days to keep statical information before deleting them. diff --git a/docs/RepoM.Plugin.WebBrowser.md b/docs/RepoM.Plugin.WebBrowser.md index 4bf444ba..04709ac7 100644 --- a/docs/RepoM.Plugin.WebBrowser.md +++ b/docs/RepoM.Plugin.WebBrowser.md @@ -2,9 +2,9 @@ The WebBrowser module provides a repository action to open an URL in a given webbrowser. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running. @@ -23,16 +23,16 @@ The following default configuration is used: Properties: - `Browsers`: Dictionary of known browsers and their path to use for opening urls. -- `Profiles`: Profiles to use. +- `Profiles`: Profiles to use. -## browser@1 +## browser@1 -Action opening a webbrowser with the provided url. +Action opening a webbrowser with the provided url. Action specific properties: - `url`: The url to browse to. (required, evaluated, string) -- `profile`: profile name used to select browser and browser profile (optional, evaluated, string) +- `profile`: profile name used to select browser and browser profile (optional, evaluated, string) Example: diff --git a/docs/RepoM.Plugin.WindowsExplorerGitInfo.md b/docs/RepoM.Plugin.WindowsExplorerGitInfo.md index dc8a1ea0..f46d93d3 100644 --- a/docs/RepoM.Plugin.WindowsExplorerGitInfo.md +++ b/docs/RepoM.Plugin.WindowsExplorerGitInfo.md @@ -6,8 +6,8 @@ As an extra goodie for Windows users, RepoM automatically detects open File Expl Note that for Windows 11 users, the title will not be updated but in the taskbar the additional git information is still visible. -To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. +To use this module, make sure it is enabled in RepoM by opening the menu and navigate to 'Plugins'. When enabling or disabling a plugin, you should restart RepoM. -## Configuration +## Configuration -This module has no configuration. +This module has no configuration. diff --git a/docs/Settings.md b/docs/Settings.md index f4cf5df0..291937d5 100644 --- a/docs/Settings.md +++ b/docs/Settings.md @@ -4,7 +4,7 @@ When RepoM starts for the first time, a configuration file wil be created. Most To do this, make sure RepoM is not running. -## Configuration +## Configuration This is the default configuration. @@ -26,7 +26,7 @@ This is the default configuration. ``` -Properties: +Properties: - `SortKey`: The selected sorting strategy. Sorting strategies can be configured manually in `RepoM.Ordering.yaml`. (optional, UI configured) - `SelectedQueryParser`: The selected query parser. Query parsers can be added by plugins. (optional, UI configured) @@ -36,4 +36,4 @@ Properties: +- `Plugins`: List of plugins. (optional, UI configured) From 9f0ba4cd533f84580b278b8d2a9ff60c646f8e27 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 09:11:20 +0200 Subject: [PATCH 05/14] update small issues --- .../RepositoryVariableProvider.cs | 124 +++++++++++------- .../VariableProviderAdapter.cs | 2 +- .../Internal/AzureDevOpsPullRequestService.cs | 25 +++- .../Services/WebBrowserConfiguration.cs | 4 +- 4 files changed, 103 insertions(+), 52 deletions(-) diff --git a/src/RepoM.Api/IO/VariableProviders/RepositoryVariableProvider.cs b/src/RepoM.Api/IO/VariableProviders/RepositoryVariableProvider.cs index bd22e642..38022b09 100644 --- a/src/RepoM.Api/IO/VariableProviders/RepositoryVariableProvider.cs +++ b/src/RepoM.Api/IO/VariableProviders/RepositoryVariableProvider.cs @@ -1,6 +1,7 @@ namespace RepoM.Api.IO.VariableProviders; using System; +using System.Diagnostics.CodeAnalysis; using System.Linq; using RepoM.Core.Plugin.Repository; @@ -32,82 +33,115 @@ private static string ProvideString(RepositoryContext context, string key) var startIndex = "Repository.".Length; var keySuffix = key[startIndex..]; - if ("Name".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + if (TryProvideProperties(repository, keySuffix, out string? result)) { - return repository.Name; + return result; } - if ("Path".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + // legacy + if ("RemoteUrls".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) { - return repository.Path; + return string.Join("|", repository.Remotes.Select(x => x.Url)); } - - if ("SafePath".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + + if (keySuffix.StartsWith("Remote.", StringComparison.CurrentCultureIgnoreCase)) { - return repository.SafePath; + startIndex = "Remote.".Length; + keySuffix = keySuffix[startIndex..]; + + var splits = keySuffix.Split('.'); + if (splits.Length != 2) + { + return string.Empty; + } + + if (TryProvideRemoteProperty(repository, splits[0], splits[1], out result)) + { + return result; + } + + return string.Empty; } - if ("Location".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + throw new NotImplementedException(); + } + + private static bool TryProvideProperties(IRepository repository, string key, [NotNullWhen(true)] out string? result) + { + if ("Name".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - return repository.Location; + result = repository.Name; + return true; } - if ("CurrentBranch".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + if ("Path".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - return repository.CurrentBranch; + result = repository.Path; + return true; } - if ("Branches".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + if ("SafePath".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - return string.Join("|", repository.Branches); + result = repository.SafePath; + return true; } - if ("LocalBranches".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + if ("Location".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - return string.Join("|", repository.LocalBranches); + result = repository.Location; + return true; } - // legacy - if ("RemoteUrls".Equals(keySuffix, StringComparison.CurrentCultureIgnoreCase)) + if ("CurrentBranch".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - return string.Join("|", repository.Remotes.Select(x => x.Url)); + result = repository.CurrentBranch; + return true; } - if (keySuffix.StartsWith("Remote.", StringComparison.CurrentCultureIgnoreCase)) + if ("Branches".Equals(key, StringComparison.CurrentCultureIgnoreCase)) { - startIndex = "Remote.".Length; - keySuffix = keySuffix[startIndex..]; + result = string.Join("|", repository.Branches); + return true; + } - var splits = keySuffix.Split('.'); - if (splits.Length != 2) - { - return string.Empty; - } + if ("LocalBranches".Equals(key, StringComparison.CurrentCultureIgnoreCase)) + { + result = string.Join("|", repository.LocalBranches); + return true; + } - Remote? remote = repository.Remotes.Find(x => x.Key.Equals(splits[0], StringComparison.CurrentCultureIgnoreCase)); - if (remote == null) - { - return string.Empty; - } + result = null; + return false; + } - if ("url".Equals(splits[1], StringComparison.CurrentCultureIgnoreCase)) - { - return remote.Url; - } + private static bool TryProvideRemoteProperty(IRepository repository, string remoteName, string property, [NotNullWhen(true)] out string? result) + { + Remote? remote = repository.Remotes.Find(x => x.Key.Equals(remoteName, StringComparison.CurrentCultureIgnoreCase)); + if (remote == null) + { + result = string.Empty; + return true; + } - if ("key".Equals(splits[1], StringComparison.CurrentCultureIgnoreCase)) - { - return remote.Key; - } + if ("url".Equals(property, StringComparison.CurrentCultureIgnoreCase)) + { + result = remote.Url; + return true; + } - if ("name".Equals(splits[1], StringComparison.CurrentCultureIgnoreCase)) - { - return remote.Name; - } + if ("key".Equals(property, StringComparison.CurrentCultureIgnoreCase)) + { + result = remote.Key; + return true; + } - return string.Empty; + if ("name".Equals(property, StringComparison.CurrentCultureIgnoreCase)) + { + result = remote.Name; + return true; } - throw new NotImplementedException(); + result = null; + return false; } } \ No newline at end of file diff --git a/src/RepoM.Api/IO/VariableProviders/VariableProviderAdapter.cs b/src/RepoM.Api/IO/VariableProviders/VariableProviderAdapter.cs index d5c15965..eb8056bc 100644 --- a/src/RepoM.Api/IO/VariableProviders/VariableProviderAdapter.cs +++ b/src/RepoM.Api/IO/VariableProviders/VariableProviderAdapter.cs @@ -47,6 +47,6 @@ public bool CanProvide(string key) private PluginVariableProvider? GetProvider(string key) { - return _variableProviderImplementation.FirstOrDefault(x => x.CanProvide(key)); + return Array.Find(_variableProviderImplementation, item => item.CanProvide(key)); } } \ No newline at end of file diff --git a/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs b/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs index 97d0c9ea..2e515862 100644 --- a/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs +++ b/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs @@ -88,7 +88,12 @@ public Task InitializeAsync() public async Task CreatePullRequestWithAutoCompleteAsync(IRepository repository, string projectId, List reviewersIds, string toBranch, int mergeStrategy, string? title = null, bool isDraft = false, bool includeWorkItems = true, bool openInBrowser = false, bool deleteSourceBranch = true, bool transitionWorkItems = true, CancellationToken cancellationToken = default) { - GitPullRequest pr = await CreatePullRequestInternalAsync(repository, projectId, reviewersIds, toBranch, title, isDraft, includeWorkItems, cancellationToken); + GitPullRequest? pr = await CreatePullRequestInternalAsync(repository, projectId, reviewersIds, toBranch, title, isDraft, includeWorkItems, cancellationToken); + + if (pr == null) + { + return; + } Guid repoId = FindRepositoryGuid(repository); @@ -117,7 +122,12 @@ public async Task CreatePullRequestWithAutoCompleteAsync(IRepository repository, public async Task CreatePullRequestAsync(IRepository repository, string projectId, List reviewersIds, string toBranch, string? title = null, bool isDraft = false, bool includeWorkItems = true, bool openInBrowser = false, CancellationToken cancellationToken = default) { - GitPullRequest pr = await CreatePullRequestInternalAsync(repository, projectId, reviewersIds, toBranch, title, isDraft, includeWorkItems, cancellationToken); + GitPullRequest? pr = await CreatePullRequestInternalAsync(repository, projectId, reviewersIds, toBranch, title, isDraft, includeWorkItems, cancellationToken); + + if (pr == null) + { + return; + } if (openInBrowser) { @@ -125,7 +135,7 @@ public async Task CreatePullRequestAsync(IRepository repository, string projectI } } - private async Task CreatePullRequestInternalAsync(IRepository repository, string projectId, List reviewersIds, string toBranch, string? title = null, bool isDraft = false, bool includeWorkItems = true, CancellationToken cancellationToken = default) + private async Task CreatePullRequestInternalAsync(IRepository repository, string projectId, List reviewersIds, string toBranch, string? title = null, bool isDraft = false, bool includeWorkItems = true, CancellationToken cancellationToken = default) { title ??= repository.CurrentBranch[(repository.CurrentBranch.IndexOf('/') + 1)..]; @@ -172,7 +182,14 @@ private async Task CreatePullRequestInternalAsync(IRepository re _ = response.EnsureSuccessStatusCode(); var responseContent = await response.Content.ReadAsStringAsync(cancellationToken) ?? throw new Exception("Invalid return type"); - return JsonConvert.DeserializeObject(responseContent); + GitPullRequest? result = JsonConvert.DeserializeObject(responseContent); + + if (result == null) + { + _logger.LogWarning($"Could not Deserialize as {nameof(GetPullRequests)}."); + } + + return result; } public int CountPullRequests(IRepository repository) diff --git a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs index eb9c10cb..eaa8786b 100644 --- a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs +++ b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserConfiguration.cs @@ -4,9 +4,9 @@ namespace RepoM.Plugin.WebBrowser.Services; internal class WebBrowserConfiguration { - public Dictionary Browsers { get; init; } + public Dictionary Browsers { get; init; } = new(); - public Dictionary Profiles { get; init; } + public Dictionary Profiles { get; init; } = new(); } internal class BrowserProfileConfig From 4e4437e5cf4860d6a6acd36f4b9893b9996ad144 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 10:56:50 +0200 Subject: [PATCH 06/14] tests --- .../Services/WebBrowserService.cs | 12 +- .../WebBrowserServiceTest.cs | 120 ++++++++++++++++++ 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs index f38951ad..c226205d 100644 --- a/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs +++ b/src/RepoM.Plugin.WebBrowser/Services/WebBrowserService.cs @@ -19,7 +19,7 @@ public bool ProfileExist(string name) public void OpenUrl(string url) { - ProcessHelper.StartProcess(url, string.Empty); + StartProcess(url, string.Empty); } public void OpenUrl(string url, string profile) @@ -40,7 +40,7 @@ public void OpenUrl(string url, string profile) if (string.IsNullOrWhiteSpace(profileConfig.CommandLineArguments)) { - ProcessHelper.StartProcess(browser, url); + StartProcess(browser, url); return; } @@ -54,6 +54,12 @@ public void OpenUrl(string url, string profile) commandLinesArgs += " " + url; } - ProcessHelper.StartProcess(browser, commandLinesArgs); + StartProcess(browser, commandLinesArgs); + } + + // virtual because of testing + protected virtual void StartProcess(string process, string arguments) + { + ProcessHelper.StartProcess(process, arguments); } } \ No newline at end of file diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs index c19abe0b..86daec25 100644 --- a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs +++ b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs @@ -1,6 +1,7 @@ namespace RepoM.Plugin.WebBrowser.Tests; using System; +using System.Collections.Generic; using FluentAssertions; using RepoM.Plugin.WebBrowser.Services; using VerifyXunit; @@ -20,4 +21,123 @@ public void Ctor_ShouldThrow_WhenArgumentNull() // assert act1.Should().Throw(); } + + [Fact] + public void ProfileExist_ShouldReturnFalse_WhenNoProfilesDefined() + { + + // arrange + var config = new WebBrowserConfiguration(); + var sut = new WebBrowserService(config); + + // act + var result = sut.ProfileExist("name"); + + // assert + _ = result.Should().BeFalse(); + } + + [Fact] + public void ProfileExist_ShouldReturnFalse_WhenNoProfileNameDoesNotMatchCase() + { + + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "Name", new BrowserProfileConfig() }, + }, + }; + var sut = new WebBrowserService(config); + + // act + var result = sut.ProfileExist("name"); + + // assert + _ = result.Should().BeFalse(); + } + + [Fact] + public void ProfileExist_ShouldReturnTrue_WhenProfileExists() + { + + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "name1", new BrowserProfileConfig() }, + { "name2", new BrowserProfileConfig() }, + { "name3", new BrowserProfileConfig() }, + }, + }; + var sut = new WebBrowserService(config); + + // act + var result = sut.ProfileExist("name2"); + + // assert + _ = result.Should().BeTrue(); + } + + [Fact] + public void OpenUrl_ShouldStartProcess() + { + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "name1", new BrowserProfileConfig() }, + { "name2", new BrowserProfileConfig() }, + { "name3", new BrowserProfileConfig() }, + }, + }; + var sut = new DummyWebBrowserService(config); + + // act + sut.OpenUrl("https://google.com"); + + // assert + sut.StartProcessCalled.Should().BeEquivalentTo("https://google.com - "); + } + + [Fact] + public void OpenUrl_WithProfile_ShouldStartProcess() + { + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "Private", new BrowserProfileConfig { BrowserName = "Edge", CommandLineArguments = "\"--profile 23 \" {url}", } }, + }, + Browsers = new() + { + { "Edge", "msedge.exe" }, + }, + }; + var sut = new DummyWebBrowserService(config); + + // act + sut.OpenUrl("https://google.com", "Private"); + + // assert + sut.StartProcessCalled.Should().BeEquivalentTo("msedge.exe - \"--profile 23 \" https://google.com"); + } +} + +file class DummyWebBrowserService : WebBrowserService +{ + public DummyWebBrowserService(WebBrowserConfiguration configuration) : base(configuration) + { + } + + public List StartProcessCalled { get; } = new(1); + + protected override void StartProcess(string process, string arguments) + { + StartProcessCalled.Add(process + " - " + arguments); + } } \ No newline at end of file From 7333d5682a9aed0040943820481a2551c7083409 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 11:09:52 +0200 Subject: [PATCH 07/14] update --- .../Services/IWebBrowserService.cs | 2 - .../BrowseActionExecutorTests.cs | 65 +++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 tests/RepoM.Plugin.WebBrowser.Tests/RepositoryActions/BrowseActionExecutorTests.cs diff --git a/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs b/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs index 1e68fe2e..d871686b 100644 --- a/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs +++ b/src/RepoM.Plugin.WebBrowser/Services/IWebBrowserService.cs @@ -2,8 +2,6 @@ namespace RepoM.Plugin.WebBrowser.Services; internal interface IWebBrowserService { - bool ProfileExist(string name); - void OpenUrl(string url); void OpenUrl(string url, string profile); diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/RepositoryActions/BrowseActionExecutorTests.cs b/tests/RepoM.Plugin.WebBrowser.Tests/RepositoryActions/BrowseActionExecutorTests.cs new file mode 100644 index 00000000..6566c35b --- /dev/null +++ b/tests/RepoM.Plugin.WebBrowser.Tests/RepositoryActions/BrowseActionExecutorTests.cs @@ -0,0 +1,65 @@ +namespace RepoM.Plugin.WebBrowser.Tests.RepositoryActions; + +using System; +using FakeItEasy; +using FluentAssertions; +using RepoM.Core.Plugin.Repository; +using RepoM.Plugin.WebBrowser.RepositoryActions; +using RepoM.Plugin.WebBrowser.RepositoryActions.Actions; +using RepoM.Plugin.WebBrowser.Services; +using Xunit; + +public class BrowseActionExecutorTests +{ + private readonly IRepository _repository; + private readonly IWebBrowserService _service; + private readonly BrowseActionExecutor _sut; + + public BrowseActionExecutorTests() + { + _repository = A.Fake(); + _service = A.Fake(); + _sut = new BrowseActionExecutor(_service); + } + + [Fact] + public void Ctor_ShouldThrow_WhenArgumentNull() + { + // arrange + + // act + Func act1 = () => new BrowseActionExecutor(null!); + + // assert + act1.Should().Throw(); + } + + [Fact] + public void Execute_ShouldCallOpenUrlWithoutProfile_WhenProfileIsNull() + { + // arrange + + // act + _sut.Execute(_repository, new BrowseAction("url", null)); + + // assert + A.CallTo(() => _service.OpenUrl("url")).MustHaveHappenedOnceExactly(); + A.CallTo(() => _service.OpenUrl(A._, A._)).MustNotHaveHappened(); + } + + [Theory] + [InlineData("profile")] + [InlineData("")] + [InlineData(" ")] + public void Execute_ShouldCallOpenUrlWithProfile_WhenProfileIsNotNull(string profile) + { + // arrange + + // act + _sut.Execute(_repository, new BrowseAction("url", profile)); + + // assert + A.CallTo(() => _service.OpenUrl(A._)).MustNotHaveHappened(); + A.CallTo(() => _service.OpenUrl("url", profile)).MustHaveHappenedOnceExactly(); + } +} \ No newline at end of file From da14c345d21c0a8d7675f570cdb207055e20e813 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 11:27:29 +0200 Subject: [PATCH 08/14] update --- .../WebBrowserServiceTest.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs index 86daec25..f1fcc170 100644 --- a/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs +++ b/tests/RepoM.Plugin.WebBrowser.Tests/WebBrowserServiceTest.cs @@ -126,6 +126,54 @@ public void OpenUrl_WithProfile_ShouldStartProcess() // assert sut.StartProcessCalled.Should().BeEquivalentTo("msedge.exe - \"--profile 23 \" https://google.com"); } + + [Fact] + public void OpenUrl_WithProfile_ShouldStartProcessWithoutProfile_WhenProfileNotExists() + { + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "Private", new BrowserProfileConfig { BrowserName = "Edge", CommandLineArguments = "\"--profile 23 \" {url}", } }, + }, + Browsers = new() + { + { "Edge", "msedge.exe" }, + }, + }; + var sut = new DummyWebBrowserService(config); + + // act + sut.OpenUrl("https://google.com", "Private-Not-Exists"); + + // assert + sut.StartProcessCalled.Should().BeEquivalentTo("https://google.com - "); + } + + [Fact] + public void OpenUrl_WithProfile_ShouldStartProcessWithoutProfile_WhenBrowserNotExists() + { + // arrange + var config = new WebBrowserConfiguration + { + Profiles = new() + { + { "Private", new BrowserProfileConfig { BrowserName = "InvalidBrowser", CommandLineArguments = "\"--profile 23 \" {url}", } }, + }, + Browsers = new() + { + { "Edge", "msedge.exe" }, + }, + }; + var sut = new DummyWebBrowserService(config); + + // act + sut.OpenUrl("https://google.com", "Private"); + + // assert + sut.StartProcessCalled.Should().BeEquivalentTo("https://google.com - "); + } } file class DummyWebBrowserService : WebBrowserService From 345500559c9a9d31e92c99684e27a115b3b81b90 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 12:04:38 +0200 Subject: [PATCH 09/14] Update docs --- .../WebBrowserConfigV1.cs | 4 +- .../WebBrowserPackage.cs | 29 ++++++++++++- .../Configuration/DocsModuleSettingsTests.cs | 42 +++++++++++++++---- ...ettings_WebBrowserPackage#desc.verified.md | 32 +++++++++++++- ...leSettingsTests.VerifyChanges.verified.txt | 21 ++++++++++ 5 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs index 4946b7df..c5a72a67 100644 --- a/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs +++ b/src/RepoM.Plugin.WebBrowser/PersistentConfiguration/WebBrowserConfigV1.cs @@ -9,10 +9,10 @@ public class WebBrowserConfigV1 /// /// Dictionary of known browsers and their path to use for opening urls. /// - public Dictionary? Browsers { get; set; } = new(); + public Dictionary? Browsers { get; set; } /// /// Profiles to use. /// - public Dictionary? Profiles { get; set; } = new(); + public Dictionary? Profiles { get; set; } } \ No newline at end of file diff --git a/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs b/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs index f4fca63d..641dd6e1 100644 --- a/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs +++ b/src/RepoM.Plugin.WebBrowser/WebBrowserPackage.cs @@ -82,11 +82,36 @@ private static async Task PersistDefaultConfigAsync(IPackage { var config = new WebBrowserConfigV1 { - Browsers = new Dictionary(), - Profiles = new Dictionary(), + Browsers = null, + Profiles = null, }; await packageConfiguration.PersistConfigurationAsync(config, CurrentConfigVersion.VERSION).ConfigureAwait(false); return config; } + + + /// This method is used by reflection to generate documentation file> + [UsedImplicitly] + [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Reflection")] + private static async Task PersistExampleConfigAsync(IPackageConfiguration packageConfiguration) + { + var config = new WebBrowserConfigV1 + { + Browsers = new Dictionary + { + { "Edge", "C:\\PathTo\\msedge.exe" }, + { "FireFox", "C:\\PathTo\\Mozilla\\firefox.exe" }, + }, + Profiles = new Dictionary + { + { "Work", new ProfileConfig { BrowserName = "Edge", CommandLineArguments = "\"--profile-directory=Profile 4\" {url}", } }, + { "Incognito", new ProfileConfig { BrowserName = "Edge", CommandLineArguments = "-inprivate", } }, + { "Incognito2", new ProfileConfig { BrowserName = "FireFox", CommandLineArguments = "-inprivate {url}", } }, + }, + }; + + await packageConfiguration.PersistConfigurationAsync(config, CurrentConfigVersion.VERSION).ConfigureAwait(false); + return config; + } } \ No newline at end of file diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs b/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs index ec7b7295..8054cbb8 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs @@ -46,6 +46,12 @@ public async Task VerifyChanges() { var (config, _) = await PersistDefaultConfigAsync(p); results.Add(p.GetType().Name, config); + + var (configExample, _) = await PersistExampleConfigAsync(p); + if (configExample != null) + { + results.Add(p.GetType().Name + "_Example", configExample); + } } // assert @@ -71,6 +77,8 @@ public async Task DocsModuleSettings(IPackage package) } else { + (_, string? examplePersistedConfig) = await PersistExampleConfigAsync(package); + var builtinClassNames = new Dictionary { [config!.GetType().Name] = "config", @@ -105,7 +113,7 @@ public async Task DocsModuleSettings(IPackage package) sb.Append(classWriter.Properties); } - var configWithSnippetDocumentationMarkdown = CreateConfigWithSnippetDocumentationMarkdown(persistedConfig/*$"Generated_DefaultConfig_{packageName}"*/); + var configWithSnippetDocumentationMarkdown = CreateConfigWithSnippetDocumentationMarkdown(persistedConfig, examplePersistedConfig); if (!string.IsNullOrWhiteSpace(sb.ToString())) { @@ -122,9 +130,9 @@ public async Task DocsModuleSettings(IPackage package) } } - private static string CreateConfigWithSnippetDocumentationMarkdown(string? snippet) + private static string CreateConfigWithSnippetDocumentationMarkdown(string? snippet, string? exampleSnippet = null) { - return new StringBuilder() + var sb = new StringBuilder() .AppendLine("## Configuration") .AppendLine(string.Empty) .AppendLine("This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running.") @@ -133,8 +141,19 @@ private static string CreateConfigWithSnippetDocumentationMarkdown(string? snipp .AppendLine(string.Empty) .AppendLine("```json") .AppendLine(snippet) - .AppendLine("```") - .ToString(); + .AppendLine("```"); + + if (!string.IsNullOrWhiteSpace(exampleSnippet)) + { + sb.AppendLine(string.Empty) + .AppendLine("For example:") + .AppendLine(string.Empty) + .AppendLine("```json") + .AppendLine(exampleSnippet) + .AppendLine("```"); + } + + return sb.ToString(); } private static string CreateConfigWithoutSnippetDocumentationMarkdown() @@ -149,9 +168,18 @@ private static string CreateConfigWithoutSnippetDocumentationMarkdown() private async Task> PersistDefaultConfigAsync(IPackage package) { - Type type = package.GetType(); - MethodInfo? methodInfo = type.GetMethod("PersistDefaultConfigAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + MethodInfo? methodInfo = package.GetType().GetMethod("PersistDefaultConfigAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + return await PersistUsingMethodAsync(package, methodInfo).ConfigureAwait(false); + } + private async Task> PersistExampleConfigAsync(IPackage package) + { + MethodInfo? methodInfo = package.GetType().GetMethod("PersistExampleConfigAsync", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); + return await PersistUsingMethodAsync(package, methodInfo).ConfigureAwait(false); + } + + private async Task> PersistUsingMethodAsync(IPackage package, MethodInfo? methodInfo) + { if (methodInfo == null) { return new Tuple(null, null); diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md index f0a324e2..8122defe 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage#desc.verified.md @@ -8,8 +8,36 @@ The following default configuration is used: { "Version": 1, "Settings": { - "Browsers": {}, - "Profiles": {} + "Browsers": null, + "Profiles": null + } +} +``` + +For example: + +```json +{ + "Version": 1, + "Settings": { + "Browsers": { + "Edge": "C:\\PathTo\\msedge.exe", + "FireFox": "C:\\PathTo\\Mozilla\\firefox.exe" + }, + "Profiles": { + "Work": { + "BrowserName": "Edge", + "CommandLineArguments": "\"--profile-directory=Profile 4\" {url}" + }, + "Incognito": { + "BrowserName": "Edge", + "CommandLineArguments": "-inprivate" + }, + "Incognito2": { + "BrowserName": "FireFox", + "CommandLineArguments": "-inprivate {url}" + } + } } } ``` diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt index 49a39cd7..dad15fde 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.VerifyChanges.verified.txt @@ -20,5 +20,26 @@ WebBrowserPackage: { $type: WebBrowserConfigV1 }, + WebBrowserPackage_Example: { + $type: WebBrowserConfigV1, + Browsers: { + Edge: C:\PathTo\msedge.exe, + FireFox: C:\PathTo\Mozilla\firefox.exe + }, + Profiles: { + Incognito: { + BrowserName: Edge, + CommandLineArguments: -inprivate + }, + Incognito2: { + BrowserName: FireFox, + CommandLineArguments: -inprivate {url} + }, + Work: { + BrowserName: Edge, + CommandLineArguments: "--profile-directory=Profile 4" {url} + } + } + }, WindowsExplorerGitInfoPackage: null } \ No newline at end of file From 13a115bd19cc0da8e17cdb4b7cb49f969b34e056 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 12:04:59 +0200 Subject: [PATCH 10/14] .. --- ...gsTests.DocsModuleSettings_WebBrowserPackage.verified.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json index 1fcd3075..6577532a 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/ModuleSettingsDocs/DocsModuleSettingsTests.DocsModuleSettings_WebBrowserPackage.verified.json @@ -1,7 +1,7 @@ { "Version": 1, "Settings": { - "Browsers": {}, - "Profiles": {} + "Browsers": null, + "Profiles": null } } \ No newline at end of file From cf6792bfe8bf8b03e8095e8e854761dbf0bc5567 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 13 Sep 2023 10:06:24 +0000 Subject: [PATCH 11/14] Docs changes --- docs/RepoM.Plugin.WebBrowser.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/docs/RepoM.Plugin.WebBrowser.md b/docs/RepoM.Plugin.WebBrowser.md index 04709ac7..7e63feda 100644 --- a/docs/RepoM.Plugin.WebBrowser.md +++ b/docs/RepoM.Plugin.WebBrowser.md @@ -14,8 +14,36 @@ The following default configuration is used: { "Version": 1, "Settings": { - "Browsers": {}, - "Profiles": {} + "Browsers": null, + "Profiles": null + } +} +``` + +For example: + +```json +{ + "Version": 1, + "Settings": { + "Browsers": { + "Edge": "C:\\PathTo\\msedge.exe", + "FireFox": "C:\\PathTo\\Mozilla\\firefox.exe" + }, + "Profiles": { + "Work": { + "BrowserName": "Edge", + "CommandLineArguments": "\"--profile-directory=Profile 4\" {url}" + }, + "Incognito": { + "BrowserName": "Edge", + "CommandLineArguments": "-inprivate" + }, + "Incognito2": { + "BrowserName": "FireFox", + "CommandLineArguments": "-inprivate {url}" + } + } } } ``` From c5d8156ff87250a936c6175ff60cbe0956d91c74 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 13:13:18 +0200 Subject: [PATCH 12/14] update --- .../DocumentationFiles/Browser01.testfile.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml index 351f5e77..cfc5f46d 100644 --- a/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml +++ b/tests/RepoM.Plugin.WebBrowser.Tests/DocumentationFiles/Browser01.testfile.yaml @@ -7,12 +7,12 @@ repository-actions: - type: browser@1 active: true variables: [] - name: 'My Github' - url: 'https://github.com/coenm' + name: My Github + url: https://github.com/coenm - type: browser@1 - name: 'My Github' - url: 'https://github.com/coenm' + name: My Github + url: https://github.com/coenm profile: edge # end-snippet \ No newline at end of file From 4c4236cc3e0a2df69526936238c1c08f2217fd93 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Wed, 13 Sep 2023 11:14:32 +0000 Subject: [PATCH 13/14] Docs changes --- docs/RepoM.Plugin.WebBrowser.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/RepoM.Plugin.WebBrowser.md b/docs/RepoM.Plugin.WebBrowser.md index 7e63feda..ebd3c870 100644 --- a/docs/RepoM.Plugin.WebBrowser.md +++ b/docs/RepoM.Plugin.WebBrowser.md @@ -72,12 +72,12 @@ repository-actions: - type: browser@1 active: true variables: [] - name: 'My Github' - url: 'https://github.com/coenm' + name: My Github + url: https://github.com/coenm - type: browser@1 - name: 'My Github' - url: 'https://github.com/coenm' + name: My Github + url: https://github.com/coenm profile: edge ``` snippet source | anchor From 2dc5967ec356006c4f0cdfa48e292cff3ae61436 Mon Sep 17 00:00:00 2001 From: Coen van den Munckhof Date: Wed, 13 Sep 2023 13:17:12 +0200 Subject: [PATCH 14/14] .. --- .../Configuration/DocsModuleSettingsTests.cs | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs b/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs index 8054cbb8..9a119d21 100644 --- a/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs +++ b/tests/RepoM.Plugin.Misc.Tests/Configuration/DocsModuleSettingsTests.cs @@ -132,16 +132,16 @@ public async Task DocsModuleSettings(IPackage package) private static string CreateConfigWithSnippetDocumentationMarkdown(string? snippet, string? exampleSnippet = null) { - var sb = new StringBuilder() - .AppendLine("## Configuration") - .AppendLine(string.Empty) - .AppendLine("This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running.") - .AppendLine(string.Empty) - .AppendLine("The following default configuration is used:") - .AppendLine(string.Empty) - .AppendLine("```json") - .AppendLine(snippet) - .AppendLine("```"); + StringBuilder sb = new StringBuilder() + .AppendLine("## Configuration") + .AppendLine(string.Empty) + .AppendLine("This plugin has specific configuration stored in a separate configuration file stored in `%APPDATA%/RepoM/Module/` directory. This configuration file should be edit manually. The safest way to do this is, is when RepoM is not running.") + .AppendLine(string.Empty) + .AppendLine("The following default configuration is used:") + .AppendLine(string.Empty) + .AppendLine("```json") + .AppendLine(snippet) + .AppendLine("```"); if (!string.IsNullOrWhiteSpace(exampleSnippet)) { @@ -159,11 +159,10 @@ private static string CreateConfigWithSnippetDocumentationMarkdown(string? snipp private static string CreateConfigWithoutSnippetDocumentationMarkdown() { return new StringBuilder() - .AppendLine("## Configuration") - .AppendLine(string.Empty) - .AppendLine("This module has no configuration.") - .ToString(); - + .AppendLine("## Configuration") + .AppendLine(string.Empty) + .AppendLine("This module has no configuration.") + .ToString(); } private async Task> PersistDefaultConfigAsync(IPackage package)