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 @@
-
+
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..e3239765 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 = TryGet_RemoteRepoLongName(repository.Remotes[0].Url);
+ yield return new UserInterfaceRepositoryAction(menuTitle, repository)
{
RepositoryCommand = new BrowseRepositoryCommand(repository.Remotes[0].Url),
};
}
else
{
+ menuTitle = "Remote repos";
yield return new DeferredSubActionsUserInterfaceRepositoryAction(
- name,
+ menuTitle,
repository,
context,
captureScope: false,
@@ -50,14 +52,27 @@ protected override async IAsyncEnumerable Map
}
}
+ private static string TryGet_RemoteRepoLongName(string remoteUrl)
+ {
+ 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(remote.Name, repository)
- {
- RepositoryCommand = new BrowseRepositoryCommand(remote.Url),
- })
+ .Select(remote => new UserInterfaceRepositoryAction(TryGet_RemoteRepoLongName(remote.Url), repository)
+ {
+ RepositoryCommand = new BrowseRepositoryCommand(remote.Url),
+ })
.Cast()
.ToArray());
}
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..db12acb6 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/Bootstrapper.cs b/src/RepoM.Api/Bootstrapper.cs
index 237588eb..3cf745c9 100644
--- a/src/RepoM.Api/Bootstrapper.cs
+++ b/src/RepoM.Api/Bootstrapper.cs
@@ -1,38 +1,38 @@
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
{
- private readonly IPluginFinder _pluginFinder;
- private readonly IFileSystem _fileSystem;
+ private readonly IPluginFinder _pluginFinder;
+ private readonly IFileSystem _fileSystem;
private readonly IAppDataPathProvider _appDataProvider;
- private readonly ILoggerFactory _loggerFactory;
+ 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));
+ _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));
+ _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..5f7c8586 100644
--- a/src/RepoM.Api/EnsureStartup.cs
+++ b/src/RepoM.Api/EnsureStartup.cs
@@ -9,12 +9,12 @@ namespace RepoM.Api;
public class EnsureStartup
{
- private readonly IFileSystem _fileSystem;
+ private readonly IFileSystem _fileSystem;
private readonly IAppDataPathProvider _appDataProvider;
public EnsureStartup(IFileSystem fileSystem, IAppDataPathProvider appDataProvider)
{
- _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
+ _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_appDataProvider = appDataProvider ?? throw new ArgumentNullException(nameof(appDataProvider));
}
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())
{
diff --git a/src/RepoM.Api/Resources/RepoM.Filtering.yaml b/src/RepoM.Api/Resources/RepoM.Filtering.yaml
index 52ff09c4..39415ff4 100644
--- a/src/RepoM.Api/Resources/RepoM.Filtering.yaml
+++ b/src/RepoM.Api/Resources/RepoM.Filtering.yaml
@@ -1,3 +1,12 @@
+Private:
+ name: Private
+ description: Private repositories
+ always-visible:
+ kind: query@1
+ query: RepoM OR is:pinned
+ filter:
+ kind: query@1
+ query: tag:private
Work:
name: Work
description: Work filtering
@@ -7,12 +16,3 @@ Work:
filter:
kind: query@1
query: tag:work
-Private:
- name: Private
- description: Private repositories
- always-visible:
- kind: query@1
- query: RepoM OR is:pinned
- filter:
- kind: query@1
- query: (-tag:work OR tag:private)
\ No newline at end of file
diff --git a/src/RepoM.Api/Resources/RepoM.Sorting.yaml b/src/RepoM.Api/Resources/RepoM.Sorting.yaml
index 8985b78e..1f1261e7 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:
+Most Active:
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,11 @@ 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
diff --git a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml
index f3890467..414ac7f6 100644
--- a/src/RepoM.Api/Resources/RepositoryActionsV2.yaml
+++ b/src/RepoM.Api/Resources/RepositoryActionsV2.yaml
@@ -1,16 +1,20 @@
-context:
-- type: evaluate-script@1
+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
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)
@@ -22,9 +26,9 @@ context:
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);
@@ -47,133 +51,210 @@ context:
ret repository.branch | string.replace "feature/" "" | string.strip
end
- remote_name_origin = get_remote_origin_name();
- is_work_repository = remotes_contain("My-Work");
+ 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 try_get_remote_origin_long_name()
+ if is_null(repository.remotes) || array.size(repository.remotes) == 0
+ ret repository.name
+ end
+ 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");
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);
- exe_vs_code = env.LocalAppData + "/Programs/Microsoft VS Code/code.exe";
+ 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
- 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 }}"'
-
-- 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
- command: '{{ solution_file }}'
- active: array.size(solution_files) == 1
-
-# 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
- 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 : 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)
+
+# 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: executable@1
- name: Open in Visual Studio Code
- executable: '{{ exe_vs_code }}'
- arguments: '"{{ repository.linux_path }}"'
-
-- type: executable@1
- name: Open in Sourcetree
- executable: '{{ env.LocalAppData }}/SourceTree/SourceTree.exe'
- arguments: -f "{{ repository.windows_path }}"
-
-- type: executable@1
- name: Open in Everything
- executable: '{{ env.ProgramW6432 }}/Everything/Everything.exe'
- arguments: -s """"{{ repository.path }}""" "
-
-- type: executable@1
- name: Open in TotalCommander
- executable: '{{ env.ProgramW6432 }}/totalcmd/TOTALCMD64.EXE'
- arguments: /O /T /L="{{ repository.linux_path }}"
-
-- 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: separator@1
-
-- type: ignore-repository@1
-
-- type: separator@1
- active: is_work_repository
-
-- type: folder@1
- name: '-- Examples --'
- context:
- - type: render-variable@1
- name: repo_docs_directory
- value: 'C:\docs\{{ repository.name }}\'
- actions:
+- 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
+
+# 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
+ # active: is_work_repository
+
+- type : pin-repository@1
+ name : "๐ Pin / Unpin Repo"
+ mode : toggle
+
+- type : folder@1
+ name : โ About {{try_get_remote_origin_long_name()}}
+ actions :
- - type: just-text@1
- name: 'Current branch is {{ repository.branch }}'
-
- - 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 : 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
+
+ # 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.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
+
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
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..0e638769 100644
--- a/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs
+++ b/src/RepoM.Plugin.AzureDevOps/Internal/PullRequest.cs
@@ -7,8 +7,8 @@ internal class PullRequest
public PullRequest(Guid repositoryId, string name, string url)
{
RepositoryId = repositoryId;
- Name = name;
- Url = url;
+ Name = name;
+ Url = url;
}
public Guid RepositoryId { get; }
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.Statistics/StatisticsModule.cs b/src/RepoM.Plugin.Statistics/StatisticsModule.cs
index f5e47275..717a344b 100644
--- a/src/RepoM.Plugin.Statistics/StatisticsModule.cs
+++ b/src/RepoM.Plugin.Statistics/StatisticsModule.cs
@@ -17,43 +17,40 @@ namespace RepoM.Plugin.Statistics;
[UsedImplicitly]
internal class StatisticsModule : IModule
{
- private readonly IStatisticsService _service;
+ 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;
-
- public StatisticsModule(
- IStatisticsService service,
- IStatisticsConfiguration configuration,
- IClock clock,
- IAppDataPathProvider pathProvider,
- IFileSystem fileSystem,
- ILogger logger)
+ 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()
{
- _service = service ?? throw new ArgumentNullException(nameof(service));
+ Formatting = Formatting.None,
+ NullValueHandling = NullValueHandling.Ignore,
+ 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));
-
- _settings = new JsonSerializerSettings
- {
- Formatting = Formatting.None,
- NullValueHandling = NullValueHandling.Ignore,
- TypeNameHandling = TypeNameHandling.All,
- };
+ _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");
-
+
_disposable = WriteEventsToFile();
await ProcessEventsFromFile().ConfigureAwait(false);
@@ -151,12 +148,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..fbc72a7a 100644
--- a/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs
+++ b/tests/RepoM.Plugin.Heidi.Tests/EnvironmentVariableManager.cs
@@ -20,16 +20,16 @@ public static IDisposable SetEnvironmentVariable(string key, string value)
private sealed class ReleaseDisposable : IDisposable
{
- private readonly object _lock = new();
- private AutoResetEvent? _are;
- private readonly string _key;
- private readonly string? _value;
+ 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;
+ _key = key;
_value = value;
+ _are = are;
}
public void Dispose()