From d987487147db7e9a8ece33e56f95386ce953229c Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:07:58 +0100 Subject: [PATCH 01/17] Update YAML --- src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj | 2 +- src/RepoM.Api/RepoM.Api.csproj | 2 +- .../RepoM.ActionMenu.CodeGen.Tests.csproj | 2 +- .../RepoM.ActionMenu.Core.TestLib.csproj | 2 +- .../RepoM.ActionMenu.Core.Tests.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj b/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj index 9911e86f..d45e7edb 100644 --- a/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj +++ b/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index b6806475..8e9310bd 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -13,7 +13,7 @@ - + diff --git a/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj b/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj index 9199915d..a305a175 100644 --- a/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj +++ b/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj @@ -35,7 +35,7 @@ all - + diff --git a/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj b/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj index d753fec1..d9b6728f 100644 --- a/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj +++ b/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj @@ -34,7 +34,7 @@ all - + diff --git a/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj b/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj index 56e352b4..21c5fcaf 100644 --- a/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj +++ b/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj @@ -36,7 +36,7 @@ all - + From 8174e266fae84cec1ea38d33b7bb54f3735bc718 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:09:11 +0100 Subject: [PATCH 02/17] Simplify code --- src/RepoM.Api/Bootstrapper.cs | 30 +++++++------------ src/RepoM.Api/EnsureStartup.cs | 12 ++------ src/RepoM.Api/Git/DefaultRepositoryMonitor.cs | 4 +-- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/RepoM.Api/Bootstrapper.cs b/src/RepoM.Api/Bootstrapper.cs index 237588eb..aaa54d01 100644 --- a/src/RepoM.Api/Bootstrapper.cs +++ b/src/RepoM.Api/Bootstrapper.cs @@ -1,38 +1,30 @@ namespace RepoM.Api; -using Microsoft.Extensions.Logging; -using RepoM.Api.Common; -using RepoM.Api.IO; -using RepoM.Api.Plugins; -using SimpleInjector; +using System; using System.Collections.Generic; using System.IO.Abstractions; using System.Linq; using System.Reflection; using System.Threading.Tasks; -using System; +using Microsoft.Extensions.Logging; +using RepoM.Api.Common; +using RepoM.Api.IO; +using RepoM.Api.Plugins; using RepoM.Api.Plugins.SimpleInjector; using RepoM.Core.Plugin; using RepoM.Core.Plugin.Common; using RepoM.Core.Plugin.RepositoryOrdering.Configuration; +using SimpleInjector; -public class CoreBootstrapper +public class CoreBootstrapper(IPluginFinder pluginFinder, IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILoggerFactory loggerFactory) { - private readonly IPluginFinder _pluginFinder; - private readonly IFileSystem _fileSystem; - private readonly IAppDataPathProvider _appDataProvider; - private readonly ILoggerFactory _loggerFactory; + private readonly IPluginFinder _pluginFinder = pluginFinder ?? throw new ArgumentNullException(nameof(pluginFinder)); + private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + private readonly IAppDataPathProvider _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); + private readonly ILoggerFactory _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); private static readonly Assembly _thisAssembly = typeof(CoreBootstrapper).Assembly; - public CoreBootstrapper(IPluginFinder pluginFinder, IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILoggerFactory loggerFactory) - { - _pluginFinder = pluginFinder ?? throw new ArgumentNullException(nameof(pluginFinder)); - _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); - _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); - } - public static void RegisterRepositoryScorerConfigurationsTypes(Container container) { foreach (Type type in GetNonAbstractNonGenericInheritedExportedTypesFrom(_thisAssembly)) diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs index 16307919..c9b15c17 100644 --- a/src/RepoM.Api/EnsureStartup.cs +++ b/src/RepoM.Api/EnsureStartup.cs @@ -7,16 +7,10 @@ namespace RepoM.Api; using RepoM.Api.Resources; using RepoM.Core.Plugin.Common; -public class EnsureStartup +public class EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider) { - private readonly IFileSystem _fileSystem; - private readonly IAppDataPathProvider _appDataProvider; - - public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider) - { - _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); - } + private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + private readonly IAppDataPathProvider _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); public async Task EnsureFilesAsync() { diff --git a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs index 8dc4f26d..1e9a07e5 100644 --- a/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs +++ b/src/RepoM.Api/Git/DefaultRepositoryMonitor.cs @@ -60,7 +60,7 @@ public DefaultRepositoryMonitor( _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _autoFetchHandler = autoFetchHandler ?? throw new ArgumentNullException(nameof(autoFetchHandler)); - _repositoryObservers = new Dictionary(); + _repositoryObservers = []; _storeFlushTimer = new Timer(RepositoryStoreFlushTimerCallback, null, Timeout.Infinite, Timeout.Infinite); } @@ -153,7 +153,7 @@ private void ObserveRepositoryChanges() { _logger.LogTrace("ObserveRepositoryChanges start"); - _detectors = new List(); + _detectors = []; foreach (var path in _pathProvider.GetPaths()) { From ac36015a39170134705ed13f9d2832a39d782634 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:09:21 +0100 Subject: [PATCH 03/17] Update logger --- src/RepoM.ActionMenu.CodeGen/RepoM.ActionMenu.CodeGen.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/RepoM.ActionMenu.CodeGen/RepoM.ActionMenu.CodeGen.csproj b/src/RepoM.ActionMenu.CodeGen/RepoM.ActionMenu.CodeGen.csproj index 918aae54..5b9471e7 100644 --- a/src/RepoM.ActionMenu.CodeGen/RepoM.ActionMenu.CodeGen.csproj +++ b/src/RepoM.ActionMenu.CodeGen/RepoM.ActionMenu.CodeGen.csproj @@ -8,7 +8,7 @@ - + From 3269350ebf43e350e35b26cb6dee54807fff0546 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:09:38 +0100 Subject: [PATCH 04/17] Update Default order mechanism --- src/RepoM.Api/Resources/RepoM.Sorting.yaml | 62 ++++++++++------------ 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/src/RepoM.Api/Resources/RepoM.Sorting.yaml b/src/RepoM.Api/Resources/RepoM.Sorting.yaml index 8985b78e..c06ea757 100644 --- a/src/RepoM.Api/Resources/RepoM.Sorting.yaml +++ b/src/RepoM.Api/Resources/RepoM.Sorting.yaml @@ -1,35 +1,12 @@ -Work: - type: composition-comparer@1 - comparers: - - type: score-comparer@1 - score-provider: - type: is-pinned-scorer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Team1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Work - - type: az-comparer@1 - property: Name - weight: 1 -Work Dynamic: +Private: type: composition-comparer@1 comparers: - type: score-comparer@1 score-provider: type: is-pinned-scorer@1 - weight: 1 - - type: score-comparer@1 - score-provider: - type: tag-scorer@1 - weight: 1 - tag: Team1 + weight: 40 + - type: last-opened-comparer@1 + weight: 30 - type: score-comparer@1 score-provider: type: usage-scorer@1 @@ -46,18 +23,31 @@ Work Dynamic: max-items: 5 - until: 168:00:00 weight: 1 - max-items: 10 - - type: last-opened-comparer@1 + max-items: 10 + - type: az-comparer@1 + property: Name weight: 1 +Work: + type: composition-comparer@1 + comparers: - type: score-comparer@1 - score-provider: + score-provider: + type: is-pinned-scorer@1 + weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Team1 + - type: score-comparer@1 + score-provider: type: tag-scorer@1 weight: 1 tag: Work - type: az-comparer@1 property: Name weight: 1 -Prive: +Work Dynamic: type: composition-comparer@1 comparers: - type: score-comparer@1 @@ -68,7 +58,7 @@ Prive: score-provider: type: tag-scorer@1 weight: 1 - tag: Prive + tag: Team1 - type: score-comparer@1 score-provider: type: usage-scorer@1 @@ -88,6 +78,12 @@ Prive: max-items: 10 - type: last-opened-comparer@1 weight: 1 + - type: score-comparer@1 + score-provider: + type: tag-scorer@1 + weight: 1 + tag: Work - type: az-comparer@1 property: Name - weight: 1 \ No newline at end of file + weight: 1 + From d9cb8c47d033ed34b47c3f59e13447bcbc3e601d Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:09:55 +0100 Subject: [PATCH 05/17] Update the hamburger menu options and added checks --- .../Resources/RepositoryActionsV2.yaml | 148 +++++++++++++----- 1 file changed, 110 insertions(+), 38 deletions(-) diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index f3890467..0db27538 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -1,10 +1,14 @@ -context: +ο»Ώcontext: - type: evaluate-script@1 content: |- func is_null(input) ret input == null end + func is_not_null(input) + ret input != null + end + func get_filename(path) ret path | string.split("\\") | array.last end @@ -47,6 +51,17 @@ context: ret repository.branch | string.replace "feature/" "" | string.strip end + func shorten_github_link(github_url) + ret github_url | string.replace "https://github.com/" "" | string.replace ".git" "" | string.strip + end + + func get_remote_name() + if is_null(repository.remotes) || array.size(repository.remotes) == 0 + ret repository.name + end + ret shorten_github_link(repository.remotes[0].url) + end + remote_name_origin = get_remote_origin_name(); is_work_repository = remotes_contain("My-Work"); is_github_repository = remotes_contain("github.com"); @@ -54,7 +69,17 @@ context: solution_files = file.find_files(repository.linux_path, "*.sln"); solution_file = array.first(solution_files); + dir_visual_studio = env.ProgramW6432 + "/Microsoft Visual Studio/"; + dir_windows_terminal_Store = env.LocalAppData + "/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/"; + dir_windows_terminal_Preview = env.LocalAppData + "/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/"; + dir_windows_terminal_Unpackaged = env.LocalAppData + "/Packages/Microsoft/WindowsTerminal/"; + exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; + exe_sourcetree = env.LocalAppData + "/SourceTree/SourceTree.exe"; + exe_gitkraken = env.LocalAppData + "/GitKraken/GitKraken.exe"; + exe_everything = env.ProgramW6432 + "/Everything/Everything.exe"; + exe_terminal_commander = env.ProgramW6432 + "/totalcmd/TOTALCMD64.EXE"; + # Specific var files - type: render-variable@1 @@ -91,29 +116,19 @@ context: action-menu: - type: command@1 - name: Open in Windows File Explorer + name: πŸ“‚ Open in Windows File Explorer command: '"{{ repository.path }}"' -- type: command@1 - name: Open in Windows Terminal - command: wt - arguments: -d "{{ repository.linux_path }}" - -- type: executable@1 - name: 'Open in Windows PowerShell' - executable: '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' - arguments: -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" - # Open in visual studio when exactly one '.sln' file was found: - type: command@1 - name: Open in Visual Studio + name: πŸ—ƒοΈ Open in Visual Studio command: '{{ solution_file }}' - active: array.size(solution_files) == 1 + active: array.size(solution_files) == 1 && file.dir_exists(dir_visual_studio) # Otherwise, Visual studio folder with all '.sln' files when multiple sln files were found: - type: folder@1 - name: Open in Visual Studio - active: array.size(solution_files) > 1 + name: πŸ—ƒοΈ Open in Visual Studio + active: array.size(solution_files) > 1 && file.dir_exists(dir_visual_studio) actions: - type: foreach@1 enumerable: solution_files @@ -123,57 +138,114 @@ action-menu: name: '{{ get_filename(sln) }}' command: '{{ sln }}' -- type: executable@1 - name: Open in Visual Studio Code - executable: '{{ exe_vs_code }}' - arguments: '"{{ repository.linux_path }}"' +- type: command@1 + name: πŸ“ Open in Visual Studio Code + command: code + arguments: '"{{ repository.path }}"' + active: file.file_exists(exe_vs_code) - type: executable@1 name: Open in Sourcetree - executable: '{{ env.LocalAppData }}/SourceTree/SourceTree.exe' + executable: '{{ exe_sourcetree }}' arguments: -f "{{ repository.windows_path }}" + active: file.file_exists(exe_sourcetree) - type: executable@1 - name: Open in Everything - executable: '{{ env.ProgramW6432 }}/Everything/Everything.exe' + name: πŸ“Š Open in GitKraken πŸ¦‘ + executable: '{{ exe_gitkraken }}' + arguments: --path "{{ repository.path }}" + +- type: command@1 + name: 🧾 Open in Windows Terminal + command: wt + arguments: -d "{{ repository.path }}" + active: file.dir_exists(dir_windows_terminal_Store) || file.dir_exists(dir_windows_terminal_Preview) || file.dir_exists(dir_windows_terminal_Unpackaged) + +- type: executable@1 + name: πŸ” Open in Everything + executable: '{{ exe_everything }}' arguments: -s """"{{ repository.path }}""" " + active: file.file_exists(exe_everything) - type: executable@1 name: Open in TotalCommander - executable: '{{ env.ProgramW6432 }}/totalcmd/TOTALCMD64.EXE' + executable: '{{ exe_terminal_commander }}' arguments: /O /T /L="{{ repository.linux_path }}" + active: file.file_exists(exe_terminal_commander) + +# - type: executable@1 +# name: 'Open in Windows PowerShell' +# executable: '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' +# arguments: -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" + +# - type: executable@1 +# name: 'Open in Windows Command Prompt' +# executable: '{{ env.WINDIR }}/System32/cmd.exe' +# arguments: /k cd "{{ repository.linux_path }}" + +- type: separator@1 + +- type: just-text@1 + name: 'Warning: No GitHub remotes to browse to' + active: array.size(repository.remotes) == 0 + +# single remote, create url menu item +- type: url@1 + name: 'πŸ”— GitHub: {{ get_remote_name() }}' + url: '{{ repository.remotes[0].url }}' + active: array.size(repository.remotes) == 1 + +# Multiple remotes, create folder with multiple menu items +- type: folder@1 + name: πŸ”— GitHub remote repositories + active: array.size(repository.remotes) > 1 + actions: + - type: foreach@1 + enumerable: repository.remotes + variable: remote + actions: + - type: url@1 + name: '[{{ remote.key}}] {{ shorten_github_link(remote.url) }}' + url: '{{ remote.url }}' - type: separator@1 - type: folder@1 - name: Git + name: πŸ“¦ Git actions: - - type: browse-repository@1 + # - type: browse-repository@1 + # - type: pin-repository@1 - type: git-fetch@1 - type: git-pull@1 - type: git-push@1 - type: git-checkout@1 - type: separator@1 - -- type: ignore-repository@1 - -- type: separator@1 - active: is_work_repository + # active: is_work_repository - type: folder@1 - name: '-- Examples --' + name: ❓ About {{get_remote_name()}} context: - type: render-variable@1 name: repo_docs_directory value: 'C:\docs\{{ repository.name }}\' actions: - - type: just-text@1 + - type: clipboard-copy@1 name: 'Current branch is {{ repository.branch }}' + text: '{{ repository.branch }}' + + - type: clipboard-copy@1 + name: 'Local path is {{ repository.windows_path }}' + text: '{{ repository.windows_path }}' + + - type: separator@1 + + - type: ignore-repository@1 + name: ❌ Ignore Repository - - type: command@1 - name: 'Create Directory {{ repo_docs_directory }}' - command: cmd - arguments: /k mkdir "{{ repo_docs_directory }}" - active: '!file.dir_exists(repo_docs_directory)' + # - type: command@1 + # name: 'Create Directory {{ repo_docs_directory }}' + # command: cmd + # arguments: /k mkdir "{{ repo_docs_directory }}" + # active: '!file.dir_exists(repo_docs_directory)' From 219bccb1e4d6874a99ec0a2f173fe9fd724a4fe3 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:19:00 +0100 Subject: [PATCH 06/17] Updates default filtering config --- src/RepoM.Api/Resources/TagsV2.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/RepoM.Api/Resources/TagsV2.yaml b/src/RepoM.Api/Resources/TagsV2.yaml index 9570cc93..a86e7595 100644 --- a/src/RepoM.Api/Resources/TagsV2.yaml +++ b/src/RepoM.Api/Resources/TagsV2.yaml @@ -36,11 +36,12 @@ context: tags: -- tag: work - when: is_work_repository +- tag: github + when: 'remotes_contain("github.com")' - tag: private when: '!is_work_repository && repository_path_contains("Projects/Private")' -- tag: github - when: 'remotes_contain("github.com")' \ No newline at end of file +- tag: work + when: is_work_repository + From 155cb9d654587256b3f3e25bb307d4d5c3eb67e3 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:23:59 +0100 Subject: [PATCH 07/17] Changed name of default order scheme --- src/RepoM.Api/Resources/RepoM.Sorting.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/RepoM.Api/Resources/RepoM.Sorting.yaml b/src/RepoM.Api/Resources/RepoM.Sorting.yaml index c06ea757..1f1261e7 100644 --- a/src/RepoM.Api/Resources/RepoM.Sorting.yaml +++ b/src/RepoM.Api/Resources/RepoM.Sorting.yaml @@ -1,4 +1,4 @@ -Private: +Most Active: type: composition-comparer@1 comparers: - type: score-comparer@1 @@ -86,4 +86,3 @@ Work Dynamic: - type: az-comparer@1 property: Name weight: 1 - From df9ca177aaa180020ef67538ad4cc4d938606731 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 02:34:48 +0100 Subject: [PATCH 08/17] Changes default filtering to All and updates Private --- src/RepoM.Api/Resources/RepoM.Filtering.yaml | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/RepoM.Api/Resources/RepoM.Filtering.yaml b/src/RepoM.Api/Resources/RepoM.Filtering.yaml index 52ff09c4..9ba49ed6 100644 --- a/src/RepoM.Api/Resources/RepoM.Filtering.yaml +++ b/src/RepoM.Api/Resources/RepoM.Filtering.yaml @@ -1,12 +1,12 @@ -Work: - name: Work - description: Work filtering +All: + name: All + description: Private repositories always-visible: kind: query@1 - query: is:pinned + query: RepoM OR is:pinned filter: kind: query@1 - query: tag:work + query: Private: name: Private description: Private repositories @@ -15,4 +15,13 @@ Private: query: RepoM OR is:pinned filter: kind: query@1 - query: (-tag:work OR tag:private) \ No newline at end of file + query: tag:private +Work: + name: Work + description: Work filtering + always-visible: + kind: query@1 + query: is:pinned + filter: + kind: query@1 + query: tag:work From 2e2a46cab1a6253ef40077a7606855a6938a1019 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 04:04:39 +0100 Subject: [PATCH 09/17] improve filtering mechanism --- src/RepoM.Api/Resources/RepoM.Filtering.yaml | 9 -- .../IRepositoryFilteringManager.cs | 2 +- .../RepositoryFilteringManager.cs | 90 ++++++++++--------- 3 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/RepoM.Api/Resources/RepoM.Filtering.yaml b/src/RepoM.Api/Resources/RepoM.Filtering.yaml index 9ba49ed6..39415ff4 100644 --- a/src/RepoM.Api/Resources/RepoM.Filtering.yaml +++ b/src/RepoM.Api/Resources/RepoM.Filtering.yaml @@ -1,12 +1,3 @@ -All: - name: All - description: Private repositories - always-visible: - kind: query@1 - query: RepoM OR is:pinned - filter: - kind: query@1 - query: Private: name: Private description: Private repositories diff --git a/src/RepoM.App/RepositoryFiltering/IRepositoryFilteringManager.cs b/src/RepoM.App/RepositoryFiltering/IRepositoryFilteringManager.cs index 5129520b..6821e4bd 100644 --- a/src/RepoM.App/RepositoryFiltering/IRepositoryFilteringManager.cs +++ b/src/RepoM.App/RepositoryFiltering/IRepositoryFilteringManager.cs @@ -27,5 +27,5 @@ public interface IRepositoryFilteringManager bool SetQueryParser(string key); - bool SetFilter(string key); + bool SetFilter(string filterName); } \ No newline at end of file diff --git a/src/RepoM.App/RepositoryFiltering/RepositoryFilteringManager.cs b/src/RepoM.App/RepositoryFiltering/RepositoryFilteringManager.cs index f6e6fcf6..9fb3fd63 100644 --- a/src/RepoM.App/RepositoryFiltering/RepositoryFilteringManager.cs +++ b/src/RepoM.App/RepositoryFiltering/RepositoryFilteringManager.cs @@ -16,7 +16,7 @@ internal class RepositoryFilteringManager : IRepositoryFilteringManager private readonly QueryParserComposition _queryParser; private readonly List _repositoryComparerKeys; private readonly List _preFilterKeys; - private readonly List _queryDictionary; + private readonly Dictionary _queryDictionary; public RepositoryFilteringManager( IAppSettingsService appSettingsService, @@ -38,28 +38,33 @@ public RepositoryFilteringManager( INamedQueryParser defaultParser = queryParsersArray.First(x => x.Name != "Lucene"); INamedQueryParser queryParser = Array.Find(queryParsersArray, x => x.Name == "Lucene") ?? defaultParser; - _queryDictionary = filterSettingsService.Configuration - .Select(x => new RepositoryFilterConfiguration - { - AlwaysVisible = Map(x.Value.AlwaysVisible), - Description = x.Value.Description, - Filter = Map(x.Value.Filter), - Name = x.Key, - }) - .ToList(); - - if (!_queryDictionary.Exists(x => x.Name.Equals("Default", StringComparison.CurrentCultureIgnoreCase))) + _queryDictionary = new Dictionary((int)StringComparison.CurrentCultureIgnoreCase); + foreach (var (key, value) in filterSettingsService.Configuration) { - _queryDictionary.Add(new RepositoryFilterConfiguration - { - AlwaysVisible = null, - Description = "Default (no filtering)", - Filter = null, - Name = "Default", - }); + _queryDictionary.Add(key, new RepositoryFilterConfiguration + { + AlwaysVisible = Map(value.AlwaysVisible), + Description = value.Description, + Filter = Map(value.Filter), + Name = key, + }); + } + + var allConfiguration = new RepositoryFilterConfiguration + { + Name = "All", + AlwaysVisible = null, + Description = "Show all (no filtering) [Default]", + Filter = null, + }; + + if (!_queryDictionary.TryAdd(allConfiguration.Name, allConfiguration)) + { + _logger.LogWarning("Invalid filter config detected: {FilterName}. Overwriting element.", allConfiguration.Name); + _queryDictionary[allConfiguration.Name] = allConfiguration; } - - _preFilterKeys = _queryDictionary.Select(x => x.Name).ToList(); + + _preFilterKeys = _queryDictionary.Keys.ToList(); _queryParser = new QueryParserComposition(queryParsersArray); @@ -69,24 +74,22 @@ public RepositoryFilteringManager( if (string.IsNullOrWhiteSpace(_appSettingsService.QueryParserKey)) { - _logger.LogInformation("Query parser was not set. Pick first one."); + _logger.LogInformation("Query parser was not set. Pick default one one."); SetQueryParser(_repositoryComparerKeys[0]); } else if (!SetQueryParser(_appSettingsService.QueryParserKey)) { - _logger.LogInformation("Could not set query parser '{Key}'. Falling back to first query parser.", _appSettingsService.QueryParserKey); + _logger.LogInformation("Could not set query parser '{Key}'. Falling back to default parser.", _appSettingsService.QueryParserKey); SetQueryParser(_repositoryComparerKeys[0]); } - RepositoryFilterConfiguration first = _queryDictionary[0]; - - if (string.IsNullOrWhiteSpace(_appSettingsService.SelectedFilter)) + if (_queryDictionary.TryGetValue("Default", out RepositoryFilterConfiguration? defaultFilterConfig) && !string.IsNullOrWhiteSpace(_appSettingsService.SelectedFilter)) { - SetFilter(first.Name); + SetFilter(defaultFilterConfig); } - else if (!SetFilter(_appSettingsService.SelectedFilter)) + else { - SetFilter(first.Name); + SetFilter(allConfiguration); } return; @@ -126,7 +129,7 @@ public RepositoryFilteringManager( public IReadOnlyList FilterKeys => _preFilterKeys; public bool SetQueryParser(string key) - { + { if (!_queryParser.SetComparer(key)) { _logger.LogWarning("Could not update/set the comparer key {Key}.", key); @@ -139,20 +142,25 @@ public bool SetQueryParser(string key) return true; } - public bool SetFilter(string key) + private void SetFilter(RepositoryFilterConfiguration filterConfig) + { + PreFilter = filterConfig.Filter ?? TrueQuery.Instance; + AlwaysVisibleFilter = filterConfig.AlwaysVisible; + _appSettingsService.SelectedFilter = filterConfig.Name; + SelectedFilterKey = filterConfig.Name; + SelectedFilterChanged?.Invoke(this, filterConfig.Name); + } + + public bool SetFilter(string filterName) { - RepositoryFilterConfiguration? value = _queryDictionary.Find(x => x.Name == key); - if (value == null) + if (_queryDictionary.TryGetValue(filterName, out RepositoryFilterConfiguration? filterConfig)) { - return false; + SetFilter(filterConfig); + return true; } - - PreFilter = value.Filter ?? TrueQuery.Instance; - AlwaysVisibleFilter = value.AlwaysVisible; - _appSettingsService.SelectedFilter = key; - SelectedFilterKey = key; - SelectedFilterChanged?.Invoke(this, key); - return true; + + _logger.LogWarning("Could not find filter with filterName {Key}.", filterName); + return false; } private sealed class RepositoryFilterConfiguration From 271292ad4e2041fc9b36db533121f8aa41983fad Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 04:27:46 +0100 Subject: [PATCH 10/17] Fixes the fork problem + code cleanup --- ...epositoryActionBrowseRepositoryV1Mapper.cs | 31 +++++++---- .../AzureDevOpsModule.cs | 9 +-- .../Internal/AzureDevOpsPullRequestService.cs | 8 +-- .../Internal/PullRequest.cs | 15 ++--- .../Internal/WorkItemExtractor.cs | 4 +- .../RepositoryActionClipboardCopyV1.cs | 2 +- ...opyToClipboardRepositoryCommandExecutor.cs | 9 +-- .../StatisticsModule.cs | 55 ++++++++----------- .../EnvironmentVariableManager.cs | 15 +---- 9 files changed, 59 insertions(+), 89 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs index 3f4e8db1..307aaf0c 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs @@ -4,7 +4,6 @@ namespace RepoM.ActionMenu.Core.ActionMenu.Model.ActionMenus.BrowseRepository; using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; -using RepoM.ActionMenu.Core.Model; using RepoM.ActionMenu.Interface.ActionMenuFactory; using RepoM.ActionMenu.Interface.UserInterface; using RepoM.ActionMenu.Interface.YamlModel; @@ -21,25 +20,28 @@ protected override async IAsyncEnumerable Map yield break; } - var name = await context.RenderStringAsync(action.Name).ConfigureAwait(false); - if (string.IsNullOrWhiteSpace(name)) - { - name = "Browse remote"; - } + string menuTitle; + //var menuTitle = await context.RenderStringAsync(action.Name).ConfigureAwait(false); + //if (string.IsNullOrWhiteSpace(menuTitle)) + //{ + // menuTitle = "πŸ”—Github: "; + //} var forceSingle = await action.FirstOnly.EvaluateAsync(context).ConfigureAwait(false); if (repository.Remotes.Count == 1 || forceSingle) { - yield return new UserInterfaceRepositoryAction(name, repository) + menuTitle = "πŸ”—Github: " + shorten_github_link(repository.Remotes[0].Url); + yield return new UserInterfaceRepositoryAction(menuTitle, repository) { RepositoryCommand = new BrowseRepositoryCommand(repository.Remotes[0].Url), }; } else { + menuTitle = "πŸ”—GitHub remote repositories"; //πŸ”— yield return new DeferredSubActionsUserInterfaceRepositoryAction( - name, + menuTitle, repository, context, captureScope: false, @@ -50,14 +52,19 @@ protected override async IAsyncEnumerable Map } } + private static string shorten_github_link(string remoteUrl) + { + return remoteUrl.Replace("https://github.com/", "").Replace(".git", "").Trim(); + } + private static Task EnumerateRemotes(IRepository repository) { return Task.FromResult(repository.Remotes .Take(50) - .Select(remote => new UserInterfaceRepositoryAction(remote.Name, repository) - { - RepositoryCommand = new BrowseRepositoryCommand(remote.Url), - }) + .Select(remote => new UserInterfaceRepositoryAction(shorten_github_link(remote.Url), repository) + { + RepositoryCommand = new BrowseRepositoryCommand(remote.Url), + }) .Cast() .ToArray()); } diff --git a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs index 800be763..1ecd2f72 100644 --- a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs +++ b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs @@ -7,14 +7,9 @@ namespace RepoM.Plugin.AzureDevOps; using RepoM.Plugin.AzureDevOps.Internal; [UsedImplicitly] -internal class AzureDevOpsModule : IModule +internal class AzureDevOpsModule(IAzureDevOpsPullRequestService service) : IModule { - private readonly IAzureDevOpsPullRequestService _service; - - public AzureDevOpsModule(IAzureDevOpsPullRequestService service) - { - _service = service ?? throw new ArgumentNullException(nameof(service)); - } + private readonly IAzureDevOpsPullRequestService _service = service ?? throw new ArgumentNullException(nameof(service)); public Task StartAsync() { diff --git a/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs b/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs index a1cc2168..c883c164 100644 --- a/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs +++ b/src/RepoM.Plugin.AzureDevOps/Internal/AzureDevOpsPullRequestService.cs @@ -25,7 +25,7 @@ internal sealed class AzureDevOpsPullRequestService : IAzureDevOpsPullRequestSer private readonly ILogger _logger; private readonly VssConnection? _connection; private GitHttpClient? _azureDevopsGitClient; - private readonly List _emptyList = new(0); + private readonly List _emptyList = []; private Timer? _updateTimer1; private Timer? _updateTimer2; @@ -36,7 +36,7 @@ internal sealed class AzureDevOpsPullRequestService : IAzureDevOpsPullRequestSer public AzureDevOpsPullRequestService(IAzureDevopsConfiguration configuration, ILogger logger) { - _httpClient = new(); + _httpClient = new HttpClient(); _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); @@ -53,8 +53,8 @@ public AzureDevOpsPullRequestService(IAzureDevopsConfiguration configuration, IL _configuration.AzureDevOpsBaseUrl, new VssBasicCredential(string.Empty, _configuration.AzureDevOpsPersonalAccessToken)); _httpClient.BaseAddress = _configuration.AzureDevOpsBaseUrl; - _httpClient.DefaultRequestHeaders.Accept.Add(new("application/json")); - _httpClient.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($":{_configuration.AzureDevOpsPersonalAccessToken}"))); + _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($":{_configuration.AzureDevOpsPersonalAccessToken}"))); } } diff --git a/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs b/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs index d51aa79c..399cdc76 100644 --- a/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs +++ b/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs @@ -2,18 +2,11 @@ namespace RepoM.Plugin.AzureDevOps.Internal; using System; -internal class PullRequest +internal class PullRequest(Guid repositoryId, string name, string url) { - public PullRequest(Guid repositoryId, string name, string url) - { - RepositoryId = repositoryId; - Name = name; - Url = url; - } + public Guid RepositoryId { get; } = repositoryId; - public Guid RepositoryId { get; } + public string Name { get; } = name; - public string Name { get; } - - public string Url { get; } + public string Url { get; } = url; } \ No newline at end of file diff --git a/src/RepoM.Plugin.AzureDevOps/Internal/WorkItemExtractor.cs b/src/RepoM.Plugin.AzureDevOps/Internal/WorkItemExtractor.cs index ddd3e03d..29a78c53 100644 --- a/src/RepoM.Plugin.AzureDevOps/Internal/WorkItemExtractor.cs +++ b/src/RepoM.Plugin.AzureDevOps/Internal/WorkItemExtractor.cs @@ -10,9 +10,9 @@ internal static partial class WorkItemExtractor public static string[] GetDistinctWorkItemsFromCommitMessages(IEnumerable commitMessages) { - List results = new(); + List results = []; - foreach (string commitMessage in commitMessages) + foreach (var commitMessage in commitMessages) { MatchCollection matches = _workItemRegex.Matches(commitMessage); if (matches.Any(m => m.Success)) diff --git a/src/RepoM.Plugin.Clipboard/ActionMenu/Model/ActionMenus/ClipboardCopy/RepositoryActionClipboardCopyV1.cs b/src/RepoM.Plugin.Clipboard/ActionMenu/Model/ActionMenus/ClipboardCopy/RepositoryActionClipboardCopyV1.cs index 63b612df..2b1c02f8 100644 --- a/src/RepoM.Plugin.Clipboard/ActionMenu/Model/ActionMenus/ClipboardCopy/RepositoryActionClipboardCopyV1.cs +++ b/src/RepoM.Plugin.Clipboard/ActionMenu/Model/ActionMenus/ClipboardCopy/RepositoryActionClipboardCopyV1.cs @@ -36,7 +36,7 @@ public string Type [Required] [Text] public Text Text { get; set; } = null!; - + /// public Context? Context { get; set; } diff --git a/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs b/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs index 89fd7c07..4d07fcbe 100644 --- a/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs +++ b/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs @@ -8,14 +8,9 @@ namespace RepoM.Plugin.Clipboard.RepositoryAction; using TextCopy; [UsedImplicitly] -internal class CopyToClipboardRepositoryCommandExecutor : ICommandExecutor +internal class CopyToClipboardRepositoryCommandExecutor(IClipboard clipboard) : ICommandExecutor { - private readonly IClipboard _clipboard; - - public CopyToClipboardRepositoryCommandExecutor(IClipboard clipboard) - { - _clipboard = clipboard ?? throw new ArgumentNullException(nameof(clipboard)); - } + private readonly IClipboard _clipboard = clipboard ?? throw new ArgumentNullException(nameof(clipboard)); public void Execute(IRepository repository, CopyToClipboardRepositoryCommand repositoryCommand) { diff --git a/src/RepoM.Plugin.Statistics/StatisticsModule.cs b/src/RepoM.Plugin.Statistics/StatisticsModule.cs index f5e47275..337c3eb8 100644 --- a/src/RepoM.Plugin.Statistics/StatisticsModule.cs +++ b/src/RepoM.Plugin.Statistics/StatisticsModule.cs @@ -15,45 +15,34 @@ namespace RepoM.Plugin.Statistics; using RepoM.Plugin.Statistics.Interface; [UsedImplicitly] -internal class StatisticsModule : IModule +internal class StatisticsModule( + IStatisticsService service, + IStatisticsConfiguration configuration, + IClock clock, + IAppDataPathProvider pathProvider, + IFileSystem fileSystem, + ILogger logger) + : IModule { - private readonly IStatisticsService _service; - private readonly IStatisticsConfiguration _configuration; - private readonly IClock _clock; - private readonly IAppDataPathProvider _pathProvider; - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; + private readonly IStatisticsService _service = service ?? throw new ArgumentNullException(nameof(service)); + private readonly IStatisticsConfiguration _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + private readonly IClock _clock = clock ?? throw new ArgumentNullException(nameof(clock)); + private readonly IAppDataPathProvider _pathProvider = pathProvider ?? throw new ArgumentNullException(nameof(pathProvider)); + private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger)); private string _basePath = string.Empty; private IDisposable? _disposable; - private readonly JsonSerializerSettings _settings; - - public StatisticsModule( - IStatisticsService service, - IStatisticsConfiguration configuration, - IClock clock, - IAppDataPathProvider pathProvider, - IFileSystem fileSystem, - ILogger logger) + private readonly JsonSerializerSettings _settings = new() { - _service = service ?? throw new ArgumentNullException(nameof(service)); - _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); - _clock = clock ?? throw new ArgumentNullException(nameof(clock)); - _pathProvider = pathProvider ?? throw new ArgumentNullException(nameof(pathProvider)); - _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - - _settings = new JsonSerializerSettings - { - Formatting = Formatting.None, - NullValueHandling = NullValueHandling.Ignore, - TypeNameHandling = TypeNameHandling.All, - }; - } + Formatting = Formatting.None, + NullValueHandling = NullValueHandling.Ignore, + TypeNameHandling = TypeNameHandling.All, + }; public async Task StartAsync() { _basePath = _fileSystem.Path.Combine(_pathProvider.AppDataPath, "Module", "Statistics"); - + _disposable = WriteEventsToFile(); await ProcessEventsFromFile().ConfigureAwait(false); @@ -151,12 +140,12 @@ private IDisposable WriteEventsToFile() .Buffer(buffer) .Subscribe(data => { - IEvent[] events = [.. data, ]; + IEvent[] events = [.. data,]; if (events.Length == 0) { return; } - + var json = JsonConvert.SerializeObject(events, _settings); var filename = _fileSystem.Path.Combine(_basePath, $"statistics.v1.{_clock.Now:yyyy-MM-dd HH.mm.ss}.json"); diff --git a/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs b/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs index 38622fb1..97e46e2b 100644 --- a/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs +++ b/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs @@ -18,25 +18,16 @@ public static IDisposable SetEnvironmentVariable(string key, string value) return new ReleaseDisposable(are, key, origValue); } - private sealed class ReleaseDisposable : IDisposable + private sealed class ReleaseDisposable(AutoResetEvent are, string key, string? value) : IDisposable { private readonly object _lock = new(); - private AutoResetEvent? _are; - private readonly string _key; - private readonly string? _value; - - public ReleaseDisposable(AutoResetEvent are, string key, string? value) - { - _are = are; - _key = key; - _value = value; - } + private AutoResetEvent? _are = are; public void Dispose() { lock (_lock) { - Environment.SetEnvironmentVariable(_key, _value); + Environment.SetEnvironmentVariable(key, value); _are?.Set(); _are = null; } From 365a25ca0f4dce0862ac2f0c0d60306009c646c0 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 06:19:28 +0100 Subject: [PATCH 11/17] Fixes pin problem --- .../Model/ActionMenus/Pin/RepositoryActionPinV1.cs | 6 +++--- src/RepoM.Api/Resources/RepositoryActionsV2.yaml | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs index 61b2637a..a0ef9fa7 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs @@ -6,7 +6,7 @@ namespace RepoM.ActionMenu.Core.ActionMenu.Model.ActionMenus.Pin; using RepoM.ActionMenu.Interface.YamlModel.Templating; /// -/// 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 persistent and all pinned repositories will be cleared when RepoM exits. /// Pinning a repository allowed custom filtering, ordering and searching. /// [RepositoryAction(TYPE_VALUE)] @@ -21,7 +21,7 @@ public string Type } /// - [Text("(Un)Pin repository")] + [Text("πŸ“Œ Pin / Unpin Repo")] public Text Name { get; set; } = null!; /// @@ -34,7 +34,7 @@ public string Type /// /// The pin mode `[Toggle, Pin, UnPin]`. /// - public PinMode? Mode { get; set; } // GitHub issue: https://github.com/coenm/RepoM/issues/87 + public PinMode? Mode { get; set; } = PinMode.Toggle; // GitHub issue: https://github.com/coenm/RepoM/issues/87 public override string ToString() { diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index 0db27538..da9b7660 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -214,7 +214,6 @@ action-menu: name: πŸ“¦ Git actions: # - type: browse-repository@1 - # - type: pin-repository@1 - type: git-fetch@1 - type: git-pull@1 - type: git-push@1 @@ -223,6 +222,8 @@ action-menu: - type: separator@1 # active: is_work_repository +- type: pin-repository@1 + - type: folder@1 name: ❓ About {{get_remote_name()}} context: From 6375a50e9f2215bbcf5b9d7f879903e791e14967 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 06:40:09 +0100 Subject: [PATCH 12/17] Setting the mode This should be unnecessary after this update. --- src/RepoM.Api/Resources/RepositoryActionsV2.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index da9b7660..2d6944e6 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -223,6 +223,8 @@ action-menu: # active: is_work_repository - type: pin-repository@1 + name: "πŸ“Œ Pin / Unpin Repo" + mode: toggle - type: folder@1 name: ❓ About {{get_remote_name()}} From a8c180d71c6153ccc473b47498c68fc28deb2a47 Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 06:59:42 +0100 Subject: [PATCH 13/17] More icons --- .../ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs | 2 +- .../Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs | 2 +- .../Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs | 2 +- .../Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs index d0ffbbf2..6bacd1a7 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("Checkout")] + [Text("πŸ—ƒοΈ Checkout")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs index e3047c01..c3ae4c0d 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("Fetch")] + [Text("⏬ Fetch")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs index a52e19de..2ba10ff5 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("Pull")] + [Text("πŸ”½ Pull")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs index 07ba68da..6a84dcd4 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("Push")] + [Text("πŸ”Ό Push")] public Text Name { get; set; } = null!; /// From a0bd9e679cc53c0f57b09bb7df10b3c07c71c64d Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 17:14:22 +0100 Subject: [PATCH 14/17] Update so that it is not limited to GitHub --- ...epositoryActionBrowseRepositoryV1Mapper.cs | 18 +- .../Resources/RepositoryActionsV2.yaml | 343 +++++++++--------- 2 files changed, 188 insertions(+), 173 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs index 307aaf0c..55ffa7f8 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs @@ -31,7 +31,7 @@ protected override async IAsyncEnumerable Map if (repository.Remotes.Count == 1 || forceSingle) { - menuTitle = "πŸ”—Github: " + shorten_github_link(repository.Remotes[0].Url); + menuTitle = "πŸ”— " + try_get_remote_repo_long_name(repository.Remotes[0].Url); yield return new UserInterfaceRepositoryAction(menuTitle, repository) { RepositoryCommand = new BrowseRepositoryCommand(repository.Remotes[0].Url), @@ -39,7 +39,7 @@ protected override async IAsyncEnumerable Map } else { - menuTitle = "πŸ”—GitHub remote repositories"; //πŸ”— + menuTitle = "πŸ”— Remote repos"; //πŸ”— yield return new DeferredSubActionsUserInterfaceRepositoryAction( menuTitle, repository, @@ -52,16 +52,24 @@ protected override async IAsyncEnumerable Map } } - private static string shorten_github_link(string remoteUrl) + private static string try_get_remote_repo_long_name(string remoteUrl) { - return remoteUrl.Replace("https://github.com/", "").Replace(".git", "").Trim(); + var splitString = remoteUrl.Trim().Split('/'); + if (splitString.Length < 2) + { + return remoteUrl; + } + + var name = splitString.Last().Replace(".git", ""); + var author = splitString[^2]; + return $"{author}/{name}"; } private static Task EnumerateRemotes(IRepository repository) { return Task.FromResult(repository.Remotes .Take(50) - .Select(remote => new UserInterfaceRepositoryAction(shorten_github_link(remote.Url), repository) + .Select(remote => new UserInterfaceRepositoryAction(try_get_remote_repo_long_name(remote.Url), repository) { RepositoryCommand = new BrowseRepositoryCommand(remote.Url), }) diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index 2d6944e6..a61686d6 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -1,5 +1,5 @@ -ο»Ώcontext: -- type: evaluate-script@1 +ο»Ώcontext: +- type : evaluate-script@1 content: |- func is_null(input) ret input == null @@ -14,7 +14,7 @@ end func remotes_contain_inner(remotes, url_part) - urls = remotes | array.map "url" + urls = remotes | array.map "url" filtered = array.filter(urls, do ret string.contains($0, url_part) end) @@ -26,9 +26,9 @@ end func get_remote_origin() - remotes = repository.remotes; + remotes = repository.remotes; filtered = array.filter(remotes, do - remote = $0; + remote = $0; ret remote.key == "origin" end) ret array.first(filtered); @@ -51,204 +51,211 @@ ret repository.branch | string.replace "feature/" "" | string.strip end - func shorten_github_link(github_url) - ret github_url | string.replace "https://github.com/" "" | string.replace ".git" "" | string.strip + func try_get_remote_repo_long_name(long_url) + splitString = long_url | string.strip | string.split "/"; + if array.size(splitString) < 2 + ret long_url + end + name = array.last(splitString) | string.replace ".git" "" + author = splitString[^2] + ret author + "/" + name end - func get_remote_name() + func try_get_remote_origin_long_name() if is_null(repository.remotes) || array.size(repository.remotes) == 0 ret repository.name end - ret shorten_github_link(repository.remotes[0].url) + ret try_get_remote_repo_long_name(repository.remotes[0].url) end - remote_name_origin = get_remote_origin_name(); - is_work_repository = remotes_contain("My-Work"); + remote_name_origin = get_remote_origin_name(); + is_work_repository = remotes_contain("My-Work"); is_github_repository = remotes_contain("github.com"); solution_files = file.find_files(repository.linux_path, "*.sln"); - solution_file = array.first(solution_files); + solution_file = array.first(solution_files); - dir_visual_studio = env.ProgramW6432 + "/Microsoft Visual Studio/"; - dir_windows_terminal_Store = env.LocalAppData + "/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/"; - dir_windows_terminal_Preview = env.LocalAppData + "/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/"; + dir_visual_studio = env.ProgramW6432 + "/Microsoft Visual Studio/"; + dir_windows_terminal_Store = env.LocalAppData + "/Packages/Microsoft.WindowsTerminal_8wekyb3d8bbwe/"; + dir_windows_terminal_Preview = env.LocalAppData + "/Packages/Microsoft.WindowsTerminalPreview_8wekyb3d8bbwe/"; dir_windows_terminal_Unpackaged = env.LocalAppData + "/Packages/Microsoft/WindowsTerminal/"; - exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; - exe_sourcetree = env.LocalAppData + "/SourceTree/SourceTree.exe"; - exe_gitkraken = env.LocalAppData + "/GitKraken/GitKraken.exe"; - exe_everything = env.ProgramW6432 + "/Everything/Everything.exe"; + exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe"; + exe_sourcetree = env.LocalAppData + "/SourceTree/SourceTree.exe"; + exe_gitkraken = env.LocalAppData + "/GitKraken/GitKraken.exe"; + exe_everything = env.ProgramW6432 + "/Everything/Everything.exe"; exe_terminal_commander = env.ProgramW6432 + "/totalcmd/TOTALCMD64.EXE"; # Specific var files -- type: render-variable@1 - name: repo_docs_directory - value: 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' - enabled: is_github_repository +- type : render-variable@1 + name : repo_docs_directory + value : 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' + enabled : is_github_repository # Env files -- type: render-variable@1 - name: repo_environment_file_directory - value: '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}' +- type : render-variable@1 + name : repo_environment_file_directory + value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}' -- type: render-variable@1 - name: repo_environment_file - value: '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}\RepoM.env' +- type : render-variable@1 + name : repo_environment_file + value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}\RepoM.env' -- type: render-variable@1 - name: repo_yaml_file - value: 'C:\\WorkCofigs\{{ remote_name_origin }}\RepoMV2.yaml' +- type : render-variable@1 + name : repo_yaml_file + value : 'C:\\WorkCofigs\{{ remote_name_origin }}\RepoMV2.yaml' # Runsettings -- type: load-file@1 - filename: '{{ repo_environment_file }}' - enabled: is_work_repository - -- type: load-file@1 - filename: '{{ env.REPOZ_CONFIG_PATH }}\work.env' - enabled: is_work_repository - -- type: load-file@1 - filename: '{{ repo_yaml_file }}' - enabled: is_work_repository - -action-menu: - -- type: command@1 - name: πŸ“‚ Open in Windows File Explorer - command: '"{{ repository.path }}"' - -# Open in visual studio when exactly one '.sln' file was found: -- type: command@1 - name: πŸ—ƒοΈ Open in Visual Studio - command: '{{ solution_file }}' - active: array.size(solution_files) == 1 && file.dir_exists(dir_visual_studio) - -# Otherwise, Visual studio folder with all '.sln' files when multiple sln files were found: -- type: folder@1 - name: πŸ—ƒοΈ Open in Visual Studio - active: array.size(solution_files) > 1 && file.dir_exists(dir_visual_studio) - actions: - - type: foreach@1 - enumerable: solution_files - variable: sln - actions: - - type: command@1 - name: '{{ get_filename(sln) }}' - command: '{{ sln }}' +- type : load-file@1 + filename : '{{ repo_environment_file }}' + enabled : is_work_repository + +- type : load-file@1 + filename : '{{ env.REPOZ_CONFIG_PATH }}\work.env' + enabled : is_work_repository + +- type : load-file@1 + filename : '{{ repo_yaml_file }}' + enabled : is_work_repository + +action-menu : + +- type : command@1 + name : πŸ“‚ Open in Windows File Explorer + command : '"{{ repository.path }}"' + +# Open in visual studio when exactly one '.sln' file was found: +- type : command@1 + name : πŸ—ƒοΈ Open in Visual Studio + command : '{{ solution_file }}' + active : array.size(solution_files) == 1 && file.dir_exists(dir_visual_studio) + +# Otherwise, Visual studio folder with all '.sln' files when multiple sln files were found: +- type : folder@1 + name : πŸ—ƒοΈ Open in Visual Studio + active : array.size(solution_files) > 1 && file.dir_exists(dir_visual_studio) + actions : + - type : foreach@1 + enumerable : solution_files + variable : sln + actions : + - type : command@1 + name : '{{ get_filename(sln) }}' + command : '{{ sln }}' -- type: command@1 - name: πŸ“ Open in Visual Studio Code - command: code - arguments: '"{{ repository.path }}"' - active: file.file_exists(exe_vs_code) - -- type: executable@1 - name: Open in Sourcetree - executable: '{{ exe_sourcetree }}' - arguments: -f "{{ repository.windows_path }}" - active: file.file_exists(exe_sourcetree) - -- type: executable@1 - name: πŸ“Š Open in GitKraken πŸ¦‘ - executable: '{{ exe_gitkraken }}' - arguments: --path "{{ repository.path }}" - -- type: command@1 - name: 🧾 Open in Windows Terminal - command: wt - arguments: -d "{{ repository.path }}" - active: file.dir_exists(dir_windows_terminal_Store) || file.dir_exists(dir_windows_terminal_Preview) || file.dir_exists(dir_windows_terminal_Unpackaged) - -- type: executable@1 - name: πŸ” Open in Everything - executable: '{{ exe_everything }}' - arguments: -s """"{{ repository.path }}""" " - active: file.file_exists(exe_everything) - -- type: executable@1 - name: Open in TotalCommander - executable: '{{ exe_terminal_commander }}' - arguments: /O /T /L="{{ repository.linux_path }}" - active: file.file_exists(exe_terminal_commander) - -# - type: executable@1 -# name: 'Open in Windows PowerShell' -# executable: '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' -# arguments: -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" - -# - type: executable@1 -# name: 'Open in Windows Command Prompt' -# executable: '{{ env.WINDIR }}/System32/cmd.exe' -# arguments: /k cd "{{ repository.linux_path }}" - -- type: separator@1 - -- type: just-text@1 - name: 'Warning: No GitHub remotes to browse to' - active: array.size(repository.remotes) == 0 +- type : command@1 + name : πŸ“ Open in Visual Studio Code + command : code + arguments : '"{{ repository.path }}"' + active : file.file_exists(exe_vs_code) + +- type : executable@1 + name : Open in Sourcetree + executable : '{{ exe_sourcetree }}' + arguments : -f "{{ repository.windows_path }}" + active : file.file_exists(exe_sourcetree) + +- type : executable@1 + name : πŸ“Š Open in GitKraken πŸ¦‘ + executable : '{{ exe_gitkraken }}' + arguments : --path "{{ repository.path }}" + +- type : command@1 + name : 🧾 Open in Windows Terminal + command : wt + arguments : -d "{{ repository.path }}" + active : file.dir_exists(dir_windows_terminal_Store) || file.dir_exists(dir_windows_terminal_Preview) || file.dir_exists(dir_windows_terminal_Unpackaged) + +- type : executable@1 + name : πŸ” Open in Everything + executable : '{{ exe_everything }}' + arguments : -s """"{{ repository.path }}""" " + active : file.file_exists(exe_everything) + +- type : executable@1 + name : Open in TotalCommander + executable : '{{ exe_terminal_commander }}' + arguments : /O /T /L="{{ repository.linux_path }}" + active : file.file_exists(exe_terminal_commander) + +# - type : executable@1 +# name : 'Open in Windows PowerShell' +# executable : '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' +# arguments : -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" + +# - type : executable@1 +# name : 'Open in Windows Command Prompt' +# executable : '{{ env.WINDIR }}/System32/cmd.exe' +# arguments : /k cd "{{ repository.linux_path }}" + +- type : separator@1 + +- type : just-text@1 + name : 'Warning: No remote repos to browse to' + active : array.size(repository.remotes) == 0 # single remote, create url menu item -- type: url@1 - name: 'πŸ”— GitHub: {{ get_remote_name() }}' - url: '{{ repository.remotes[0].url }}' - active: array.size(repository.remotes) == 1 +- type : url@1 + name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' + url : '{{ repository.remotes[0].url }}' + active : array.size(repository.remotes) == 1 # Multiple remotes, create folder with multiple menu items -- type: folder@1 - name: πŸ”— GitHub remote repositories - active: array.size(repository.remotes) > 1 - actions: - - type: foreach@1 - enumerable: repository.remotes - variable: remote - actions: - - type: url@1 - name: '[{{ remote.key}}] {{ shorten_github_link(remote.url) }}' - url: '{{ remote.url }}' +- type : folder@1 + name : πŸ”— Remote repos + active : array.size(repository.remotes) > 1 + actions : + - type : foreach@1 + enumerable : repository.remotes + variable : remote + actions : + - type : url@1 + name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' + url : '{{ remote.url }}' - type: separator@1 -- type: folder@1 - name: πŸ“¦ Git - actions: - # - type: browse-repository@1 - - type: git-fetch@1 - - type: git-pull@1 - - type: git-push@1 - - type: git-checkout@1 +- type : folder@1 + name : πŸ“¦ Git + actions : + # - type : browse-repository@1 + - type : git-fetch@1 + - type : git-pull@1 + - type : git-push@1 + - type : git-checkout@1 -- type: separator@1 +- type : separator@1 # active: is_work_repository -- type: pin-repository@1 - name: "πŸ“Œ Pin / Unpin Repo" - mode: toggle - -- type: folder@1 - name: ❓ About {{get_remote_name()}} - context: - - type: render-variable@1 - name: repo_docs_directory - value: 'C:\docs\{{ repository.name }}\' - actions: - - - type: clipboard-copy@1 - name: 'Current branch is {{ repository.branch }}' - text: '{{ repository.branch }}' +- type : pin-repository@1 + name : "πŸ“Œ Pin / Unpin Repo" + mode : toggle - - type: clipboard-copy@1 - name: 'Local path is {{ repository.windows_path }}' - text: '{{ repository.windows_path }}' +- type : folder@1 + name : ❓ About {{try_get_remote_origin_long_name()}} + actions : + + - type : clipboard-copy@1 + name : 'Current branch is {{ repository.branch }}' + text : '{{ repository.branch }}' - - type: separator@1 + - type : clipboard-copy@1 + name : 'Local path is {{ repository.windows_path }}' + text : '{{ repository.windows_path }}' - - type: ignore-repository@1 - name: ❌ Ignore Repository + - type : separator@1 - # - type: command@1 - # name: 'Create Directory {{ repo_docs_directory }}' - # command: cmd - # arguments: /k mkdir "{{ repo_docs_directory }}" - # active: '!file.dir_exists(repo_docs_directory)' + - type : ignore-repository@1 + name : ❌ Ignore Repository + + # context : + # - type : render-variable@1 + # name : repo_docs_directory + # value : 'C:\docs\{{ repository.name }}\' + + # - type : command@1 + # name : 'Create Directory {{ repo_docs_directory }}' + # command : cmd + # arguments : /k mkdir "{{ repo_docs_directory }}" + # active : '!file.dir_exists(repo_docs_directory)' From 577a8433f0e8e337c69d07bb17431c38e0da3a4f Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Tue, 10 Sep 2024 17:23:49 +0100 Subject: [PATCH 15/17] fixes --- .../Resources/RepositoryActionsV2.yaml | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index a61686d6..7ba98fae 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -195,31 +195,29 @@ action-menu : name : 'Warning: No remote repos to browse to' active : array.size(repository.remotes) == 0 -# single remote, create url menu item -- type : url@1 - name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' - url : '{{ repository.remotes[0].url }}' - active : array.size(repository.remotes) == 1 - -# Multiple remotes, create folder with multiple menu items -- type : folder@1 - name : πŸ”— Remote repos - active : array.size(repository.remotes) > 1 - actions : - - type : foreach@1 - enumerable : repository.remotes - variable : remote - actions : - - type : url@1 - name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' - url : '{{ remote.url }}' - -- type: separator@1 - +# #single remote, create url menu item +# - type : url@1 +# name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' +# url : '{{ repository.remotes[0].url }}' +# active : array.size(repository.remotes) == 1 + +# #Multiple remotes, create folder with multiple menu items +# - type : folder@1 +# name : πŸ”— Remote repos +# active : array.size(repository.remotes) > 1 +# actions : +# - type : foreach@1 +# enumerable : repository.remotes +# variable : remote +# actions : +# - type : url@1 +# name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' +# url : '{{ remote.url }}' + +- type : browse-repository@1 - type : folder@1 name : πŸ“¦ Git actions : - # - type : browse-repository@1 - type : git-fetch@1 - type : git-pull@1 - type : git-push@1 From f9f8b996dd0bbf162338fc8b501238c7a2c5a52c Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Sat, 14 Sep 2024 21:01:04 +0100 Subject: [PATCH 16/17] fixed error --- .../Resources/RepositoryActionsV2.yaml | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index 7ba98fae..09571503 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -1,4 +1,4 @@ -ο»Ώcontext: +context: - type : evaluate-script@1 content: |- func is_null(input) @@ -123,7 +123,8 @@ action-menu : - type : command@1 name : πŸ“‚ Open in Windows File Explorer - command : '"{{ repository.path }}"' + command : explorer + arguments : '{{ repository.path }}' # Open in visual studio when exactly one '.sln' file was found: - type : command@1 @@ -146,7 +147,7 @@ action-menu : - type : command@1 name : πŸ“ Open in Visual Studio Code - command : code + command : '{{ exe_vs_code }}' arguments : '"{{ repository.path }}"' active : file.file_exists(exe_vs_code) @@ -195,26 +196,26 @@ action-menu : name : 'Warning: No remote repos to browse to' active : array.size(repository.remotes) == 0 -# #single remote, create url menu item -# - type : url@1 -# name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' -# url : '{{ repository.remotes[0].url }}' -# active : array.size(repository.remotes) == 1 - -# #Multiple remotes, create folder with multiple menu items -# - type : folder@1 -# name : πŸ”— Remote repos -# active : array.size(repository.remotes) > 1 -# actions : -# - type : foreach@1 -# enumerable : repository.remotes -# variable : remote -# actions : -# - type : url@1 -# name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' -# url : '{{ remote.url }}' - -- type : browse-repository@1 +# single remote, create url menu item +- type : url@1 + name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' + url : '{{ repository.remotes[0].url }}' + active : array.size(repository.remotes) == 1 + +# Multiple remotes, create folder with multiple menu items +- type : folder@1 + name : πŸ”— Remote repos + active : array.size(repository.remotes) > 1 + actions : + - type : foreach@1 + enumerable : repository.remotes + variable : remote + actions : + - type : url@1 + name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' + url : '{{ remote.url }}' + +# - type : browse-repository@1 - type : folder@1 name : πŸ“¦ Git actions : From e8ae97b598f51d6968d46b96a60e82091d5325af Mon Sep 17 00:00:00 2001 From: Gabriel Vanca Date: Fri, 20 Sep 2024 04:20:37 +0100 Subject: [PATCH 17/17] restore style and YAML package --- ...epositoryActionBrowseRepositoryV1Mapper.cs | 10 +- .../Checkout/RepositoryActionGitCheckoutV1.cs | 2 +- .../Git/Fetch/RepositoryActionGitFetchV1.cs | 2 +- .../Git/Pull/RepositoryActionGitPullV1.cs | 2 +- .../Git/Push/RepositoryActionGitPushV1.cs | 2 +- .../ActionMenus/Pin/RepositoryActionPinV1.cs | 2 +- .../RepoM.ActionMenu.Core.csproj | 2 +- src/RepoM.Api/Bootstrapper.cs | 18 +- src/RepoM.Api/EnsureStartup.cs | 12 +- src/RepoM.Api/RepoM.Api.csproj | 2 +- .../Resources/RepositoryActionsV2.yaml | 288 +++++++++--------- .../AzureDevOpsModule.cs | 9 +- .../Internal/PullRequest.cs | 15 +- ...opyToClipboardRepositoryCommandExecutor.cs | 9 +- .../StatisticsModule.cs | 40 ++- .../RepoM.ActionMenu.CodeGen.Tests.csproj | 2 +- .../RepoM.ActionMenu.Core.TestLib.csproj | 2 +- .../RepoM.ActionMenu.Core.Tests.csproj | 2 +- .../EnvironmentVariableManager.cs | 17 +- 19 files changed, 243 insertions(+), 195 deletions(-) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs index 55ffa7f8..e3239765 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/BrowseRepository/RepositoryActionBrowseRepositoryV1Mapper.cs @@ -24,14 +24,14 @@ protected override async IAsyncEnumerable Map //var menuTitle = await context.RenderStringAsync(action.Name).ConfigureAwait(false); //if (string.IsNullOrWhiteSpace(menuTitle)) //{ - // menuTitle = "πŸ”—Github: "; + // menuTitle = "Github: "; //} var forceSingle = await action.FirstOnly.EvaluateAsync(context).ConfigureAwait(false); if (repository.Remotes.Count == 1 || forceSingle) { - menuTitle = "πŸ”— " + try_get_remote_repo_long_name(repository.Remotes[0].Url); + menuTitle = TryGet_RemoteRepoLongName(repository.Remotes[0].Url); yield return new UserInterfaceRepositoryAction(menuTitle, repository) { RepositoryCommand = new BrowseRepositoryCommand(repository.Remotes[0].Url), @@ -39,7 +39,7 @@ protected override async IAsyncEnumerable Map } else { - menuTitle = "πŸ”— Remote repos"; //πŸ”— + menuTitle = "Remote repos"; yield return new DeferredSubActionsUserInterfaceRepositoryAction( menuTitle, repository, @@ -52,7 +52,7 @@ protected override async IAsyncEnumerable Map } } - private static string try_get_remote_repo_long_name(string remoteUrl) + private static string TryGet_RemoteRepoLongName(string remoteUrl) { var splitString = remoteUrl.Trim().Split('/'); if (splitString.Length < 2) @@ -69,7 +69,7 @@ private static Task EnumerateRemotes(IRepos { return Task.FromResult(repository.Remotes .Take(50) - .Select(remote => new UserInterfaceRepositoryAction(try_get_remote_repo_long_name(remote.Url), repository) + .Select(remote => new UserInterfaceRepositoryAction(TryGet_RemoteRepoLongName(remote.Url), repository) { RepositoryCommand = new BrowseRepositoryCommand(remote.Url), }) diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs index 6bacd1a7..d0ffbbf2 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Checkout/RepositoryActionGitCheckoutV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("πŸ—ƒοΈ Checkout")] + [Text("Checkout")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs index c3ae4c0d..e3047c01 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Fetch/RepositoryActionGitFetchV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("⏬ Fetch")] + [Text("Fetch")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs index 2ba10ff5..a52e19de 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Pull/RepositoryActionGitPullV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("πŸ”½ Pull")] + [Text("Pull")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs index 6a84dcd4..07ba68da 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Git/Push/RepositoryActionGitPushV1.cs @@ -20,7 +20,7 @@ public string Type } /// - [Text("πŸ”Ό Push")] + [Text("Push")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs index a0ef9fa7..db12acb6 100644 --- a/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs +++ b/src/RepoM.ActionMenu.Core/ActionMenu/Model/ActionMenus/Pin/RepositoryActionPinV1.cs @@ -21,7 +21,7 @@ public string Type } /// - [Text("πŸ“Œ Pin / Unpin Repo")] + [Text("Pin / Unpin Repo")] public Text Name { get; set; } = null!; /// diff --git a/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj b/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj index d45e7edb..9911e86f 100644 --- a/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj +++ b/src/RepoM.ActionMenu.Core/RepoM.ActionMenu.Core.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/RepoM.Api/Bootstrapper.cs b/src/RepoM.Api/Bootstrapper.cs index aaa54d01..3cf745c9 100644 --- a/src/RepoM.Api/Bootstrapper.cs +++ b/src/RepoM.Api/Bootstrapper.cs @@ -16,15 +16,23 @@ namespace RepoM.Api; using RepoM.Core.Plugin.RepositoryOrdering.Configuration; using SimpleInjector; -public class CoreBootstrapper(IPluginFinder pluginFinder, IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILoggerFactory loggerFactory) +public class CoreBootstrapper { - private readonly IPluginFinder _pluginFinder = pluginFinder ?? throw new ArgumentNullException(nameof(pluginFinder)); - private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - private readonly IAppDataPathProvider _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); - private readonly ILoggerFactory _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + private readonly IPluginFinder _pluginFinder; + private readonly IFileSystem _fileSystem; + private readonly IAppDataPathProvider _appDataProvider; + private readonly ILoggerFactory _loggerFactory; private static readonly Assembly _thisAssembly = typeof(CoreBootstrapper).Assembly; + public CoreBootstrapper(IPluginFinder pluginFinder, IFileSystem fileSystem, IAppDataPathProvider appDataProvider, ILoggerFactory loggerFactory) + { + _pluginFinder = pluginFinder ?? throw new ArgumentNullException(nameof(pluginFinder)); + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); + _loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)); + } + public static void RegisterRepositoryScorerConfigurationsTypes(Container container) { foreach (Type type in GetNonAbstractNonGenericInheritedExportedTypesFrom(_thisAssembly)) diff --git a/src/RepoM.Api/EnsureStartup.cs b/src/RepoM.Api/EnsureStartup.cs index c9b15c17..5f7c8586 100644 --- a/src/RepoM.Api/EnsureStartup.cs +++ b/src/RepoM.Api/EnsureStartup.cs @@ -7,10 +7,16 @@ namespace RepoM.Api; using RepoM.Api.Resources; using RepoM.Core.Plugin.Common; -public class EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider) +public class EnsureStartup { - private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - private readonly IAppDataPathProvider _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); + private readonly IFileSystem _fileSystem; + private readonly IAppDataPathProvider _appDataProvider; + + public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider) + { + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider)); + } public async Task EnsureFilesAsync() { diff --git a/src/RepoM.Api/RepoM.Api.csproj b/src/RepoM.Api/RepoM.Api.csproj index 8e9310bd..b6806475 100644 --- a/src/RepoM.Api/RepoM.Api.csproj +++ b/src/RepoM.Api/RepoM.Api.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml index 09571503..414ac7f6 100644 --- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml +++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml @@ -1,5 +1,5 @@ context: -- type : evaluate-script@1 +- type : evaluate-script@1 content: |- func is_null(input) ret input == null @@ -88,173 +88,173 @@ context: # Specific var files -- type : render-variable@1 - name : repo_docs_directory - value : 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' - enabled : is_github_repository +- type : render-variable@1 + name : repo_docs_directory + value : 'G:\\My Drive\\RepoDocs\\github.com\\{{ remote_name_origin }}' + enabled : is_github_repository # Env files -- type : render-variable@1 - name : repo_environment_file_directory - value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}' +- type : render-variable@1 + name : repo_environment_file_directory + value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}' -- type : render-variable@1 - name : repo_environment_file - value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}\RepoM.env' +- type : render-variable@1 + name : repo_environment_file + value : '{{ env.REPOZ_CONFIG_PATH }}\{{ remote_name_origin }}\RepoM.env' -- type : render-variable@1 - name : repo_yaml_file - value : 'C:\\WorkCofigs\{{ remote_name_origin }}\RepoMV2.yaml' +- type : render-variable@1 + name : repo_yaml_file + value : 'C:\\WorkCofigs\{{ remote_name_origin }}\RepoMV2.yaml' # Runsettings -- type : load-file@1 - filename : '{{ repo_environment_file }}' - enabled : is_work_repository +- type : load-file@1 + filename : '{{ repo_environment_file }}' + enabled : is_work_repository -- type : load-file@1 - filename : '{{ env.REPOZ_CONFIG_PATH }}\work.env' - enabled : is_work_repository +- type : load-file@1 + filename : '{{ env.REPOZ_CONFIG_PATH }}\work.env' + enabled : is_work_repository -- type : load-file@1 - filename : '{{ repo_yaml_file }}' - enabled : is_work_repository +- type : load-file@1 + filename : '{{ repo_yaml_file }}' + enabled : is_work_repository -action-menu : +action-menu : -- type : command@1 - name : πŸ“‚ Open in Windows File Explorer - command : explorer - arguments : '{{ repository.path }}' +- type : command@1 + name : πŸ“‚ Open in Windows File Explorer + command : explorer + arguments : '{{ repository.path }}' # Open in visual studio when exactly one '.sln' file was found: -- type : command@1 - name : πŸ—ƒοΈ Open in Visual Studio - command : '{{ solution_file }}' - active : array.size(solution_files) == 1 && file.dir_exists(dir_visual_studio) +- type : command@1 + name : πŸ—ƒοΈ Open in Visual Studio + command : '{{ solution_file }}' + active : array.size(solution_files) == 1 && file.dir_exists(dir_visual_studio) # Otherwise, Visual studio folder with all '.sln' files when multiple sln files were found: -- type : folder@1 - name : πŸ—ƒοΈ Open in Visual Studio - active : array.size(solution_files) > 1 && file.dir_exists(dir_visual_studio) - actions : - - type : foreach@1 - enumerable : solution_files - variable : sln - actions : - - type : command@1 - name : '{{ get_filename(sln) }}' - command : '{{ sln }}' +- type : folder@1 + name : πŸ—ƒοΈ Open in Visual Studio + active : array.size(solution_files) > 1 && file.dir_exists(dir_visual_studio) + actions : + - type : foreach@1 + enumerable : solution_files + variable : sln + actions : + - type : command@1 + name : '{{ get_filename(sln) }}' + command : '{{ sln }}' -- type : command@1 - name : πŸ“ Open in Visual Studio Code - command : '{{ exe_vs_code }}' - arguments : '"{{ repository.path }}"' - active : file.file_exists(exe_vs_code) - -- type : executable@1 - name : Open in Sourcetree - executable : '{{ exe_sourcetree }}' - arguments : -f "{{ repository.windows_path }}" - active : file.file_exists(exe_sourcetree) - -- type : executable@1 - name : πŸ“Š Open in GitKraken πŸ¦‘ - executable : '{{ exe_gitkraken }}' - arguments : --path "{{ repository.path }}" - -- type : command@1 - name : 🧾 Open in Windows Terminal - command : wt - arguments : -d "{{ repository.path }}" - active : file.dir_exists(dir_windows_terminal_Store) || file.dir_exists(dir_windows_terminal_Preview) || file.dir_exists(dir_windows_terminal_Unpackaged) - -- type : executable@1 - name : πŸ” Open in Everything - executable : '{{ exe_everything }}' - arguments : -s """"{{ repository.path }}""" " - active : file.file_exists(exe_everything) - -- type : executable@1 - name : Open in TotalCommander - executable : '{{ exe_terminal_commander }}' - arguments : /O /T /L="{{ repository.linux_path }}" - active : file.file_exists(exe_terminal_commander) - -# - type : executable@1 -# name : 'Open in Windows PowerShell' -# executable : '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' -# arguments : -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" - -# - type : executable@1 -# name : 'Open in Windows Command Prompt' -# executable : '{{ env.WINDIR }}/System32/cmd.exe' -# arguments : /k cd "{{ repository.linux_path }}" - -- type : separator@1 - -- type : just-text@1 - name : 'Warning: No remote repos to browse to' - active : array.size(repository.remotes) == 0 +- type : command@1 + name : πŸ“ Open in Visual Studio Code + command : '{{ exe_vs_code }}' + arguments : '"{{ repository.path }}"' + active : file.file_exists(exe_vs_code) + +- type : executable@1 + name : Open in Sourcetree + executable : '{{ exe_sourcetree }}' + arguments : -f "{{ repository.windows_path }}" + active : file.file_exists(exe_sourcetree) + +- type : executable@1 + name : πŸ“Š Open in GitKraken πŸ¦‘ + executable : '{{ exe_gitkraken }}' + arguments : --path "{{ repository.path }}" + +- type : command@1 + name : 🧾 Open in Windows Terminal + command : wt + arguments : -d "{{ repository.path }}" + active : file.dir_exists(dir_windows_terminal_Store) || file.dir_exists(dir_windows_terminal_Preview) || file.dir_exists(dir_windows_terminal_Unpackaged) + +- type : executable@1 + name : πŸ” Open in Everything + executable : '{{ exe_everything }}' + arguments : -s """"{{ repository.path }}""" " + active : file.file_exists(exe_everything) + +- type : executable@1 + name : Open in TotalCommander + executable : '{{ exe_terminal_commander }}' + arguments : /O /T /L="{{ repository.linux_path }}" + active : file.file_exists(exe_terminal_commander) + +# - type : executable@1 +# name : 'Open in Windows PowerShell' +# executable : '{{ env.WINDIR }}/System32/WindowsPowerShell/v1.0/powershell.exe' +# arguments : -executionpolicy bypass -noexit -command "Set-Location '{{ repository.linux_path }}'" + +# - type : executable@1 +# name : 'Open in Windows Command Prompt' +# executable : '{{ env.WINDIR }}/System32/cmd.exe' +# arguments : /k cd "{{ repository.linux_path }}" + +- type : separator@1 + +- type : just-text@1 + name : 'Warning: No remote repos to browse to' + active : array.size(repository.remotes) == 0 # single remote, create url menu item -- type : url@1 - name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' - url : '{{ repository.remotes[0].url }}' - active : array.size(repository.remotes) == 1 +- type : url@1 + name : 'πŸ”— {{ try_get_remote_origin_long_name() }}' + url : '{{ repository.remotes[0].url }}' + active : array.size(repository.remotes) == 1 # Multiple remotes, create folder with multiple menu items -- type : folder@1 - name : πŸ”— Remote repos - active : array.size(repository.remotes) > 1 - actions : - - type : foreach@1 - enumerable : repository.remotes - variable : remote - actions : - - type : url@1 - name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' - url : '{{ remote.url }}' - -# - type : browse-repository@1 -- type : folder@1 - name : πŸ“¦ Git - actions : - - type : git-fetch@1 - - type : git-pull@1 - - type : git-push@1 - - type : git-checkout@1 - -- type : separator@1 +- type : folder@1 + name : πŸ”— Remote repos + active : array.size(repository.remotes) > 1 + actions : + - type : foreach@1 + enumerable : repository.remotes + variable : remote + actions : + - type : url@1 + name : '{{ try_get_remote_repo_long_name(remote.url) }} [{{ remote.key }}] ' + url : '{{ remote.url }}' + +# - type : browse-repository@1 +- type : folder@1 + name : πŸ“¦ Git + actions : + - type : git-fetch@1 + - type : git-pull@1 + - type : git-push@1 + - type : git-checkout@1 + +- type : separator@1 # active: is_work_repository -- type : pin-repository@1 - name : "πŸ“Œ Pin / Unpin Repo" - mode : toggle +- type : pin-repository@1 + name : "πŸ“Œ Pin / Unpin Repo" + mode : toggle -- type : folder@1 - name : ❓ About {{try_get_remote_origin_long_name()}} - actions : +- type : folder@1 + name : ❓ About {{try_get_remote_origin_long_name()}} + actions : - - type : clipboard-copy@1 - name : 'Current branch is {{ repository.branch }}' - text : '{{ repository.branch }}' + - type : clipboard-copy@1 + name : 'Current branch is {{ repository.branch }}' + text : '{{ repository.branch }}' - - type : clipboard-copy@1 - name : 'Local path is {{ repository.windows_path }}' - text : '{{ repository.windows_path }}' + - type : clipboard-copy@1 + name : 'Local path is {{ repository.windows_path }}' + text : '{{ repository.windows_path }}' - - type : separator@1 + - type : separator@1 - - type : ignore-repository@1 - name : ❌ Ignore Repository + - type : ignore-repository@1 + name : ❌ Ignore Repository - # context : - # - type : render-variable@1 - # name : repo_docs_directory - # value : 'C:\docs\{{ repository.name }}\' - - # - type : command@1 - # name : 'Create Directory {{ repo_docs_directory }}' - # command : cmd - # arguments : /k mkdir "{{ repo_docs_directory }}" - # active : '!file.dir_exists(repo_docs_directory)' + # context : + # - type : render-variable@1 + # name : repo_docs_directory + # value : 'C:\docs\{{ repository.name }}\' + + # - type : command@1 + # name : 'Create Directory {{ repo_docs_directory }}' + # command : cmd + # arguments : /k mkdir "{{ repo_docs_directory }}" + # active : '!file.dir_exists(repo_docs_directory)' diff --git a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs index 1ecd2f72..800be763 100644 --- a/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs +++ b/src/RepoM.Plugin.AzureDevOps/AzureDevOpsModule.cs @@ -7,9 +7,14 @@ namespace RepoM.Plugin.AzureDevOps; using RepoM.Plugin.AzureDevOps.Internal; [UsedImplicitly] -internal class AzureDevOpsModule(IAzureDevOpsPullRequestService service) : IModule +internal class AzureDevOpsModule : IModule { - private readonly IAzureDevOpsPullRequestService _service = service ?? throw new ArgumentNullException(nameof(service)); + private readonly IAzureDevOpsPullRequestService _service; + + public AzureDevOpsModule(IAzureDevOpsPullRequestService service) + { + _service = service ?? throw new ArgumentNullException(nameof(service)); + } public Task StartAsync() { diff --git a/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs b/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs index 399cdc76..0e638769 100644 --- a/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs +++ b/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs @@ -2,11 +2,18 @@ namespace RepoM.Plugin.AzureDevOps.Internal; using System; -internal class PullRequest(Guid repositoryId, string name, string url) +internal class PullRequest { - public Guid RepositoryId { get; } = repositoryId; + public PullRequest(Guid repositoryId, string name, string url) + { + RepositoryId = repositoryId; + Name = name; + Url = url; + } - public string Name { get; } = name; + public Guid RepositoryId { get; } - public string Url { get; } = url; + public string Name { get; } + + public string Url { get; } } \ No newline at end of file diff --git a/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs b/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs index 4d07fcbe..89fd7c07 100644 --- a/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs +++ b/src/RepoM.Plugin.Clipboard/RepositoryAction/CopyToClipboardRepositoryCommandExecutor.cs @@ -8,9 +8,14 @@ namespace RepoM.Plugin.Clipboard.RepositoryAction; using TextCopy; [UsedImplicitly] -internal class CopyToClipboardRepositoryCommandExecutor(IClipboard clipboard) : ICommandExecutor +internal class CopyToClipboardRepositoryCommandExecutor : ICommandExecutor { - private readonly IClipboard _clipboard = clipboard ?? throw new ArgumentNullException(nameof(clipboard)); + private readonly IClipboard _clipboard; + + public CopyToClipboardRepositoryCommandExecutor(IClipboard clipboard) + { + _clipboard = clipboard ?? throw new ArgumentNullException(nameof(clipboard)); + } public void Execute(IRepository repository, CopyToClipboardRepositoryCommand repositoryCommand) { diff --git a/src/RepoM.Plugin.Statistics/StatisticsModule.cs b/src/RepoM.Plugin.Statistics/StatisticsModule.cs index 337c3eb8..717a344b 100644 --- a/src/RepoM.Plugin.Statistics/StatisticsModule.cs +++ b/src/RepoM.Plugin.Statistics/StatisticsModule.cs @@ -15,23 +15,16 @@ namespace RepoM.Plugin.Statistics; using RepoM.Plugin.Statistics.Interface; [UsedImplicitly] -internal class StatisticsModule( - IStatisticsService service, - IStatisticsConfiguration configuration, - IClock clock, - IAppDataPathProvider pathProvider, - IFileSystem fileSystem, - ILogger logger) - : IModule +internal class StatisticsModule : IModule { - private readonly IStatisticsService _service = service ?? throw new ArgumentNullException(nameof(service)); - private readonly IStatisticsConfiguration _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); - private readonly IClock _clock = clock ?? throw new ArgumentNullException(nameof(clock)); - private readonly IAppDataPathProvider _pathProvider = pathProvider ?? throw new ArgumentNullException(nameof(pathProvider)); - private readonly IFileSystem _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - private readonly ILogger _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - private string _basePath = string.Empty; - private IDisposable? _disposable; + private readonly IStatisticsService _service; + private readonly IStatisticsConfiguration _configuration; + private readonly IClock _clock; + private readonly IAppDataPathProvider _pathProvider; + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + private string _basePath = string.Empty; + private IDisposable? _disposable; private readonly JsonSerializerSettings _settings = new() { Formatting = Formatting.None, @@ -39,6 +32,21 @@ internal class StatisticsModule( TypeNameHandling = TypeNameHandling.All, }; + public StatisticsModule(IStatisticsService service, + IStatisticsConfiguration configuration, + IClock clock, + IAppDataPathProvider pathProvider, + IFileSystem fileSystem, + ILogger logger) + { + _service = service ?? throw new ArgumentNullException(nameof(service)); + _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + _clock = clock ?? throw new ArgumentNullException(nameof(clock)); + _pathProvider = pathProvider ?? throw new ArgumentNullException(nameof(pathProvider)); + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + public async Task StartAsync() { _basePath = _fileSystem.Path.Combine(_pathProvider.AppDataPath, "Module", "Statistics"); diff --git a/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj b/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj index a305a175..9199915d 100644 --- a/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj +++ b/tests/RepoM.ActionMenu.CodeGen.Tests/RepoM.ActionMenu.CodeGen.Tests.csproj @@ -35,7 +35,7 @@ all - + diff --git a/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj b/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj index d9b6728f..d753fec1 100644 --- a/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj +++ b/tests/RepoM.ActionMenu.Core.TestLib/RepoM.ActionMenu.Core.TestLib.csproj @@ -34,7 +34,7 @@ all - + diff --git a/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj b/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj index 21c5fcaf..56e352b4 100644 --- a/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj +++ b/tests/RepoM.ActionMenu.Core.Tests/RepoM.ActionMenu.Core.Tests.csproj @@ -36,7 +36,7 @@ all - + diff --git a/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs b/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs index 97e46e2b..fbc72a7a 100644 --- a/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs +++ b/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs @@ -18,16 +18,25 @@ public static IDisposable SetEnvironmentVariable(string key, string value) return new ReleaseDisposable(are, key, origValue); } - private sealed class ReleaseDisposable(AutoResetEvent are, string key, string? value) : IDisposable + private sealed class ReleaseDisposable : IDisposable { - private readonly object _lock = new(); - private AutoResetEvent? _are = are; + private readonly object _lock = new(); + private AutoResetEvent? _are; + private readonly string _key; + private readonly string? _value; + + public ReleaseDisposable(AutoResetEvent are, string key, string? value) + { + _key = key; + _value = value; + _are = are; + } public void Dispose() { lock (_lock) { - Environment.SetEnvironmentVariable(key, value); + Environment.SetEnvironmentVariable(_key, _value); _are?.Set(); _are = null; }