diff --git a/README.md b/README.md
index 47e686c2..05601667 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ RepoM is a minimal-conf git repository hub with Windows Explorer enhancements. I
It's populating itself as you work with git. It does not get in the way and does not require any user attention to work.
-Repo< will not compete with your favourite git clients, so keep them. It's not about working within a repository: It's a new way to use all of your repositories to make your daily work easier.
+RepoM will not compete with your favourite git clients, so keep them. It's not about working within a repository: It's a new way to use all of your repositories to make your daily work easier.
📦 [Check the Releases page](https://github.com/coenm/RepoM/releases) to **download** the latest version and see **what's new**!
@@ -26,7 +26,7 @@ For Windows, use the hotkeys Ctrl+Alt+R to show
To open a file browser, simply press Return on the keyboard once you selected a repository. To open a command prompt instead, hold Ctrl on Windows or Command on macOS while pressing Return. These modifier keys will also work with mouse navigation.
-## Enhanced Windows Explorer Titles
+## Plugin: Enhanced Windows Explorer Titles
As an extra goodie for Windows users, RepoZ automatically detects open File Explorer windows and adds a status appendix to their title if they are in context of a git repository.
@@ -34,4 +34,4 @@ As an extra goodie for Windows users, RepoZ automatically detects open File Expl
## Credits
-RepoM is a fork of the amazing RepoZ, which was created by [Screenshot](https://github.com/awaescher/RepoZ).
+RepoM is a fork of the amazing RepoZ, which was created by [Andreas Wäscher](https://github.com/awaescher/RepoZ).
diff --git a/RepoM.sln b/RepoM.sln
index 5802ec6e..7bbbd73a 100644
--- a/RepoM.sln
+++ b/RepoM.sln
@@ -33,6 +33,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Api.Tests", "tests\Re
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Core.Plugin", "src\RepoM.Core.Plugin\RepoM.Core.Plugin.csproj", "{E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.Statistics", "src\RepoM.Plugin.Statistics\RepoM.Plugin.Statistics.csproj", "{DF4F5FA8-0E3F-4D84-A048-20242FD032BC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RepoM.Plugin.Statistics.Tests", "tests\RepoM.Plugin.Statistics.Tests\RepoM.Plugin.Statistics.Tests.csproj", "{C90AA844-B355-4C62-96FA-D4F338EE094A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -327,6 +331,46 @@ Global
{E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Release|x64.Build.0 = Release|Any CPU
{E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Release|x86.ActiveCfg = Release|Any CPU
{E38D9928-A0A6-4978-BD7E-C7F2E2B6BC9B}.Release|x86.Build.0 = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|ARM.Build.0 = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|x64.Build.0 = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Debug|x86.Build.0 = Debug|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|ARM.ActiveCfg = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|ARM.Build.0 = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|ARM64.Build.0 = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|x64.ActiveCfg = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|x64.Build.0 = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC}.Release|x86.Build.0 = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|ARM.Build.0 = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|x64.Build.0 = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Debug|x86.Build.0 = Debug|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|ARM.ActiveCfg = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|ARM.Build.0 = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|ARM64.Build.0 = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|x64.ActiveCfg = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|x64.Build.0 = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|x86.ActiveCfg = Release|Any CPU
+ {C90AA844-B355-4C62-96FA-D4F338EE094A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -340,6 +384,8 @@ Global
{74B95BAF-0DB4-42C8-92EA-A364E8080809} = {D6E372DC-10D3-4997-9DFC-568B4666635A}
{26FF9590-66C7-4B87-9574-E816E1E36628} = {D6E372DC-10D3-4997-9DFC-568B4666635A}
{C2014EE2-F17C-478E-B282-9D0971065BB8} = {D6E372DC-10D3-4997-9DFC-568B4666635A}
+ {DF4F5FA8-0E3F-4D84-A048-20242FD032BC} = {D6E372DC-10D3-4997-9DFC-568B4666635A}
+ {C90AA844-B355-4C62-96FA-D4F338EE094A} = {D6E372DC-10D3-4997-9DFC-568B4666635A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1765ABAA-0652-4DA5-ABBF-05396F2957D7}
diff --git a/RepoM.sln.DotSettings b/RepoM.sln.DotSettings
index 7f128dd7..abeb3a9d 100644
--- a/RepoM.sln.DotSettings
+++ b/RepoM.sln.DotSettings
@@ -1,5 +1,7 @@

True
+ True
+ True
True
True
True
diff --git a/src/RepoM.Api/Common/AppSettings.cs b/src/RepoM.Api/Common/AppSettings.cs
index eb2d8b76..a152c130 100644
--- a/src/RepoM.Api/Common/AppSettings.cs
+++ b/src/RepoM.Api/Common/AppSettings.cs
@@ -11,7 +11,9 @@ public AppSettings()
EnabledSearchProviders = new List();
SonarCloudPersonalAccessToken = string.Empty;
AzureDevOps = AzureDevOpsOptions.Default;
+ SortKey = string.Empty;
}
+ public string SortKey { get; set; }
public AutoFetchMode AutoFetchMode { get; set; }
diff --git a/src/RepoM.Api/Common/FileAppSettingsService.cs b/src/RepoM.Api/Common/FileAppSettingsService.cs
index 0c92a184..b172d510 100644
--- a/src/RepoM.Api/Common/FileAppSettingsService.cs
+++ b/src/RepoM.Api/Common/FileAppSettingsService.cs
@@ -7,7 +7,67 @@ namespace RepoM.Api.Common;
using System.Linq;
using Newtonsoft.Json;
using RepoM.Api.Git.AutoFetch;
-using RepoM.Api.IO;
+using RepoM.Core.Plugin.Common;
+using RepoM.Core.Plugin.RepositoryOrdering.Configuration;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
+public class FilesICompareSettingsService : ICompareSettingsService
+{
+ private readonly IFileSystem _fileSystem;
+ private readonly IEnumerable _registrations;
+ private readonly IAppDataPathProvider _appDataPathProvider;
+ private Dictionary? _configuration;
+
+
+ public FilesICompareSettingsService(IAppDataPathProvider appDataPathProvider, IFileSystem fileSystem, IEnumerable registrations)
+ {
+ _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
+ _registrations = registrations.ToList();
+ _appDataPathProvider = appDataPathProvider ?? throw new ArgumentNullException(nameof(appDataPathProvider));
+ }
+
+ public Dictionary Configuration => _configuration ??= Load();
+
+
+ private string GetFileName()
+ {
+ return _fileSystem.Path.Combine(_appDataPathProvider.GetAppDataPath(), "RepoM.Ordering.yaml");
+ }
+
+ private Dictionary Load()
+ {
+ var file = GetFileName();
+
+ if (!_fileSystem.File.Exists(file))
+ {
+ throw new Exception("File doesn't exist");
+ }
+
+ try
+ {
+ var yml = _fileSystem.File.ReadAllText(file);
+
+ DeserializerBuilder builder = new DeserializerBuilder()
+ .WithNamingConvention(HyphenatedNamingConvention.Instance);
+
+ foreach (IConfigurationRegistration instance in _registrations)
+ {
+ var tag = instance.Tag.TrimStart('!');
+ builder.WithTagMapping("!" + tag, instance.ConfigurationType);
+ }
+
+ IDeserializer deserializer = builder.Build();
+
+ return deserializer.Deserialize>(yml);
+ }
+ catch
+ {
+ throw;
+ /* Our app settings are not critical. For our purposes, we want to ignore IO exceptions */
+ }
+ }
+}
public class FileAppSettingsService : IAppSettingsService
{
@@ -72,6 +132,24 @@ private string GetFileName()
private AppSettings Settings => _settings ??= Load();
+
+ public string SortKey
+ {
+ get => Settings.SortKey;
+ set
+ {
+ if (value == Settings.SortKey)
+ {
+ return;
+ }
+
+ Settings.SortKey = value;
+
+ NotifyChange();
+ Save();
+ }
+ }
+
public AutoFetchMode AutoFetchMode
{
get => Settings.AutoFetchMode;
diff --git a/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs b/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs
index ac358df1..4cb163b7 100644
--- a/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs
+++ b/src/RepoM.Api/Common/HardcodededMiniHumanizer.cs
@@ -1,16 +1,12 @@
namespace RepoM.Api.Common;
using System;
+using RepoM.Core.Plugin.Common;
public class HardcodededMiniHumanizer : IHumanizer
{
private readonly IClock _clock;
- public HardcodededMiniHumanizer()
- : this(new SystemClock())
- {
- }
-
public HardcodededMiniHumanizer(IClock clock)
{
_clock = clock ?? throw new ArgumentNullException(nameof(clock));
diff --git a/src/RepoM.Api/Common/IAppSettingsService.cs b/src/RepoM.Api/Common/IAppSettingsService.cs
index 043880e5..e49c1b0e 100644
--- a/src/RepoM.Api/Common/IAppSettingsService.cs
+++ b/src/RepoM.Api/Common/IAppSettingsService.cs
@@ -3,6 +3,12 @@ namespace RepoM.Api.Common;
using System;
using System.Collections.Generic;
using RepoM.Api.Git.AutoFetch;
+using RepoM.Core.Plugin.RepositoryOrdering.Configuration;
+
+public interface ICompareSettingsService
+{
+ Dictionary Configuration { get; }
+}
public interface IAppSettingsService
{
@@ -22,5 +28,7 @@ public interface IAppSettingsService
string AzureDevOpsBaseUrl { get; set; }
+ string SortKey { get; set; }
+
void RegisterInvalidationHandler(Action handler);
}
diff --git a/src/RepoM.Api/Common/SystemClock.cs b/src/RepoM.Api/Common/SystemClock.cs
index 7c403999..255697d1 100644
--- a/src/RepoM.Api/Common/SystemClock.cs
+++ b/src/RepoM.Api/Common/SystemClock.cs
@@ -1,8 +1,15 @@
namespace RepoM.Api.Common;
using System;
+using RepoM.Core.Plugin.Common;
public class SystemClock : IClock
{
+ private SystemClock()
+ {
+ }
+
+ public static SystemClock Instance { get; } = new();
+
public DateTime Now => DateTime.Now;
}
\ No newline at end of file
diff --git a/src/RepoM.Api/Git/AutoFetch/DefaultAutoFetchHandler.cs b/src/RepoM.Api/Git/AutoFetch/DefaultAutoFetchHandler.cs
index 799bc92d..44b0f6f3 100644
--- a/src/RepoM.Api/Git/AutoFetch/DefaultAutoFetchHandler.cs
+++ b/src/RepoM.Api/Git/AutoFetch/DefaultAutoFetchHandler.cs
@@ -9,7 +9,7 @@ namespace RepoM.Api.Git.AutoFetch;
public class DefaultAutoFetchHandler : IAutoFetchHandler
{
private bool _active;
- private AutoFetchMode? _mode = null;
+ private AutoFetchMode? _mode;
private readonly Timer _timer;
private readonly Dictionary _profiles;
private int _lastFetchRepository = -1;
@@ -26,10 +26,10 @@ public DefaultAutoFetchHandler(
_profiles = new Dictionary
{
- { AutoFetchMode.Off, new AutoFetchProfile() { PauseBetweenFetches = TimeSpan.MaxValue, } },
- { AutoFetchMode.Discretely, new AutoFetchProfile() { PauseBetweenFetches = TimeSpan.FromMinutes(5), } },
- { AutoFetchMode.Adequate, new AutoFetchProfile() { PauseBetweenFetches = TimeSpan.FromMinutes(1), } },
- { AutoFetchMode.Aggressive, new AutoFetchProfile() { PauseBetweenFetches = TimeSpan.FromSeconds(2), } },
+ { AutoFetchMode.Off, new AutoFetchProfile { PauseBetweenFetches = TimeSpan.MaxValue, } },
+ { AutoFetchMode.Discretely, new AutoFetchProfile { PauseBetweenFetches = TimeSpan.FromMinutes(5), } },
+ { AutoFetchMode.Adequate, new AutoFetchProfile { PauseBetweenFetches = TimeSpan.FromMinutes(1), } },
+ { AutoFetchMode.Aggressive, new AutoFetchProfile { PauseBetweenFetches = TimeSpan.FromSeconds(2), } },
};
_timer = new Timer(FetchNext, null, Timeout.Infinite, Timeout.Infinite);
@@ -71,28 +71,28 @@ private void FetchNext(object timerState)
// 2. makes sure that no repository is jumped over because the list
// of repositories is constantly changed and not sorted in any way in memory.
// So we cannot guarantuee that each repository is fetched on each iteration if we do not sort.
- var repositories = RepositoryInformationAggregator.Repositories
+ var repositories = RepositoryInformationAggregator.Repositories?
.OrderBy(r => r.Name)
- .ToList();
+ .ToArray() ?? Array.Empty();
// temporarily disable the timer to prevent parallel fetch executions
UpdateBehavior(AutoFetchMode.Off);
_lastFetchRepository++;
- if (repositories.Count <= _lastFetchRepository)
+ if (repositories.Length <= _lastFetchRepository)
{
_lastFetchRepository = 0;
}
- RepositoryView repositoryView = repositories[_lastFetchRepository];
+ RepositoryViewModel repositoryViewModel = repositories[_lastFetchRepository];
- Console.WriteLine($"Auto-fetching {repositoryView.Name} (index {_lastFetchRepository} of {repositories.Count})");
+ Console.WriteLine($"Auto-fetching {repositoryViewModel.Name} (index {_lastFetchRepository} of {repositories.Length})");
- repositoryView.IsSynchronizing = true;
+ repositoryViewModel.IsSynchronizing = true;
try
{
- RepositoryWriter.Fetch(repositoryView.Repository);
+ RepositoryWriter.Fetch(repositoryViewModel.Repository);
}
catch
{
@@ -103,7 +103,7 @@ private void FetchNext(object timerState)
// re-enable the timer to get to the next fetch
UpdateBehavior();
- repositoryView.IsSynchronizing = false;
+ repositoryViewModel.IsSynchronizing = false;
}
}
@@ -134,7 +134,7 @@ public AutoFetchMode Mode
}
_mode = value;
- Console.WriteLine("Auto fetch is: " + _mode.GetValueOrDefault().ToString());
+ Console.WriteLine("Auto fetch is: " + _mode.GetValueOrDefault());
UpdateBehavior();
}
diff --git a/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs b/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs
index 303659cb..13fbda7f 100644
--- a/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs
+++ b/src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs
@@ -5,7 +5,7 @@ namespace RepoM.Api.Git;
using System.IO;
using System.IO.Abstractions;
using System.Linq;
-using RepoM.Api.IO;
+using RepoM.Core.Plugin.Common;
public class DefaultRepositoryIgnoreStore : FileRepositoryStore, IRepositoryIgnoreStore
{
diff --git a/src/RepoM.Api/Git/DefaultRepositoryInformationAggregator.cs b/src/RepoM.Api/Git/DefaultRepositoryInformationAggregator.cs
index 55faa4b1..eaf497ec 100644
--- a/src/RepoM.Api/Git/DefaultRepositoryInformationAggregator.cs
+++ b/src/RepoM.Api/Git/DefaultRepositoryInformationAggregator.cs
@@ -13,16 +13,16 @@ public class DefaultRepositoryInformationAggregator : IRepositoryInformationAggr
public DefaultRepositoryInformationAggregator(IThreadDispatcher dispatcher)
{
_dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher));
- Repositories = new ObservableCollection();
+ Repositories = new ObservableCollection();
}
- public ObservableCollection Repositories { get; }
+ public ObservableCollection Repositories { get; }
public void Add(Repository repository, IRepositoryMonitor repositoryMonitor)
{
_dispatcher.Invoke(() =>
{
- var view = new RepositoryView(repository, repositoryMonitor);
+ var view = new RepositoryViewModel(repository, repositoryMonitor);
Repositories.Remove(view);
Repositories.Add(view);
@@ -33,7 +33,7 @@ public void RemoveByPath(string path)
{
_dispatcher.Invoke(() =>
{
- RepositoryView[] viewsToRemove = Repositories.Where(r => r.Path.Equals(path, StringComparison.OrdinalIgnoreCase)).ToArray();
+ RepositoryViewModel[] viewsToRemove = Repositories.Where(r => r.Path.Equals(path, StringComparison.OrdinalIgnoreCase)).ToArray();
for (var i = viewsToRemove.Length - 1; i >= 0; i--)
{
@@ -44,18 +44,18 @@ public void RemoveByPath(string path)
public string? GetStatusByPath(string path)
{
- RepositoryView? view = GetRepositoryByPath(path);
+ RepositoryViewModel? view = GetRepositoryByPath(path);
return view?.BranchWithStatus;
}
- private RepositoryView? GetRepositoryByPath(string path)
+ private RepositoryViewModel? GetRepositoryByPath(string path)
{
if (string.IsNullOrEmpty(path))
{
return null;
}
- List? views = null;
+ List? views = null;
try
{
views = Repositories.ToList();
@@ -76,7 +76,7 @@ public void RemoveByPath(string path)
path += "\\";
}
- RepositoryView[] viewsByPath = views!
+ RepositoryViewModel[] viewsByPath = views!
.Where(r =>
r?.Path != null
&&
diff --git a/src/RepoM.Api/Git/DefaultRepositoryReader.cs b/src/RepoM.Api/Git/DefaultRepositoryReader.cs
index deba0a83..e42949a5 100644
--- a/src/RepoM.Api/Git/DefaultRepositoryReader.cs
+++ b/src/RepoM.Api/Git/DefaultRepositoryReader.cs
@@ -113,9 +113,9 @@ public DefaultRepositoryReader(IRepositoryTagsFactory resolver, ILogger logger)
RemoteCollection? remoteCollection = repo.Network?.Remotes;
if (remoteCollection != null)
{
- foreach (LibGit2Sharp.Remote r in remoteCollection.Where(r => !string.IsNullOrWhiteSpace(r.Name) && !string.IsNullOrWhiteSpace(r.Url)))
+ foreach (Remote r in remoteCollection.Where(r => !string.IsNullOrWhiteSpace(r.Name) && !string.IsNullOrWhiteSpace(r.Url)))
{
- repository.Remotes.Add(new Remote(r.Name.Trim(), r.Url.Trim()));
+ repository.Remotes.Add(new Core.Plugin.Repository.Remote(r.Name.Trim(), r.Url.Trim()));
}
}
diff --git a/src/RepoM.Api/Git/DefaultRepositoryStore.cs b/src/RepoM.Api/Git/DefaultRepositoryStore.cs
index 3ae39a8f..e6364569 100644
--- a/src/RepoM.Api/Git/DefaultRepositoryStore.cs
+++ b/src/RepoM.Api/Git/DefaultRepositoryStore.cs
@@ -3,7 +3,7 @@ namespace RepoM.Api.Git;
using System;
using System.IO;
using System.IO.Abstractions;
-using RepoM.Api.IO;
+using RepoM.Core.Plugin.Common;
public class DefaultRepositoryStore : FileRepositoryStore
{
diff --git a/src/RepoM.Api/Git/IRepositoryInformationAggregator.cs b/src/RepoM.Api/Git/IRepositoryInformationAggregator.cs
index 4d159bbc..05c0ea8b 100644
--- a/src/RepoM.Api/Git/IRepositoryInformationAggregator.cs
+++ b/src/RepoM.Api/Git/IRepositoryInformationAggregator.cs
@@ -10,7 +10,7 @@ public interface IRepositoryInformationAggregator
string? GetStatusByPath(string path);
- ObservableCollection Repositories { get; }
+ ObservableCollection Repositories { get; }
void Reset();
diff --git a/src/RepoM.Api/Git/IRepositoryView.cs b/src/RepoM.Api/Git/IRepositoryView.cs
index e5291cea..2a2fa629 100644
--- a/src/RepoM.Api/Git/IRepositoryView.cs
+++ b/src/RepoM.Api/Git/IRepositoryView.cs
@@ -11,4 +11,6 @@ public interface IRepositoryView
bool IsPinned { get; }
bool HasUnpushedChanges { get; }
+
+ Repository Repository { get; }
}
\ No newline at end of file
diff --git a/src/RepoM.Api/Git/Repository.cs b/src/RepoM.Api/Git/Repository.cs
index bd7a0f38..7ba85cc2 100644
--- a/src/RepoM.Api/Git/Repository.cs
+++ b/src/RepoM.Api/Git/Repository.cs
@@ -3,9 +3,10 @@ namespace RepoM.Api.Git;
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using RepoM.Core.Plugin.Repository;
[DebuggerDisplay("{Name} @{Path}")]
-public class Repository
+public class Repository : IRepository
{
public Repository()
{
@@ -17,7 +18,7 @@ public Repository()
Location = string.Empty;
}
- public override bool Equals(object obj)
+ public override bool Equals(object? obj)
{
if (obj is not Repository other)
{
diff --git a/src/RepoM.Api/Git/RepositoryAction.cs b/src/RepoM.Api/Git/RepositoryAction.cs
index edf5e451..16c47e37 100644
--- a/src/RepoM.Api/Git/RepositoryAction.cs
+++ b/src/RepoM.Api/Git/RepositoryAction.cs
@@ -2,14 +2,23 @@ namespace RepoM.Api.Git;
using System;
using System.Collections.Generic;
+using RepoM.Core.Plugin.Repository;
+using RepoM.Core.Plugin.RepositoryActions;
+using RepoM.Core.Plugin.RepositoryActions.Actions;
public class RepositorySeparatorAction : RepositoryActionBase
{
+ public RepositorySeparatorAction(IRepository repository)
+ : base(repository)
+ {
+ }
}
+
public class RepositoryAction : RepositoryActionBase
{
- public RepositoryAction(string name)
+ public RepositoryAction(string name, IRepository repository):
+ base(repository)
{
Name = name;
}
@@ -19,7 +28,14 @@ public RepositoryAction(string name)
public abstract class RepositoryActionBase
{
- public Action