Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
8621986
WIP
coenm Nov 18, 2022
efdd25d
poc
coenm Nov 21, 2022
3f8b9ae
wip
coenm Nov 21, 2022
240d07a
wip
coenm Nov 21, 2022
9f04ed3
.
coenm Nov 21, 2022
d9f3ec4
update
coenm Nov 22, 2022
34c8d19
fix readme
coenm Nov 22, 2022
64eac7f
update
coenm Nov 22, 2022
5873591
wip
coenm Nov 22, 2022
09e53f1
updadte
coenm Nov 22, 2022
8682f2f
cleanup
coenm Nov 22, 2022
fc1e9f8
update
coenm Nov 22, 2022
6dfdb5d
..
coenm Nov 22, 2022
ecb628c
update
coenm Nov 24, 2022
10ac4c1
fix
coenm Nov 24, 2022
3c3ab68
FIle service
coenm Nov 25, 2022
6453dbc
fix sonar
coenm Nov 25, 2022
86a1912
sonar
coenm Nov 25, 2022
a942a64
abstraction around actions
coenm Nov 26, 2022
3823231
Moving implementations from plugin to api project
coenm Nov 26, 2022
c1e2055
.
coenm Nov 26, 2022
9bffd18
WIP
coenm Nov 26, 2022
5678aad
fixing tests
coenm Nov 26, 2022
5db6ed9
Add module mvp
coenm Nov 26, 2022
0b9cace
update
coenm Nov 27, 2022
708f270
Update
coenm Nov 27, 2022
c9c17b3
.
coenm Nov 28, 2022
f1c5b0e
update
coenm Nov 29, 2022
4b721aa
wip
coenm Nov 29, 2022
4a8d65a
..
coenm Nov 29, 2022
f6e9a46
..
coenm Nov 29, 2022
3c36274
wip
coenm Nov 30, 2022
496b733
update
coenm Nov 30, 2022
c916488
.
coenm Nov 30, 2022
beaf218
Update
coenm Dec 2, 2022
93658ee
wip
coenm Dec 6, 2022
193d260
Adding tests
coenm Dec 6, 2022
1ac507f
add tests
coenm Dec 6, 2022
30f73b6
styling
coenm Dec 6, 2022
55c2cd8
Depend on System.IO.Abstractions in Statistics project
coenm Dec 6, 2022
57d301b
add tests
coenm Dec 6, 2022
112669b
fix test
coenm Dec 6, 2022
11e76b7
Add test
coenm Dec 6, 2022
368728b
added tests
coenm Dec 7, 2022
a543a54
Remove poc project
coenm Dec 7, 2022
fa9e2a5
..
coenm Dec 7, 2022
45ad5ae
persist sort key
coenm Dec 7, 2022
79d20eb
..
coenm Dec 7, 2022
024c6f7
simple injector upgrade
coenm Dec 8, 2022
bfb8d23
updating packages
coenm Dec 8, 2022
21f4b17
targeting net6
coenm Dec 8, 2022
0f7784a
Update packages
coenm Dec 9, 2022
fe9eb56
Remove data after 30 days.
coenm Dec 9, 2022
073ae91
.
coenm Dec 9, 2022
3de459a
..
coenm Dec 9, 2022
159942b
wip
coenm Dec 10, 2022
a9b0650
Wip
coenm Dec 12, 2022
fee1420
add tests
coenm Dec 12, 2022
6dd312f
..
coenm Dec 12, 2022
0448caa
Move types to own files
coenm Dec 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**!

Expand All @@ -26,12 +26,12 @@ For Windows, use the hotkeys <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>R</kbd> to show

To open a file browser, simply press <kbd>Return</kbd> on the keyboard once you selected a repository. To open a command prompt instead, hold <kbd>Ctrl</kbd> on Windows or <kbd>Command</kbd> on macOS while pressing <kbd>Return</kbd>. 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.

![Screenshot](https://raw.githubusercontent.com/awaescher/RepoZ/master/_doc/RepoZ-ReadMe-Explorer.png)

## 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).
46 changes: 46 additions & 0 deletions RepoM.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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}
Expand Down
2 changes: 2 additions & 0 deletions RepoM.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=bindable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=comparers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=decoratee/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Devops/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Gravell/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hardcodeded/@EntryIndexedValue">True</s:Boolean>
Expand Down
2 changes: 2 additions & 0 deletions src/RepoM.Api/Common/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ public AppSettings()
EnabledSearchProviders = new List<string>();
SonarCloudPersonalAccessToken = string.Empty;
AzureDevOps = AzureDevOpsOptions.Default;
SortKey = string.Empty;
}
public string SortKey { get; set; }

public AutoFetchMode AutoFetchMode { get; set; }

Expand Down
80 changes: 79 additions & 1 deletion src/RepoM.Api/Common/FileAppSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<IConfigurationRegistration> _registrations;
private readonly IAppDataPathProvider _appDataPathProvider;
private Dictionary<string, IRepositoriesComparerConfiguration>? _configuration;


public FilesICompareSettingsService(IAppDataPathProvider appDataPathProvider, IFileSystem fileSystem, IEnumerable<IConfigurationRegistration> registrations)
{
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_registrations = registrations.ToList();
_appDataPathProvider = appDataPathProvider ?? throw new ArgumentNullException(nameof(appDataPathProvider));
}

public Dictionary<string, IRepositoriesComparerConfiguration> Configuration => _configuration ??= Load();


private string GetFileName()
{
return _fileSystem.Path.Combine(_appDataPathProvider.GetAppDataPath(), "RepoM.Ordering.yaml");
}

private Dictionary<string, IRepositoriesComparerConfiguration> 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<Dictionary<string, IRepositoriesComparerConfiguration>>(yml);
}
catch
{
throw;
/* Our app settings are not critical. For our purposes, we want to ignore IO exceptions */
}
}
}

public class FileAppSettingsService : IAppSettingsService
{
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 1 addition & 5 deletions src/RepoM.Api/Common/HardcodededMiniHumanizer.cs
Original file line number Diff line number Diff line change
@@ -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));
Expand Down
8 changes: 8 additions & 0 deletions src/RepoM.Api/Common/IAppSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, IRepositoriesComparerConfiguration> Configuration { get; }
}

public interface IAppSettingsService
{
Expand All @@ -22,5 +28,7 @@ public interface IAppSettingsService

string AzureDevOpsBaseUrl { get; set; }

string SortKey { get; set; }

void RegisterInvalidationHandler(Action handler);
}
7 changes: 7 additions & 0 deletions src/RepoM.Api/Common/SystemClock.cs
Original file line number Diff line number Diff line change
@@ -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;
}
28 changes: 14 additions & 14 deletions src/RepoM.Api/Git/AutoFetch/DefaultAutoFetchHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<AutoFetchMode, AutoFetchProfile> _profiles;
private int _lastFetchRepository = -1;
Expand All @@ -26,10 +26,10 @@ public DefaultAutoFetchHandler(

_profiles = new Dictionary<AutoFetchMode, AutoFetchProfile>
{
{ 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);
Expand Down Expand Up @@ -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<RepositoryViewModel>();

// 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
{
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion src/RepoM.Api/Git/DefaultRepositoryIgnoreStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
Loading